XY-pic Complete Sources with TEXnical Commentary

Kristoffer H. Rose ⟨Kristoffer.Rose@ens-lyon.fr⟩^{1} Ross Moore ⟨ross@mpce.mq.edu.au⟩^{2} XY-pic version 3.7 ⟨1999/02/16⟩

1Ecole Normale Supérieure de Lyon (LIP), 46 Allée d’Italie, F–69364 Lyon, France. 2MPCE (Mathematics dept.), Macquarie University, North Ryde, Sydney, Australia NSW 2109.

Printed February 25, 1999, from xysource.man version 3.7.

This report is typeset from the XY-pic sources, kernel version 3.7 released February 16, 1999. It includes all of the text in the XY-pic Reference Manual [16].

XY-pic related files can be retrieved by anonymous ftp from Internet host ftp.ens-lyon.fr in the directory /pub/users/LIP/krisrose/TeX in files with prefix xy as well as from CTAN hosts in macros/generic/diagrams/xypic. News about XY-pic can be obtained from the authors and through the ‘XY-pic World Wide Web home page’ with URL: http://

www.ens-lyon.fr/∼krisrose/Xy-pic.html.

XY-pic Complete Sources with TEXnical Commentary Copyright \begin{matrix}c \\ ◯ \end{matrix} 1991–1998, Kristoffer H. Rose. Copyright \begin{matrix}c \\ ◯ \end{matrix} 1993–1998, Ross Moore.

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 the XY-pic package; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

Preface

In this report we present the TEX and sources of the XY-pic package with TEXnical commentary. It assumes that you are familiar with the use of XY-pic as described in the User’s Guide [14] as well as with the fundamentals of TEX [6] and [7].

Overview. Chapter 1 explains the TEX sources of the XY-picture kernel drawing language. Chapter 2 explains the sources of the standard extensions providing extended graphic capabilities, and chapter 3 the sources of standard features providing specialised notation for particular diagram types. Chapter 5 exposes the sources of the standard fonts provided in the distribution.

The appendices contain additional information: Appendix A contains answers to all the exercises of the main text. Appendix B summarises the backwards compatibility with XY-pic version 2. Appendix C contains the GNU General Public License detailing the conditions of use of XY-pic, and appendix D various support files contained in the distribution. Finally a bibliography and the index.

The report includes most of the information in the reference manual [?].

License. Most of the XY-pic package is copyright by the individual authors. We have chosen to use the “GNU Copyleft” to make the package available without restriction to as many users as possible and ensure that it is attributed to its authors without risk of persecution. The disclaimer can be found on the inside cover page; the full text of the license is reproduced as appendix C. ii

Contents

1 Kernel: xy.doc 1

1.1 The XY-pic implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1.1 Loading XY-pic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1.2 Logo, version, and messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 1.1.3 Fonts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.1.4 Allocations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.1.5 Utility macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

1.2 Picture basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 1.2.1 Positions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 1.2.2 Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 1.2.3 Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 1.2.4 Decorations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 1.2.5 The XY-pic state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

1.3 Positions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 1.4 Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 1.5 Decorations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 1.6 Kernel object library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

1.6.1 Directionals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 1.6.2 Circle segments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 1.6.3 Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

1.7 XY-pic options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 1.7.1 Loading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 1.7.2 Option file format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 1.7.3 Driver options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

1.8 Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 1.8.1 Directions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 1.8.2 Edges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 1.8.3 Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

2 Extensions 119

2.1 Curve and Spline extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 2.1.1 Curved connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 2.1.2 Circles and Ellipses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 2.1.3 Quadratic Splines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193

2.2 Frame and Bracket extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 2.2.1 Frames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 2.2.2 Brackets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 2.2.3 Filled regions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 2.2.4 Framing as object modifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211

2.2.5 Using curves for frames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 2.3 More Tips extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214

2.3.1 End & log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 2.4 Line styles extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 2.5 Rotate and Scale extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 2.6 Colour extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 2.7 Pattern and Tile extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 2.8 Import graphics extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 2.9 Movie Storyboard extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 2.10 PostScript backend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253

2.10.1 Choosing the DVI-driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 2.10.2 Why use PostScript^{1} . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 2.10.3 Hooking into XY-pic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 2.10.4 Kernel improvements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262

2.11 TPIC backend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 2.12 em-TeX backend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276 2.13 Necula’s extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279

2.13.1 Expansion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 2.13.2 Polygon shapes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281

3 Features 291 3.1 All features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291 3.2 Dummy option . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292 3.3 Arrow and Path feature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294

3.3.1 Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 3.3.2 Arrows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307

3.4 Two-cell feature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316 3.4.1 Typesetting 2-cells in Diagrams . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 3.4.2 Standard Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 3.4.3 Nudging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 3.4.4 Extra Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 3.4.5 After Parsing... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330 3.4.6 2-cells in general XY-pictures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331

3.5 Matrix feature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341 3.5.1 XY-matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342 3.5.2 New coordinate formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 3.5.3 Spacing and rotation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 3.5.4 Entries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357

3.6 Graph feature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360 3.7 Polygon feature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369 3.8 Lattice and web feature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389 3.9 Circle, Ellipse, Arc feature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394

3.9.1 Full Circles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396 3.9.2 Ellipses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399 3.9.3 Drawing arcs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400 3.9.4 Circular and Elliptical Arcs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405

3.10 Knots and Links feature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418 3.11 Smart Path option . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445 4 Drivers 461

1PostScript is a registered Trademark of Adobe, Inc. [1].

4.1 Support for Specific Drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461 4.2 dvidrv driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461 4.3 DVIPS driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462 4.4 DVITOPS driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467 4.5 OzTeX driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472 4.6 OzTeX v1.7 driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477 4.7 Textures driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481 4.8 Textures v1.6 driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485 4.9 XDVI driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489 4.10 CMacTeX driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494 4.11 Extra features with PostScript support . . . . . . . . . . . . . . . . . . . . . . . . . 495

4.11.1 xyps-ps.doc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495 4.11.2 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497 4.11.3 Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504 4.11.4 xyps-c.doc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506 4.11.5 Colour . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507 4.11.6 xyps-f.doc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509 4.11.7 Frames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510 4.11.8 xyps-l.doc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513 4.11.9 Line-styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514 4.11.10 xyps-r.doc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516 4.11.11 Rotations and scaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517 4.11.12 xyps-t.doc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519 4.11.13 Patterns and tiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520

5 Standard Fonts 523

5.1 Semidirectional font . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523 5.1.1 xyd2.mf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523 5.1.2 xydash10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525

5.2 Directional font . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527 5.2.1 xyd.mf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527 5.2.2 xyatip10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528 5.2.3 xybtip10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530 5.2.4 xybsql10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532

5.3 Special fonts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534

5.3.1 xycirc10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534 5.4 Optional fonts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538

5.4.1 xycmat10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538 5.4.2 xycmbt10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539 5.4.3 xyeuat10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541 5.4.4 xyeubt10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542

A Answers to all exercises 545

B Backwards Compatibility 553

B.1 Version 2 Compatibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553 B.1.1 Unsupported incompatibilities . . . . . . . . . . . . . . . . . . . . . . . . . . . 554 B.1.2 Obsolete kernel features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555 B.1.3 Obsolete extensions & features . . . . . . . . . . . . . . . . . . . . . . . . . . . 560 B.1.4 Obsolete loading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563 B.1.5 Compiling v2-diagrams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 565

B.2 Obsolete fonts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567 B.2.1 xyline10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567 B.2.2 xyqc10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570 B.2.3 xymisc10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572

C GNU General Public License 577

D Distribution support files 583

D.1 Hype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583 D.1.1 CATALOG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583 D.1.2 README . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583

D.2 Installation instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585 D.2.1 TRAILER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585 D.2.2 INSTALL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587

D.3 Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594 D.3.1 MAKE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594 D.3.2 Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598

Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 628

Index 631

Chapter 1

Kernel: xy.doc

After giving an overview of the XY-pic environment in §1.1, this chapter document the basic concepts of XY-picture construction in §1.2, including the maintained ‘graphic state’. The following sections give the precise syntax rules of the main XY-pic constructions: the position language in §1.3, the object constructions in §1.4, and the picture ‘decorations’ in §1.5. §1.6 presents the kernel repertoire of objects for use in pictures; §1.7 documents the interface to XY-pic options like the standard ‘feature’ and ‘extension’ options.

Section §1.8 documents the more complicated algorithms used to compute directions, edges, and connections.

1.1 The XY-pic implementation

This section briefly discusses the various aspects of the present XY-pic kernel implementation of which the user should be aware.

1.1.1 Loading XY-pic

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

                                      \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 L^{A}TEX [10]).

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.

File header: Here is what actually happens in the header of xy.doc. It contains the copyright message, protection against loading the file more than once, and then bootstrap code to handle category codes and the DOCMODE format—we explain each separately below:

1 %% $Id: xy.doc,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %%
3 %% Basic Xy-pictures: Xy-pic bootstrap and kernel macros.
4 %% Copyright (c) 1991-1999  Kristoffer H. Rose  <krisrose@ens-lyon.fr>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.

7 %% Copyright (c) 1991-1999  Kristoffer H. Rose  <krisrose@ens-lyon.fr>
8 %%
9 %% The Xy-pic package is free software; you can redistribute it and/or modify
10 %% it under the terms of the GNU General Public License as published by the
11 %% Free Software Foundation; either version 2 of the License, or (at your
12 %% option) any later version.
13 %%
14 %% The Xy-pic package is distributed in the hope that it will be useful, but
15 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 %% for more details.
18 %%
19 %% You should have received a copy of the GNU General Public License along
20 %% with this package; if not, write to the Free Software Foundation, Inc.,
21 %% 675 Mass Ave, Cambridge, MA 02139, USA.
22 %%
23 \ifx\xyloaded\undefined\else\message{not reloaded}\endinput\fi
24 \let\xyloaded=\relax
26 % NOTE: Apart from the actual macros (as also found in xy.tex), this file
27 % contains both the Xy-pic kernel reference manual and TeXnical documentation.
28 % See xyrefer.man and xysource.man for how to typeset this information.
30 \message{Bootstrap\string'ing\string:}
32 {\catcode96 12\catcode`\#6\catcode`\.12\catcode`\:12\catcode`\'12\catcode`\@11
33 \ifx\xywarnifdefined\undefined\else \immediate\write16{}%
34 \immediate\write16{Xy-pic Warning: \string\xywarnifdefined\space redefined.}%
35 \immediate\write16{}\fi
36 \gdef\xywarnifdefined#1{\ifx#1\undefined\else \immediate\write16{}%
37 \immediate\write16{Xy-pic Warning: `\string#1' redefined.}%
38 \immediate\write16{}\fi}
39 \xywarnifdefined\xydef@ \gdef\xydef@#1{\xywarnifdefined#1\gdef#1}
40 \xywarnifdefined\xylet@ \gdef\xylet@#1{\xywarnifdefined#1\global\let#1}
41 \xywarnifdefined\xynew@
42 \gdef\xynew@#1#2{\xywarnifdefined#2\csname new#1\endcsname#2}}
44 \message{catcodes\string,}
46 \xywarnifdefined\xyuncatcodes
47 \xywarnifdefined\xyreuncatcodes \def\xyreuncatcodes{\edef\xyuncatcodes{%
48 \catcode92 0 \catcode123 1 \catcode125 2 \catcode37 14
49 \catcode 9 \the\catcode 9 \catcode10 \the\catcode10 \catcode12 \the\catcode12
50 \catcode35 \the\catcode35 \catcode36 \the\catcode36 \catcode38 \the\catcode38
51 \catcode43 \the\catcode43 \catcode45 \the\catcode45 \catcode46 \the\catcode46
52 \catcode47 \the\catcode47
53 \catcode60 \the\catcode60 \catcode61 \the\catcode61 \catcode62 \the\catcode62
54 \catcode64 \the\catcode64 \catcode96 \the\catcode96
55 \newlinechar \the\newlinechar \endlinechar \the\endlinechar }}
56 \xyreuncatcodes
58 \xywarnifdefined\xycatcodes \def\xycatcodes{%
59 \catcode 9 10

60 \catcode 35  6 \catcode 36 3 \catcode 38 4
61 \catcode 43 12 \catcode 45 12 \catcode 46 12 \catcode 47 12
62 \catcode 60 12 \catcode 61 12 \catcode 62 12
63 \catcode 64 11 \catcode 96 12 }
65 \xycatcodes
67 \message{docmode,}
69 {\catcode`\|0 \xywarnifdefined|DOCMODE
70 \gdef|DOCMODE#1{\ifx(#1\relax \xycatcodes \expandafter\ignorespaces
71 \else \skipspecials@ \expandafter\docm@\fi}%
73 \xywarnifdefined\skipspecials@
74 \gdef\skipspecials@{%
75 \catcode`\\12 \catcode`\{12 \catcode`\}12 \catcode`\#12 \catcode`\%12
76 \catcode`\^^L12 \endlinechar`\^^J }%
78 \catcode`\/=12 \lccode`\/`\\%
79 \lccode`\D`\D \lccode`\O`\O \lccode`\C`\C \lccode`\M`\M \lccode`\E`\E
80 \lowercase{%
81 \xywarnifdefined\docm@ \gdef\docm@{\docm@i}%
82 \xywarnifdefined\docm@i \gdef\docm@i#1^^J{\docm@ii#1/DOCMODE\docm@iii}%
83 \xywarnifdefined\docm@ii
84 \gdef\docm@ii#1/DOCMODE{\def\next@{#1}\futurelet\next\docm@iii}%
85 \xywarnifdefined\docm@iii \gdef\docm@iii#1\docm@iii{%
86 \ifx\next\docm@iii \let\next\next@ \docecho@ \let\next@\docm@
87 \else\ifx\next@\empty \let\next@\docfinish@
88 \else \edef\next@{\noexpand\docm@iv\next@/DOCMODE#1\noexpand\docm@iv}%
89 \fi\fi \next@}%
90 \xywarnifdefined\docm@iv
91 \gdef\docm@iv#1/DOCMODE\docm@iv{\def\next{#1}\docecho@ \docm@}}%
93 \xywarnifdefined\docecho@ \global\let\docecho@\relax
94 \xywarnifdefined\docfinish@ \gdef\docfinish@{\xyuncatcodes|DOCMODE\next}}

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 XY-pic last and get no warning messages like

                          Xy-pic Warning: ` . . . ' redefined.

In general the XY-pic kernel will check all control sequences it redefines except that (1) generic temporaries like \next are not checked, (2) predefined font identifiers (see §1.1.3) are assumed intentionally preloaded, and (3) some of the more exotic control sequence names used internally (like @{-}) are only checked to be different from \relax.

This is handled by \xywarnifdefined—after we have ensured that it is unique itself^{1}. \xydef @, \xylet @, and \xynew@{⟨type⟩} are abbreviations used to this end throughout XY-pic instead of \let, \def, and the \new⟨type⟩ commands.

1This may seem paranoid but in fact many inconvieniences in the TEX world stem from the fact that somebody copied somebody elses definition of, say, \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.

Next some auxilliaries: \xydefcsname@ is similar to \xydef@ except that it builds the control sequence with \csname … \endcsname which means that it is \relax when undefined—there is thus no way to prevent redefinition of control sequences bound to \relax ◯_{¨⌢}.

201 \xydef@\xydefcsname@#1{\DN@{#1}\DNii@##1{%
202 \ifx ##1\relax\else \xywarning@{\string`\string##1\string' redefined}\fi
203 \def##1}%
204 \expandafter\nextii@\csname\codeof\next@\endcsname}

\xyletcsnamecsname@ is to \let one weird control sequence be the same as another using several

\expandafters:

211 \xydef@\xyletcsnamecsname@#1#2{\def\1{#1}\def\2{#2}\DN@##1##2{%
212 \ifx ##1\relax\else \xywarning@{`\string##1\string' redefined}\fi
213 \let##1=##2}%
214 \expandafter\expandafter\expandafter\next@
215 \expandafter\csname\expandafter\codeof\expandafter\1\expandafter\endcsname
216  \csname\codeof\2\endcsname}

Finally \codeof: a useful hack used to allow any characters in control sequences: \codeof⟨cs⟩ expands to the characters of the control sequence ⟨cs⟩ as a string of ‘other’ characters, i.e., all of category 12 and with a ␣_{12} after every control sequence. The ⟨cs⟩ must be a macro or it blows up.

226 \xywarnifdefined\codeof
227 \xywarnifdefined\codeof@
228 {\catcode`\:=12 % to ensure that all of :-> and <-: are other :-)
229 \gdef\codeof#1{\expandafter\codeof@\meaning#1<-:}
230 \gdef\codeof@#1:->#2<-:{#2}}

Category codes: The situation is complicated by the flexibility of TEX’s input format. The culprit is the ‘category code’ concept of TEX (cf. [6, p.37]): when loaded XY-pic requires the characters ␣\{}% (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 loading of XY-pic with \makeatother … \makeatletter when loading it from within a L^{A}TEX package, and that (2) XY-pic should be loaded after files that change category codes like the german.sty that makes " active. Some styles require that you reset the catcodes for every diagram, e.g., with french.sty you should use the command \english before every \xymatrix.

We define \xyuncatcodes to restore the current catcodes, and \xycatcodes to install our own. Here is an exact list of the category codes which XY-pic requires (all standard in plain TEX):

character(s)  \     {     }  CR  TAB SP  A–Z a–z     0–9     %
category code  0  1  2  5  10  11  12  14

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 \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:

   character  #      $     &    '     +      -      .     <    =    >    @    `

ASCII code  35  36  38 39  43  45  46 60 61 62 64 96
category code  6  3  4  12  12  12  12 12 12 12 11 12

   abbreviation HASH   DOLL   AND   RQ   PLUS   DASH   DOT   LT   EQ   GT   AT   LQ

with special control sequences named \add⟨abbreviation⟩@ that take an argument and expand to it followed by the original character token, i.e., many tests throughout the program look like \addDOT@

\ifx \next . . .

293 \xywarnifdefined\addAT@
294 \xywarnifdefined\addHASH@
295 \xywarnifdefined\addDOLL@
296 \xywarnifdefined\addAND@
297 \xywarnifdefined\addRQ@
298 \xywarnifdefined\addPLUS@
299 \xywarnifdefined\addDASH@
300 \xywarnifdefined\addDOT@
301 \xywarnifdefined\addLT@
302 \xywarnifdefined\addEQ@
303 \xywarnifdefined\addGT@
304 \xywarnifdefined\addLQ@
306 \xydef@\xymakeADD@#1#2 #3 {\ifnum\catcode#3=6 \def#1##1{##1#2#2}%
307 \else \def#1##1{##1#2}\fi}
309 \xydef@\xyrecat@{\xymakeADD@\addAT@}
310 \xydef@\xyrecat{\xyrecat@}
311 \xydef@\xyresetcatcodes{\def\xyrecat{\xyrecat@}\xyreuncatcodes
312 \input xyrecat \relax \xyuncatcodes}
314 \xyuncatcodes \xyresetcatcodes \xycatcodes
316 \xydef@\testAND@{{\aftergroup\ifx
317 \addAND@\ifx\next\addFalse@\else\addTrue@\fi}}
318 \xydef@\addFalse@{\aftergroup\iffalse}
319 \xydef@\addTrue@{\aftergroup\iftrue}

However, it is possible to ‘repair’ the problem in case any of the characters #$&'+-.<=>` change category code:

                                  \xyresetcatcodes

will load the file xyrecat.tex (version 3.3) to do it.

1 %% $Id: xyrecat.doc,v 3.3 1996/12/19 03:31:56 krisrose Exp $
2 %%
3 %% Xy-pic ``Reset Category Codes'' utility.
4 %% Copyright (c) 1994-1996      Kristoffer H. Rose      <krisrose@brics.dk>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996      Kristoffer H. Rose      <krisrose@brics.dk>

9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%

Header: The command is defined in xy.doc: the purpose of this file is to be reloadable such that the characters can be reread by TEX with fresh catcodes.

The code redefines the special \add… @ control sequences used for parsing of just those characters, assuming \next is defined correctly before loading it:

51 %\xyreuncatcodes
52 \xyuncatcodes
54 \xyrecat @ 64 \catcode 64 11
56 \xymakeADD@\addHASH@    # 35
57 \xymakeADD@\addDOLL@    $ 36
58 \xymakeADD@\addAND@     & 38
59 \xymakeADD@\addRQ@      ' 39
60 \xymakeADD@\addPLUS@    + 43
61 \xymakeADD@\addDASH@    - 45
62 \xymakeADD@\addDOT@     . 46
63 \xymakeADD@\addLT@      < 60
64 \xymakeADD@\addEQ@      = 61
65 \xymakeADD@\addGT@      > 62
66 \xymakeADD@\addLQ@      ` 96
68 \endinput
70 % $Log: xyrecat.doc,v $
71 % Revision 3.3  1996/12/19 03:31:56  krisrose
72 % Maintenance release

73 %

74 % Revision 3.1  1995/09/05 20:31:32  kris
75 % Releasing!

76 %

77 % Revision 3.0  1995/07/07  20:14:21  kris
78 % Major release w/new User's Guide!

79 %

80 % Revision 2.13  1995/07/04  15:11:17  kris
81 % Ready to release v3?

83 % NEW file to go in version 3!

The last block of the XY-pic header bootstraps the “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 §D.3.2 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 L^{A}TEX package used to typeset XY-pic documentation; please read it if you intend to write XY-pic options.

Integration with standard formats This is handled by the xyidioms.tex file and the integration as a L^{A}TEX [10] package by xy.sty.

We input xyidioms.tex from the kernel:

350 \input xyidioms

xyidioms.doc: This included file provides some common idioms whose definition depends on the used format such that XY-pic can use predefined dimension registers etc. and yet still be independent of the format under which it is used. The current version (3.4) handles plain TEX (version 2 and 3 [6]), AMS-TEX (version 2.0 and 2.1 [17]), L^{A}TEX (version 2.09 [9] and 2ε [10]), AMS-L^{A}TEX (version 1.0, 1.1 [2], and 1.2), and eplain (version 2.6 [3])^{2}.

1 %% $Id: xyidioms.doc,v 3.4 1997/05/18 01:14:25 krisrose Exp $
2 %%
3 %% Format-dependent idioms for Xy-pic.
4 %% Copyright (c) 1991-1997  Kristoffer H. Rose  <krisrose@brics.dk>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997  Kristoffer H. Rose  <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyidiomsloaded\empty \message{not reloaded}\endinput \fi
25 \let\xyidiomsloaded=\empty

Header: This is a separate file so that we can abort the definitions easily using \endinput.

2The ‘v2’ feature introduces some name conflicts, in order to maintain compatibility with earlier versions of XY-pic.

Scratch registers: All the formats currently treated allow the use of the following plain TEX scratch register conventions (cf. [6, p.346])

• \count@ is available as a local scratch counter register.

   • \dimen@, \dimen@i, \dimen@ii, \dimen3 to \dimen9, and \dimen255 are available as scratch

dimension registers.

• \skip@, \skip1 to \skip9, and \skip255 are available as scratch skip registers.

• \toks@ and \toks1 to \toks9 are available as scratch token lists.

• \boxz@ and \box1 to \box9 are available as scratch box registers.

with the constraint that \global should never (always) be used when assigning to number 0, 2, 4, 6, 8, and 255 (1, 3, 5, 7, and 9).

XY-specific scratch registers: We first give new names to dimension registers 4, 6, and 8, since none of the formats do that: \A@, \B@, and \R@ are specific to XY-pic and will be referred to as A, B, and R in comments.

85 \xywarnifdefined\A@ \dimendef\A@=4
86 \xywarnifdefined\B@ \dimendef\B@=6
87 \xywarnifdefined\R@ \dimendef\R@=8

Some shared scratch registers are defined last.

Idioms: First check that \undefined is indeed undefined… or rather: the same as an extremely unlikely control sequence that we are making up:

98 \ifx\undefined\AveryUNLIKELYc@ntr@lSEQUENCE@@\else
99 \errmessage{Xy-pic Error: \string\undefined\space defined.}\fi

These idioms are so common they are just conditionally defined:

105 \ifx\undefined\literal@ \def\literal@#1{#1}\fi
106 \ifx\undefined\eat@     \def\eat@#1{}\fi
108 \xydef@\xyFN@{\futurelet\next} % Now private because of AMS-LaTeX change.
109 \ifx\undefined\DN@      \def\DN@{\def\next@}\fi
110 \ifx\undefined\DNii@    \def\DNii@{\def\nextii@}\fi
112 \ifx\undefined\setboxz@h\def\setboxz@h{\setbox\z@\hbox}\fi
113 \ifx\undefined\wdz@     \def\wdz@{\wd\z@}\fi
114 \ifx\undefined\boxz@    \def\boxz@{\box\z@}\fi
116 \ifx\undefined\W@       \def\W@{\immediate\write16 }\fi
118 \ifx\undefined\space@   \def\space@.{\futurelet\space@\relax}\space@. \fi
120 \ifx\undefined\notempty \def\notempty#1{T\if @#1@F\else T\fi}\fi

Delayed setup: This is used when it is advantageous to delay loading of something until after the preamble, i.e., after all options, etc., have been loaded. This is particularly true for nested \xywithoption uses that will otherwise be executed repeatedly. Currently properly supported with L^{A}TEX 2ε and the amsppt style of AMS-TEX.

132 \xydef@\xysetup@dummy#1{\xyuncatcodes#1}

133 \xywarnifdefined\xysetup@@
135 \ifx\AtEndDocument\undefined
136 \expandafter\ifx\csname amsppt.sty\endcsname\relax
137 \let\xysetup@@=\xysetup@dummy
138 \else
139 \def\xysetup@@#1{%
140  \expandafter\def\expandafter\topmatter\expandafter{\topmatter
141  #1\xyuncatcodes}}\fi
142 \else
143 \def\xysetup@@#1{\AtBeginDocument{#1\xyuncatcodes}}
144 \fi
146 \ifx\xysetup@@\xysetup@dummy\else
147 \xysetup@@{\let\xysetup@@=\xysetup@dummy \xyuncatcodes}\fi

Similarly, the following provides a place to insert ‘trailing messages’ if the format supports it; otherwise it just throws away the argument (useful for repeating the most important warnings).

155 \xywarnifdefined\xyclosedown@@
157 \ifx\AtEndDocument\undefined \let\xyclosedown@@=\eat@
158 \else \def\xyclosedown@@#1{\AtEndDocument{#1}}\fi

This may be useful to hook into specialised mechanisms for including \special material on the page.

165 \xylet@\xy@begindvi=\literal@

For example, L^{A}TEX 2ε (post Dec ’94) defines an \AtBeginDvi macro to allow zero-sized material to be placed at the beginning of each shipped-out page. Among other uses, this allows such material not to be discarded, when on a page containing only floats. This is used by XY-pic in connection with the PostScript header dictionary xyps-ps.doc.

175 \ifx\undefined\AtBeginDvi\else
176 \AtBeginDocument{\let\xy@begindvi=\AtBeginDvi}
177 \AtBeginDvi{\global\let\xy@begindvi=\literal@}\fi

Shared scratch registers: Everything else in this file is also done by AMS-TEX so we exit here when using that format after renaming their \toks@@ to \toks@ii…

187 \ifx\amstexloaded@\relax
188 \xylet@\toks@ii=\toks@@ \endinput \fi

Thus the job of allocating scratch registers is simple except for counters where we only have one so we use L^{A}TEX scratch counters when available and otherwise allocate two new ones:

196 \ifx\@tempcnta\undefined
197 \xynew@{count}\count@@
198 \xynew@{count}\count@@@
199 \else
200 \xylet@\count@@=\@tempcnta
201 \xylet@\count@@@=\@tempcntb
202 \fi

Finally the second scratch token register not available with L^{A}TEX.

208 \ifx\undefined\toks@ii  \toksdef\toks@ii=2 \fi

10 CHAPTER 1. KERNEL: XY.DOC End & log: That’s all.

216 \endinput
218 % $Log: xyidioms.doc,v $
219 % Revision 3.4  1997/05/18 01:14:25  krisrose
220 % Essential bugfixes.

221 %

222 % Revision 3.3  1996/12/19 03:31:56  krisrose
223 % Maintenance release

224 %

225 % Revision 3.1  1995/09/05  20:31:32  kris
226 % Releasing!

227 %

228 % Revision 3.0  1995/07/07  20:14:21  kris
229 % Major release w/new User's Guide!

230 %

231 % Revision 2.13  1995/07/04  15:11:17  kris
232 % Ready to release v3?

233 %

234 % Revision 2.12  1994/10/25  11:34:25  kris
235 % Interim release just before v3 [works with AMS-LaTeX 1.2]...

236 %

237 % Revision 2.11  1994/07/05  10:37:32  kris
238 % Third 3beta release [bug fixes].
239 % Experimental graph feature included (for ECCT-94 presentation).

240 %

241 % Revision 2.9  1994/06/09  15:02:49  kris
242 % Release 3beta.

243 %

244 % Revision 2.8  1994/04/08  04:30:00  kris
245 % Second (bug fix) 3alpha release.

246 %

247 % Revision 2.7  1994/03/08  02:06:01  kris
248 % Release 3alpha.

249 %

250 % Revision 2.6.9.1  1994/03/07  04:22:46  kris
251 % Last internal 3alpha and pre-2.7 release.

252 %

253 % Now contains scratch register allocations.
254 % Cleaned of AMS-TeX special macros.
255 % Renamed from xyamstex.doc to xyidioms.doc for version 2.7.

256 %

257 % Revision 2.4  1992/01/22  02:15:10  kris
258 % \\ works with AMS-LaTeX: don't use \Let@ [Werner Struckmann/Darrel Hankerson]
259 % Made redefinition of \text conditional.

260 %

261 % Revision 2.3  1992/01/10  21:43:09  kris
262 % Fixed AMS-LaTeX name clash problems.

263 %

264 % Revision 2.2  1992/01/09  04:05:40  kris

265 % Patched to fix problem with \text and support AMS-LaTeX.

266 %

267 % Revision 2.1  1992/01/02  14:55:27  kris
268 % Release version.

269 %

270 % Revision 1.3  1991/12/17  04:51:16  kris
271 % Version distributed with `final draft' on Usenet.

xy.sty: If you use L^{A}TEX then this file makes it possible to load XY-pic as a ‘package’ using the L^{A}TEX 2ε [10] \usepackage command:

                            \usepackage [⟨option⟩,. . . ] {xy}

where the ⟨option⟩s will be interpreted as if passed to \xyoption (cf. §1.7).

The only exceptions to this are the options having the same names as those driver package options of chapter ??, which appear in cf. [4, table 11.2, p.317] or the L^{A}TEX 2ε graphics bundle. These will automatically invoke any backend extension required to best emulate the L^{A}TEX 2ε behaviour. (This means that, e.g., [dvips] and [textures] can be used as options to the \documentclass command, with the normal effect.)

The file also works as a L^{A}TEX 2.09 [9] ‘style option’ although you will then have to load options with the \xyoption mechanism described in §1.7.

Here is the raw source of xy.sty.

1 %% $Id: xy.sty,v 3.3 1996/12/19 03:31:56 krisrose Exp $
2 %%
3 %% ``Xy-pic as LaTeX 2.09 style option and LaTeX 2e package''.
4 %% Copyright (c) 1993-1996      Kristoffer H. Rose      <krisrose@brics.dk>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996      Kristoffer H. Rose      <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
24 % Load Xy-pic with catcode of @ set as it will be in user text:
25 \count255=\the\catcode`\@ {\catcode`\@=11 \xdef\xystycatcode{\the\count255}}
26 \makeatletter
28 % REPAIR bug of the 2e version of AMS-LaTeX where \makeatother is broken...

29 \ifx\@ifpackageloaded\undefined \makeatother
30 \else \@ifpackageloaded{amstex}{\catcode`\@=\active}{\makeatother}\fi
32 \input xy
34 % That is all unless this is called as a LaTeX2e `native mode' package.  Is
35 % there an official way to check this?  Anyway, this seems to work:
36 \makeatletter
37 \ifx\if@compatibility\undefined \catcode`\@=\xystycatcode \endinput \fi
39 % Ensure that we are *really* running LaTeX2e...!
40 \NeedsTeXFormat{LaTeX2e}
42 % This file provides the current version of Xy-pic!
43 \edef\next{%
44 \noexpand\ProvidesPackage{xy}[\xydate\space Xy-pic version \xyversion]}\next
46 % Recognise some standard LaTeX2e class options (cf. `LaTeX Companion' p.317):
47 \DeclareOption{cmactex}{\xyoption{cmactex}}
48 \DeclareOption{dvips}{\xyoption{dvips}\xyoption{ps}}
49 \DeclareOption{dvitops}{\xyoption{dvitops}\xyoption{ps}}
50 \DeclareOption{emtex}{\xyoption{emtex}}
51 \DeclareOption{ln}{\xywarning@{`ln' DVI driver not yet fully supported}}
52 \DeclareOption{oztex}{\xyoption{oztex}}
53 \DeclareOption{textures}{\xyoption{textures}}
54 \DeclareOption{xdvi}{\xyoption{xdvi}}
56 % This is special:
57 \DeclareOption{colour}{\xyoption{color}} % :-)
59 % This (obsolete) cmtip style option should be activated after loading:
60 \DeclareOption{cmtip}{\xyoption{cmtip}\UseComputerModernTips}
62 % Pass the desired tip size if defined
63 \DeclareOption{10pt}{\xywithoption{tips}{\def\tipsize@@{10}}}
64 \DeclareOption{11pt}{\xywithoption{tips}{\def\tipsize@@{11}}}
65 \DeclareOption{12pt}{\xywithoption{tips}{\def\tipsize@@{12}}}
67 % Other options are just loaded.
68 \DeclareOption*{\edef\next{\noexpand\xyoption{\CurrentOption}}\next}
70 % Reinstall catcode of @...
71 \catcode`\@=\xystycatcode
73 % ... process the options, and that is all.
74 \ProcessOptions
76 \endinput
78 % $Log: xy.sty,v $
79 % Revision 3.3  1996/12/19 03:31:56  krisrose
80 % Maintenance release

81 %

82 % Revision 3.1  1995/09/05  20:31:32  kris
83 % Releasing!

84 %

85 % Revision 3.0  1995/07/07  20:14:21  kris
86 % Major release w/new User's Guide!

87 %

88 % Revision 2.13  1995/07/04  15:11:17  kris
89 % Ready to release v3?

90 %

91 % Revision 2.12  1994/10/25  11:34:25  kris
92 % Interim release just before v3 [works with AMS-LaTeX 1.2]...

93 %

94 % Revision 2.9  1994/06/09  14:59:19  kris
95 % Release 3beta.

96 %

97 % Revision 2.8  1994/04/08  04:30:00  kris
98 % Second (bug fix) 3alpha release.

99 %

100 % Revision 2.7  1994/03/08  02:06:01  kris
101 % Release 3alpha.

102 %

103 % New for version 2.7.

1.1.2 Logo, version, and messages

Loading XY-pic prints a banner containing the version and author of the kernel; small progress messages are printed when each major division of the kernel has been loaded. Any options loaded will announce themself in a similar fashion.

Of these, \stripRCS is a very useful hack for extracting the first component of an RCS $… $ keyword value.

412 \xydef@\stripRCS$#1${\stripRCS@#1: @@ @@@}
413 \xydef@\stripRCS@#1: #2@ #3@@@{%
414 \ifx @#2\string?\else\ifx :#2\else\stripRCS@@#2\fi\fi}
415 \xydef@\stripRCS@@#1 #2: @{#1}
417 \edef\next{\stripRCS$Revision: 3.7 $}
418 \xylet@\xyversion=\next
420 \edef\next{\stripRCS$Date: 1999/02/16 15:12:50 $}
421 \xylet@\xydate=\next
423 \xydef@\Xygreet@{%
424 \W@{}%
425 \W@{ Xy-pic version \xyversion\space<\xydate>}%
426 \W@{ Copyright (c) 1991-1998 by Kristoffer H. Rose <krisrose@ens-lyon.fr>}%
427 \W@{ Xy-pic is free software: see the User\string's Guide for details.}%
428 \W@{}}
429 \Xygreet@
430 \expandafter\everyjob\expandafter{\the\everyjob\Xygreet@}
432 \message{Loading kernel:}

If you refer to XY-pic in your written text (please do ◯_{¨⌣}) then you can use the command \Xy-pic to typeset the “XY-pic” logo. The version of the kernel is typeset by \xyversion and the release date by \xydate (as found in the banner). By the way, the XY-pic name^{3} 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.

3No description of a TEX program is complete without an explanation of its name.

451 \xydef@\Xy{\leavevmode
452 \hbox{\kern-.1em X\kern-.3em\lower.4ex\hbox{Y\kern-.15em}}}

Messages that start with “Xy-pic Warning” are indications that something needs your attention; an “Xy-pic Error” will stop TEX because XY-pic does not know how to proceed.

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. \newlinechar is set locally to ^^J while writing such that messages of several lines can be written.

469 \message{messages;}
471 \xywarnifdefined\thelineno@
472 \ifx\inputlineno\undefined \edef\thelineno@{\string?}
473 \else \def\thelineno@{\the\inputlineno}\fi
474 \xydef@\xytracelineno@{ \string[\jobname:\thelineno@\string]}
476 \xydef@\xywarning@#1{{\newlinechar=10 %
477 \W@{}\W@{Xy-pic Warning: #1\xytracelineno@.}\W@{}}}
479 \xydef@\xyerror@#1#2{\if\inxy@\xy@{ERROR #1}{}\fi
480 {\def\2{#2}\newlinechar=10 %
481 \ifx\2\empty \errhelp{See the Xy-pic manual for further information.}%
482 \else \errhelp{#2}\fi
483 \errmessage{Xy-pic error: #1}}}

Finally one that I hope will never get expanded ◯_{¨⌢}

489 \xydef@\xybug@#1{{\newlinechar=10 %
490 \errhelp{This is a bug in Xy-pic and should not happen!^^J%
491 If it did then please send a bug report with the offending Xy-pic code^^J%
492 to the author of Xy-pic, krisrose@ens-lyon.fr.}%
493 \errmessage{Xy-pic BUG: #1 -- notify krisrose@ens-lyon.fr.}}}

1.1.3 Fonts

The XY-pic kernel implementation makes its drawings using five specially designed fonts:

Font  Characters  Default

                     \xydashfont         dashes  xydash10

                     \xyatipfont

arrow tips, upper half

                                                       xyatip10
                     \xybtipfont

arrow tips, lower half

                                                       xybtip10
                     \xybsqlfont

quarter circles for

                                                       xybsql10

hooks and squiggles

                     \xycircfont

1/8 circle segments

                                                       xycirc10

The first four contain variations of characters in a large number of directions, the last contains 1/8 circle segments.

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.

To be more precise, XY-pic requires \xydashfont to be a semidirectional font as will generate with the driver file xyd2.mf—this is very important because the italic corrections of the characters in this particular font are used to approximate trigonometric computations, so if you replace \xydashfont be sure to replace it with another semidirectional font! Similarly, the three fonts \xyatipfont, \xybtipfont, and \xybsqlfont should be directional as will generate with the driver file xyd.mf.

Finally, \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 dimen-

sions for \xydashfont and \xybsqlfont: for each of these f we define f_{ℓ} 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).

557 \message{fonts;}
559 \xydef@\xyfont@#1{\ifx#1\undefined \DN@{\global\font#1}\expandafter\next@
560 \else \xywarning@{Using previously loaded \string#1\space font}\fi}
562 \xyfont@\xydashfont=xydash10
563 \xydef@\xydashl@{\fontdimen6\xydashfont}
564 \xydef@\xydashh@{\fontdimen5\xydashfont}
565 \xydef@\xydashw@{\fontdimen8\xydashfont}
567 \xyfont@\xyatipfont=xyatip10
568 \xyfont@\xybtipfont=xybtip10
570 \xyfont@\xybsqlfont=xybsql10
571 \xydef@\xybsqll@{\fontdimen6\xybsqlfont}
572 \xydef@\xybsqlh@{\fontdimen5\xybsqlfont}
573 \xydef@\xybsqlw@{\fontdimen8\xybsqlfont}
575 \xyfont@\xycircfont=xycirc10

1.1.4 Allocations

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 L^{A}TEX; 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).

598 \message{allocations:}

See §1.1.1 for scratch register allocations.

Picture state: These realise the picture state as described in §1.2.5: c, p, the base, and the picture size:

609 \message{state,}
611 \xynew@{dimen}\X@c
612 \xynew@{dimen}\Y@c

613 \xynew@{dimen}\U@c
614 \xynew@{dimen}\D@c
615 \xynew@{dimen}\L@c
616 \xynew@{dimen}\R@c
617 \xynew@{toks}\Edge@c
619 \xynew@{dimen}\X@p
620 \xynew@{dimen}\Y@p
621 \xynew@{dimen}\U@p
622 \xynew@{dimen}\D@p
623 \xynew@{dimen}\L@p
624 \xynew@{dimen}\R@p
625 \xynew@{toks}\Edge@p
627 \xynew@{dimen}\X@origin \X@origin=\z@
628 \xynew@{dimen}\Y@origin \X@origin=\z@
629 \xynew@{dimen}\X@xbase  \X@xbase=1mm
630 \xynew@{dimen}\Y@xbase  \Y@xbase=\z@
631 \xynew@{dimen}\X@ybase  \X@ybase=\z@
632 \xynew@{dimen}\Y@ybase  \Y@ybase=1mm
634 \xynew@{dimen}\X@min
635 \xynew@{dimen}\Y@min
636 \xynew@{dimen}\X@max
637 \xynew@{dimen}\Y@max

Drop and connect: \lastobjectbox@ stores the most recently dropped object.

646 \xynew@{box}\lastobjectbox@

\zerodotbox@ 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; \zz @ is ‘almost-zero-check’.

654 \xynew@{box}\zerodotbox@
655 \setbox\zerodotbox@=\hbox{\dimen@=.5\xydashw@
656 \kern-\dimen@ \vrule width\xydashw@ height\dimen@ depth\dimen@}
657 \wd\zerodotbox@=\z@ \ht\zerodotbox@=\z@ \dp\zerodotbox@=\z@
659 \xynew@{dimen}\almostz@ \almostz@=50sp
660 \xydef@\zz@#1{\ifdim#1<\z@-\fi#1<\almostz@\relax}
662 \xynew@{if}\iftmp@

Direction state: The direction state is rather complicated and described in detail in §1.8.1.

671 \message{direction,}
673 \xynew@{dimen}\d@X
674 \xynew@{dimen}\d@Y
675 \xydef@\sd@X{}
676 \xydef@\sd@Y{}
678 \xynew@{count}\K@ \K@=1024
679 \xynew@{count}\KK@ \KK@=32
681 \xynew@{count}\Direction

682 \xynew@{dimen}\K@dXdY
683 \xynew@{dimen}\K@dYdX
685 \xydef@\cosDirection{}
686 \xydef@\sinDirection{}
688 \xywarnifdefined\DirectionChar
689 \xywarnifdefined\SemiDirectionChar

Miscellaneous: Finally some generic allocations used in the following:

697 \xynew@{read}\xyread@                   % for `safe input'
698 \xynew@{write}\xywrite@                 % for `saving' to .xyc file
700 \xynew@{count}\csp@                     % for `control stack pointer'
701 \xynew@{dimen}\quotPTK@                 % for `fractions'

The required temporaries are defined by xyidioms.tex.

1.1.5 Utility macros

Finally we define some utility macros.

715 \message{utility macros;}

Simple queue: Just appending to the \toks @ list.

724 \xydef@\addtotoks@#1{\toks@=\expandafter{\the\toks@#1}}

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.

735 \xydef@\xyinputorelse@#1#2{%
736 \expandafter\let\expandafter\next@\csname#1loaded\endcsname
737 \ifx\next@\empty \else
738 \DN@{\xyinputorelse@@{#1}{\xyinputorelse@@{#1.doc}{#2}}}%
739 \fi \next@}
741 \xydef@\xyinputorelse@@#1#2{\openin\xyread@=#1 %
742 \ifeof\xyread@ \DN@{#2}\else \DN@{\closein\xyread@\input#1 }\fi \next@}

Continuation stack: This is used to ‘enter’ a new context and ‘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

\csp@  ‘Continuation Stack Pointer’

\enter@{⟨code⟩} Enter new block with ⟨code⟩ expanded as continu-

ation

\nter@{⟨code⟩} Enter new block with⟨code⟩ as continuation
\dontleave@  Execute continuation without leaving block
\unenter@  Leave block without executing its continuation
\leave@  Leave block (execute its continuation)

   So \enter@{}\leave@ is a noop and \leave@ is the same as \dontleave@\unenter@.

765 \global\csp@=\z@
767 \xydef@\enter@#1{\global\advance\csp@\@ne
768 \expandafter\xdef\csname cs@\number\csp@\endcsname{#1}\ignorespaces}
770 \xydef@\nter@#1{\global\advance\csp@\@ne
771 \expandafter\gdef\csname cs@\number\csp@\endcsname{#1}\ignorespaces}
773 \xydef@\dontleave@{\csname cs@\number\csp@\endcsname}
775 \xydef@\unenter@{\global\advance\csp@\m@ne}
777 \xydef@\leave@{\expandafter\unenter@\csname cs@\number\csp@\endcsname}

Fractions: 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.

\quotient@ ⟨cs⟩ {A} {B} Defines ⟨cs⟩ to expand (immediately) to the factor corresponding to A/B; A, B must be dimensions where |A| < \maxdimen/KK and |B| > KK

\quotient@@ ⟨cs⟩ {A} {B} Same, but uses 8KK for KK.

Notes: (1) If \c is a count register, then {1\c} is a legal dimension. (2) Really computes

((A × |KK|)/(B/ |KK|)) × (1pt/ |K|)

and then defines ⟨cs⟩ to expand to the resulting pt value. This means that results are only reasonable for |A| ≪ \maxdimen/KK and |B| ≫ KK.

807 \quotPTK@=\p@ \divide\quotPTK@\K@
808 \xylet@\quotsign@@=\empty
809 \xywarnifdefined\removePT@
810 {\catcode`p=12 \catcode`t=12 \gdef\removePT@#1pt{#1}}
812 \xydef@\quotient@#1#2#3{\A@=#2\relax \B@=#3\relax
813 \ifdim\A@<\z@\def\quotsign@@{-}\else\def\quotsign@@{+}\fi
814 \ifdim\quotsign@@\A@<15pt \multiply\A@\K@
815 \else\ifdim\quotsign@@\A@<511pt \multiply\A@\KK@
816  \advance\B@\ifdim\B@<\z@-\fi 16sp \divide\B@\KK@
817 \else
818  \advance\B@\ifdim\B@<\z@-\fi 512sp \divide\B@\K@
819 \fi\fi
820 \ifdim\ifdim\B@<\z@-\fi\B@<\quotPTK@ \xywarning@{division overflow}%
821 \else \advance\A@.5\B@ \divide\A@\B@ \fi
822 \multiply\A@\quotPTK@ \edef#1{\expandafter\removePT@\the\A@}}
824 \xydef@\quotient@@#1#2#3{\A@=#2\relax \B@=#3\relax \multiply\A@\KK@
825 \advance\B@\ifdim\B@<\z@-\fi 128sp \divide\B@\KK@ \divide\B@ 8 %
826 \ifdim\B@=\z@\else \advance\A@.5\B@ \divide\A@\B@ \fi
827 \B@=.125\quotPTK@ \multiply\A@\B@ \edef#1{\expandafter\removePT@\the\A@}}

Loops: XY-pic uses its own \loop@ to avoid interference with plain \loop.

836 \xydef@\loop@#1\repeat@{\def\body@{#1}\iterate@}\xylet@\repeat@=\fi
837 \xydef@\iterate@{\body@\expandafter\iterate@\else\fi}

Execution: All execution of XY-commands should be ‘indirect’, i.e., 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.

854 \xydef@\xyinitial@#1#2{\DN@{#1}%
855 \xyerror@{command used out of context: \codeof\next@}{}}
857 \xylet@\xy@=\xyinitial@
858 \xylet@\oxy@=\xy@
860 \xydef@\change@oxy@#1{\let\oxy@=#1\relax
861 % \W@{*OXY@:=\meaning\oxy@}%

862 }

This is also used to check whether an XY-picture is already active; use as \if\inxy@… \else… \fi:

869 \xydef@\inxy@{T\ifx\xy@\xyinitial@ F\else T\fi}

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@{… } is the same as \xy@@{\global\toks9={… }} except for the category codes used for the ….

879 \xydef@\xyxy@@ix@{\begingroup
880 \xyuncatcodes\afterassignment\endgroup\global\toks9=}

This to save some tokens – maybe not worth it:

886 \xydef@\xy@@{\xy@{}}

Finally this to establish a sane state – only use within a group!

892 \xydef@\plainxy@{\let\xy@=\xyxy@ \change@oxy@\xy@ \let\xy@@ix@=\xyxy@@ix@}

To Do: 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…

1.2 Picture 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:

\xy ⟨pos⟩ ⟨decor⟩ \endxy

builds a box with an XY-picture (L^{A}TEX users may substitute \begin{xy} … \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 § and in more depth in the following §§.

The code for the \xy… \endxy command is presented last in this section.

1.2.1 Positions

All positions may be written <X,Y > where X is the TEX dimension distance right and Y the distance up from the zero position 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 \xy… \endxy command together with the four parameters X_{min}, X_{max}, Y_{min}, and Y_{max} set such that all the objects in the picture are ‘contained’ in the following rectangle:

[figure: ∘; 0; TEX reference point; •; X_{min}; X_{max}; Y_{min}; Y_{max}]

where the distances follow the “up and right > 0” principle, e.g., 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} ≤ X_{max} ∧ Y_{min} ≤ Y_{max} always holds. The possible positions are described in detail in §1.3.

When an XY-picture is entered in math mode then the reference point becomes the “vcenter” instead, i.e., we use the point <X_{min},-\the\fontdimen22> as reference point.

1.2.2 Objects

The simplest form of putting things into the picture is to ‘drop’ an object at a position. An object is like a TEX box except that it has a general Edge around its reference point—in particular this has the extents (i.e., it is always contained within) the dimensions L, R, U, and 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 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:

∘^{L}  ^{R}_{D}^{U} TEX reference point ^{•}

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 §1.4.

1.2.3 Connections

Besides having the ability to be dropped at a position in a picture, all objects may be used to connect the two current objects of the state, i.e., 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:

[figure: p; c; \begin{matrix}∘ & ^{L} & ^{R} & ^{D} & ^{U} \\ ∘ & ^{L} & ^{R} & ^{D} & ^{U} \\ ∘ & ^{L} & ^{R} & ^{D} & ^{U} \\ ∘ & ^{L} & ^{R} & ^{D} & ^{U} \\ ∘ & ^{L} & ^{R} & ^{D} & ^{U} \\ ∘ & ^{L} & ^{R} & ^{D} & ^{U} \\ ∘ & ^{L} & ^{R} & ^{D} & ^{U} \\ ∘ & ^{L} & ^{R} & ^{D} & ^{U} \\ ∘ & ^{L} & ^{R} & ^{D} & ^{U} \\ ∘ & ^{L} & ^{R} & D & ^{U} \end{matrix}]

The ways the various objects connect are described along with the objects.

1.2.4 Decorations

When the \xy command reaches something that can not be interpreted as a continuation of the position being read, then it is expected to be a decoration, i.e., in a restricted set of TEX commands which add to pictures. Most such commands are provided by the various user options (cf. §1.7)—only a few are provided within the kernel to facilitate programming of such options (and user macros) as described in §1.5.

1.2.5 The XY-pic state

Finally we summarise the user-accessible parts of the XY-picture state of two positions together with the last object associated with each: the previous, p, is the position <X_{p}, Y_{p}> with the object L_{p}, R_{p}, D_{p}, U_{p}, Edge_{p}, and the current, c, is the position <X_{c}, Y_{c}> with the object L_{c}, R_{c}, D_{c}, U_{c}, Edge_{c}.

Furthermore, XY-pic has a configurable cartesian coordinate system described by an origin position <X_{origin},Y_{origin}> and two base vectors <X_{xbase},Y_{xbase}> and <X_{ybase},Y_{ybase}> accessed by the usual notation using parentheses:

(x,y) = < X_{origin} + x × X_{xbase} + y × X_{ybase} ,
Y_{origin} + x × Y_{xbase} + y × Y_{ybase} >

This is explained in full when we show how to set the base in note 1.3d of §1.3.

Finally typesetting a connection will setup a “placement state” for referring to positions on the connection that is accessed through a special ? position construction; this is also discussed in detail in §1.3.

The XY-pic state consists of all these parameters together. They are initialised to zero except for X_{xbase} = Y_{ybase} = 1mm.

The edges are are available to the programmer as token lists; see §1.8.2 for details.

Procedure: \xy … \endxy builds an object from an XY-pic ⟨pos⟩ ⟨decor⟩ sequence as follows: (l.1114) \xy starts the \hbox to contain the XY-picture, (l.1115) 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 (l.1117) 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 \mathsurround is set to zero to make changes into math mode safe.

1107 \message{pictures: \string\xy,}
1109 \xydef@\xy{\ifmmode\expandafter\xymath@\else\expandafter\xynomath@\fi}
1110 \xydef@\xymath@{\hbox\bgroup \dimen@=\the\fontdimen22\textfont\tw@ \xyinside@}
1111 \xydef@\xynomath@{\hbox\bgroup \dimen@=\z@ \xyinside@}
1113 \xydef@\xyinside@{%
1114 \saveXyStyle@ \aftergroup\xycheck@end
1115 \setboxz@h\bgroup
1116 \plainxy@
1117 \X@c=\z@ \Y@c=\z@ \czeroEdge@
1118 \X@p=\z@ \Y@p=\z@ \U@p=\z@ \D@p=\z@ \L@p=\z@ \R@p=\z@ \Edge@p={\zeroEdge}%
1119 \X@min=\hsize \X@max=-\hsize \Y@min=\hsize \Y@max=-\hsize
1120 \mathsurround=\z@
1121 \expandafter\POS\everyxy@@}
1123 \xydef@\czeroEdge@{\U@c=\z@ \D@c=\U@c \L@c=\U@c \R@c=\U@c \Edge@c={\zeroEdge}}

1125 \xydef@\xyxy@#1#2{#2}
1127 \xywarnifdefined\everyxy
1128 \expandafter\def\addEQ@\everyxy#1{\def\everyxy@@{#1}\ignorespaces}
1130 \xylet@\everyxy@@=\empty

When finished \endxy does a \relax to disable any parser still active and (l.1144) resets the size of the generated box to zero if no (unhidden) objects were inserted, and (l.1148) defines a command to end both the temporary and the ‘proper’ box and set its size correctly—this uses \edef to expand the required dimensions used within the temporary box before leaving the two groups (namely the temporary box and the ‘proper’ box).

1142 \xydef@\endxy{\if\inxy@\else\xyerror@{Unexpected \string\endxy}{}\fi
1143 \relax
1144 \dimen@=\Y@max \advance\dimen@-\Y@min
1145 \ifdim\dimen@<\z@ \dimen@=\z@ \Y@min=\z@ \Y@max=\z@ \fi
1146 \dimen@=\X@max \advance\dimen@-\X@min
1147 \ifdim\dimen@<\z@ \dimen@=\z@ \X@min=\z@ \X@max=\z@ \fi
1148 \edef\tmp@{\egroup
1149  \setboxz@h{\kern-\the\X@min\boxz@}%
1150  \ht\z@=\the\Y@max \dp\z@=-\the\Y@min \wdz@=\the\dimen@
1151  \noexpand\maybeunraise@ \raise\dimen@\boxz@
1152  \noexpand\recoverXyStyle@ \egroup \noexpand\xy@end
1153  \U@c=\the\Y@max \D@c=-\the\Y@min \L@c=-\the\X@min \R@c=\the\X@max}\tmp@}
1155 \xydef@\maybeunraise@{\if\inxy@\else \dimen@ii=\dp\z@
1156 \ifdim\dimen@ii<\z@ \advance\dimen@\dimen@ii \fi\fi}

If an \xy is not properly closed by an \endxy then the error message is produced. This happens if (a) too many \xys or (b) too many \endxys or (c) if there is the correct number of each but the grouping becomes unbalanced due to a misplaced } or \egroup.

1165 \xydef@\xycheck@end{\xyFN@\xycheck@end@}
1166 \xydef@\xycheck@end@{\ifx\next\xy@end\DN@\xy@end{}\else\DN@{\xy@end}\fi\next@}
1167 \xydef@\xy@end{%
1168 \xyerror@{An \string\xy\space environment is not closed correctly.}%
1169 {I expected \string\endxy.  You probably have an umatched {} grouping.}}

It is possible to insert an ‘initial’ piece of ⟨pos⟩ ⟨decor⟩ at the start of every XY-picture with the declaration

                                  \everyxy={ ⟨text⟩ }

This will act as if the ⟨text⟩ was typed literally right after each \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⟩.

1.3 Positions

1195 \message{positions,}

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.

All possible positions are shown in figure 1.1 with explanatory notes below.

Syntax  Action
⟨pos⟩  ⟶ ⟨coord⟩  c ← ⟨coord⟩
| ⟨pos⟩ + ⟨coord⟩  c ← ⟨pos⟩ + ⟨coord⟩1.3a
| ⟨pos⟩ - ⟨coord⟩  c ← ⟨pos⟩ − ⟨coord⟩1.3a
| ⟨pos⟩ ! ⟨coord⟩  c ← ⟨pos⟩ then skew1.3b c by ⟨coord⟩
| ⟨pos⟩ . ⟨coord⟩  c ← ⟨pos⟩ but also covering1.3c ⟨coord⟩
| ⟨pos⟩ , ⟨coord⟩  c ← ⟨pos⟩ then c ← ⟨coord⟩
| ⟨pos⟩ ; ⟨coord⟩  c ← ⟨pos⟩, swap p and c, c ← ⟨coord⟩
| ⟨pos⟩ : ⟨coord⟩  c ← ⟨pos⟩, set base1.3d, c ← ⟨coord⟩
| ⟨pos⟩ :: ⟨coord⟩  c ← ⟨pos⟩, ybase ← c − origin, c ← ⟨coord⟩
| ⟨pos⟩ * ⟨object⟩  c ← ⟨pos⟩, drop1.3f ⟨object⟩
| ⟨pos⟩ ** ⟨object⟩  c ← ⟨pos⟩, connect1.3g using ⟨object⟩
| ⟨pos⟩ ? ⟨place⟩  c ← ⟨pos⟩, c ← ⟨place⟩1.3h
| ⟨pos⟩ @ ⟨stacking⟩  c ← ⟨pos⟩, do ⟨stacking⟩1.3o
| ⟨pos⟩ = ⟨saving⟩  c ← ⟨pos⟩, do ⟨saving⟩1.3p
⟨coord⟩ ⟶ ⟨vector⟩  ⟨pos⟩ is ⟨vector⟩ with zero size
| ⟨empty⟩ | c  reuse last c (do nothing)
| p  p
| x | y  axis intersection1.3k with \overline{pc}
| s⟨digit⟩ | s{⟨number⟩} stack1.3o position ⟨digit⟩ or ⟨number⟩ below the top
| "⟨id⟩"  restore what was saved1.3p as ⟨id⟩ earlier
| { ⟨pos⟩ ⟨decor⟩ }  the c resulting from interpreting the group1.3l
⟨vector⟩ ⟶ 0  zero
| < ⟨dimen⟩ , ⟨dimen⟩ >  absolute
| < ⟨dimen⟩ >  absolute with equal dimensions
| ( ⟨factor⟩ , ⟨factor⟩ )  in current base1.3d
| a ( ⟨number⟩ )  angle in current base1.3e
| ⟨corner⟩  from reference point to ⟨corner⟩ of c
| ⟨corner⟩ ( ⟨factor⟩ )  The ⟨corner⟩ multiplied with ⟨factor⟩
| / ⟨direction⟩ ⟨dimen⟩ /  vector ⟨dimen⟩ in ⟨direction⟩1.3m
⟨corner⟩ ⟶ L | R | D | U  offset1.3n to left, right, down, up side
| CL | CR | CD | CU | C  offset1.3n to center of side, true center
| LD | RD | LU | RU  offset1.3n to actual left/down, … corner
| E | P  offset1.3n to nearest/proportional edge point to p
⟨place⟩ ⟶ < ⟨place⟩ | > ⟨place⟩  shave1.3h (0)/(1) to edge of p/c, f ← 0/1
| ( ⟨factor⟩ ) ⟨place⟩  f ← ⟨factor⟩
| ⟨slide⟩  pick place1.3h and apply ⟨slide⟩

| ! {⟨pos⟩} ⟨slide⟩ intercept1.3j with line setup by ⟨pos⟩ and apply

⟨slide⟩

⟨slide⟩ ⟶ / ⟨dimen⟩ /  slide1.3i ⟨dimen⟩ further along connection
| ⟨empty⟩  no slide

Figure 1.1: ⟨pos⟩itions.

Exercise 1.1: Which of the positions 0, <0pt,0pt>, <0pt>, (0,0), and /0pt/ is different from the others?

Parsing: First the \POS and \afterPOS ⟨decor⟩ations, and similar \afterCOORD and \afterVECTORorEMPTY ones. They handle parsing of ⟨pos⟩, ⟨coord⟩, and ⟨vector⟩; parsing of ⟨corner⟩ and ⟨place⟩ is presented along with note 1.3n and 1.3h explaining them.

1368 \xydef@\POS{\afterPOS{}}
1370 \xydef@\afterPOS#1{%
1371 \DN@##1{\def\afterPOS@{\def\afterPOS@{##1}#1}}%
1372 \expandafter\next@\expandafter{\afterPOS@}%
1373 \afterCOORD{\xyFN@\POS@}}
1375 \xylet@\afterPOS@=\empty
1377 \xydef@\afterCOORD#1{%
1378 \DN@##1{\def\afterCOORD@{\def\afterCOORD@{##1}#1}}%
1379 \expandafter\next@\expandafter{\afterCOORD@}%
1380 \afterVECTORorEMPTY{\xy@@\czeroEdge@ \afterCOORD@}{\xyFN@\COORD@}}
1382 \xylet@\afterCOORD@=\empty
1384 \xydef@\afterVECTORorEMPTY#1#2{%
1385 \DN@##1{\def\afterVECTOR@{\def\afterVECTOR@{##1}%
1386 \ifVECTORempty@\DN@{#2}\else\DN@{#1}\fi \next@}}%
1387 \expandafter\next@\expandafter{\afterVECTOR@}%
1388 \xyFN@\VECTOR@}
1390 \xynew@{if}\ifVECTORempty@
1391 \xylet@\afterVECTOR@=\empty

The \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, e.g., 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:

1415 \xydef@\xyVECTOR@{%
1416 \ifx \space@\next \expandafter\DN@\space{\xyFN@\VECTOR@}%gobble spaces
1417 \else \ifcat A\noexpand\next \let\next@=\VECTOR@letter
1418 \else \let\next@=\VECTOR@other \fi\fi \next@}
1420 \xylet@\VECTOR@=\xyVECTOR@

All letters used for ⟨vector⟩s are uppercase ⟨corner⟩s except for a used for angles (where the main code is in note 1.3e); 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:

1430 \def\notrelaxorelse@#1#2{\ifx#1\relax \expandafter#2\else\expandafter#1\fi}
1432 \xydef@\VECTOR@letter{%

1433 \ifx a\next \expandafter\VECTOR@a \else \expandafter\CORNER@ \fi}
1435 \xydef@\VECTOR@a a(#1){\xy@{a(#1)}{\vfromcartesianangle@{#1}}%
1436 \VECTORempty@false \afterVECTOR@}

The ⟨corner⟩ trick is to do nothing when there is nothing and initialise both X and Y in all other cases.

1443 \xydef@\CORNER@{%
1444 \xy@{}{\A@=-.5\L@c \advance\A@.5\R@c \B@=-.5\D@c \advance\B@.5\U@c
1445 \let\nextii@=\zeroit@}%
1446 \VECTORempty@true\CORNER@i}
1448 \xydef@\zeroit@#1{#1=\z@}
1450 \xydef@\CORNER@i{%
1451 \ifx D\next      \DN@ D{\xy@{D}{\Y@c=-\D@c \nextii@\X@c \B@=\Y@c}\CORNER@ii}%
1452 \else\ifx U\next \DN@ U{\xy@{U}{\Y@c= \U@c \nextii@\X@c \B@=\Y@c}\CORNER@ii}%
1453 \else\ifx L\next \DN@ L{\xy@{L}{\X@c=-\L@c \nextii@\Y@c \A@=\X@c}\CORNER@ii}%
1454 \else\ifx R\next \DN@ R{\xy@{R}{\X@c= \R@c \nextii@\Y@c \A@=\X@c}\CORNER@ii}%
1455 \else\ifx C\next \DN@ C{\xy@{C}{\X@c= \A@ \Y@c= \B@}\CORNER@ii}%
1456 \else\ifx E\next \DN@ E{\xy@{E}{%
1457  \A@=\X@c \B@=\Y@c \the\Edge@c\z@ \advance\X@c-\A@ \advance\Y@c-\B@}%
1458 \CORNER@ii}%
1459 \else\ifx P\next \DN@ P{\xy@{P}{%
1460  \A@=\X@c \B@=\Y@c \the\Edge@c\thr@@ \advance\X@c-\A@ \advance\Y@c-\B@}%
1461 \CORNER@ii}%
1462 \else\ifx (\next %)
1463 \DN@(##1){\xy@{(##1)}{\X@c=##1\X@c \Y@c=##1\Y@c}\afterVECTOR@}%
1464 \else \let\next@=\afterVECTOR@
1465 \fi\fi\fi\fi\fi\fi\fi\fi \next@}
1467 \xydef@\CORNER@ii{\xy@@{\let\nextii@=\eat@}%
1468 \VECTORempty@false \xyFN@\CORNER@i}

\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.

1477 \xydef@\VECTOR@other{%
1478 \addLT@\ifx \next
1479 \addGT@{\addLT@\DN@##1}{\xy@{<##1>}{\vfromabsolute@{##1}}%
1480 \VECTORempty@false\afterVECTOR@}%
1481 \else\ifx (\next %)
1482 \DN@({\xyFN@\VECTOR@other@open}%)
1483 \else\ifx /\next %/
1484 \DN@/##1/{\xy@@ix@{{##1}}%
1485 \xy@{/##1/}{\expandafter\vfromslide@\the\toks9 }%
1486 \VECTORempty@false\afterVECTOR@}%
1487 \else\ifx 0\next
1488 \DN@ 0{\xy@{0}{\X@c=\z@ \Y@c=\z@}\VECTORempty@false\afterVECTOR@}%
1489 \else
1490 \DN@{\VECTORempty@true\afterVECTOR@}%
1491 \fi\fi\fi\fi \next@}

26 CHAPTER 1. KERNEL: XY.DOC

Hack: escape out in case of the special (* introducer… picked up by the ⟨coord⟩ parser, then.

1498 \xydef@\VECTOR@other@open{%
1499 \ifx *\next \DN@{\VECTORempty@true \xyFN@\afterVECTOR@(}%)
1500 \else
1501 \DN@##1){\xy@{(##1)}{\vfromcartesian@{##1}}\VECTORempty@false\afterVECTOR@}%
1502 \fi \next@}

Next ⟨coord⟩inates that are not ⟨vector⟩s:

1508 \xydef@\xyCOORD@{%
1509 \ifx \space@\next \expandafter\DN@\space{\xyFN@\COORD@}%gobble spaces
1510 \else \ifcat A\noexpand\next \let\next@=\xyCOORD@letter
1511 \else \let\next@=\xyCOORD@other \fi\fi \next@}
1513 \xylet@\COORD@=\xyCOORD@
1515 \xydef@\xyCOORD@letter{%
1516 \ifx c\next
1517 \DN@ c{\xy@{c}{}\afterCOORD@}%
1518 \else\ifx p\next
1519 \DN@ p{\xy@{p}\cfromp@ \afterCOORD@}%
1520 \else\ifx x\next
1521 \DN@ x{\xy@{x}{\R@c=\X@xbase \U@c=\Y@xbase \intersect@}\afterCOORD@}%
1522 \else\ifx y\next
1523 \DN@ y{\xy@{y}{\R@c=\X@ybase \U@c=\Y@ybase \intersect@}\afterCOORD@}%
1524 \else\ifx s\next
1525 \DN@ s##1{\xy@{s{##1}}{\cfroms@{##1}}\afterCOORD@}%
1526 \else \let\next@=\afterCOORD@ \fi\fi\fi\fi\fi \next@}
1528 \xydef@\xyCOORD@other{%
1529 \ifx "\next %"
1530 \DN@"##1"{\xy@{"##1"}{\cfromid@{##1}}\afterCOORD@}%
1531 \else\ifx \bgroup\next
1532 \DN@##1{\xy@{{##1}}{\enter@{\pfromthep@\basefromthebase@}}%
1533 \silencexy@ \POS##1\relax \unsilencexy@ \xy@@\leave@ \afterCOORD@}%
1534 \else\ifx (\next %)
1535 \DN@({\xyFN@\xyCOORD@other@open}%)
1536 \else \let\next@=\afterCOORD@ \fi\fi\fi \next@}
1538 \xynew@{if}\ifsilentxy@
1540 \xydef@\silencexy@{%
1541 \ifsilentxy@ \nter@{}%
1542 \else \nter@{\silentxy@false \let\xy@=\unsilent@@xy@}
1543 \silentxy@true \let\unsilent@@xy@=\xy@ \def\xy@##1##2{\unsilent@@xy@{}{##2}}%
1544 \fi}
1546 \xydef@\unsilencexy@{\leave@}
1548 \xydef@\xyCOORD@other@open{%
1549 \ifx *\next
1550 \DN@*##1*){\xy@{(*}{\enter@{\pfromthep@\basefromthebase@}}%
1551 \POS##1\relax \xy@{*)}\leave@ \afterCOORD@}%
1552 \else \DN@{\xyFN@\afterCOORD@(}%)
1553 \fi \next@}

Finally ⟨pos⟩ parsing after ⟨coord⟩ (possibly ⟨vector⟩) is interpreted:

1560 \xydef@\xyPOS@{%
1561 \ifx \space@\next \expandafter\DN@\space{\xyFN@\POS@}%gobble spaces
1562 \else\addPLUS@\ifx \next
1563 \addPLUS@\DN@{\xy@+{\enter@\cplusthec@}%
1564  \afterCOORD{\xy@@\leave@ \xyFN@\POS@}}%
1565 \else\addDASH@\ifx \next
1566 \addDASH@\DN@{\xy@-{\enter@\cplusthec@}%
1567  \afterCOORD{\xy@@{\X@c=-\X@c \Y@c=-\Y@c\leave@}\xyFN@\POS@}}%
1568 \else\ifx !\next
1569 \DN@ !{\xy@!{\enter@\cskewthec@}\afterCOORD{\xy@@\leave@ \xyFN@\POS@}}%
1570 \else\addDOT@\ifx \next
1571 \addDOT@\DN@{\xy@.{\enter@\cmergethec@}%
1572 \afterCOORD{\xy@@\leave@ \xyFN@\POS@}}%
1573 \else\ifx ,\next
1574 \DN@ ,{\xy@,{\comma@@}\afterCOORD{\xyFN@\POS@}}%
1575 \else\ifx ;\next
1576 \DN@ ;{\xy@;{\swap@}\afterCOORD{\xyFN@\POS@}}%
1577 \else\ifx :\next
1578 \DN@ :{\xyFN@\POS@colon}%
1579 \else\addEQ@\ifx \next
1580 \addEQ@\DN@{\xyFN@\saveid@}%
1581 \else\ifx *\next
1582 \DN@ *{\xyFN@\POS@star}%
1583 \else \ifx ?\next
1584 \DN@?{\xy@?{}\afterPLACE{\xyFN@\POS@}}%
1585 \else \addAT@\ifx \next
1586 \addAT@\DN@{\xyFN@\STACK@}%
1587 \else
1588 \let\next@=\afterPOS@
1589 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
1591 \xylet@\comma@@=\relax
1593 \xylet@\POS@=\xyPOS@

\comma@@ is a hook used to change the operation of ,, e.g., when reading a stack setup where it means ‘push’.

The final functions serve only to distinguish between the single character :/* and dual character ::/** operators:

1603 \xydef@\POS@colon{\DNii@{\afterCOORD{\xyFN@\POS@}}%
1604 \ifx :\next \xy@{::}{\setbase@@\X@c\Y@c}\DN@:{\nextii@}%
1605 \else \xy@:{\setbase@\X@p\Y@p\X@c\Y@c}\let\next@=\nextii@ \fi
1606 \next@}
1608 \xydef@\POS@star{%
1609 \ifx *\next
1610 \DN@*##1##{\nextii@{##1}}%
1611 \DNii@##1##2{\xy@@ix@{{##1}{##2}}%
1612 \xy@{**##1{##2}}{\expandafter\connect@\the\toks9 }\xyFN@\POS@}%
1613 \else

1614 \DN@##1##{\nextii@{##1}}%
1615 \DNii@##1##2{\xy@@ix@{{##1}{##2}}%
1616 \xy@{*##1{##2}}{\expandafter\drop@\the\toks9 }\xyFN@\POS@}%

1617 \fi

1618 \next@}

Simple actions: Next follow the simplest actions; the complicated ones are explained along with their notes below.

1629 \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
1630 \Edge@c=\expandafter{\the\Edge@p}}
1632 \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
1633 \Edge@p=\expandafter{\the\Edge@c}}
1635 \xydef@\swapdimen@#1#2{\dimen@=#1\relax #1=#2\relax #2=\dimen@}
1637 \xynew@{toks}\swaptoks@@
1639 \xydef@\swap@{\swapdimen@\X@c\X@p \swapdimen@\Y@c\Y@p
1640 \swapdimen@\U@c\U@p\swapdimen@\D@c\D@p \swapdimen@\L@c\L@p\swapdimen@\R@c\R@p
1641 \swaptoks@@=\Edge@c \Edge@c=\Edge@p \Edge@p=\swaptoks@@}

Next the parsing of coordinate pairs in <>:

1647 \xydef@\vfromabsolute@#1{\vfromabsolute@@#1,@}
1649 \xydef@\vfromabsolute@@#1,#2@{\X@c=#1\relax
1650 \DN@{#2}\ifx\next@\empty \Y@c=\X@c
1651 \else \DN@##1,{\Y@c=##1}\next@#2\relax \fi
1652 % \advance\X@c 1sp \advance\Y@c 1sp %HACK

1653 }

The next group of commands are used to store on the control stack with the \enter@ command, so they expand to something useful:

1660 \xydef@\cfromthec@{\X@c=\the\X@c \Y@c=\the\Y@c
1661 \U@c=\the\U@c \D@c=\the\D@c \L@c=\the\L@c \R@c=\the\R@c
1662 \Edge@c={\expandafter\noexpand\the\Edge@c}}
1664 \xydef@\cfromthep@{\X@c=\the\X@p \Y@c=\the\Y@p
1665 \U@c=\the\U@p \D@c=\the\D@p \L@c=\the\L@p \R@c=\the\R@p
1666 \Edge@c={\expandafter\noexpand\the\Edge@p}}
1668 \xydef@\pfromthep@{\X@p=\the\X@p \Y@p=\the\Y@p
1669 \U@p=\the\U@p \D@p=\the\D@p \L@p=\the\L@p \R@p=\the\R@p
1670 \Edge@p={\expandafter\noexpand\the\Edge@p}}
1672 \xydef@\pfromthec@{\X@p=\the\X@c \Y@p=\the\Y@c
1673 \U@p=\the\U@c \D@p=\the\D@c \L@p=\the\L@c \R@p=\the\R@c
1674 \Edge@p={\expandafter\noexpand\the\Edge@c}}

Notes

1.3a. When doing arithmetic with + and - then the resulting current object inherits the size of the ⟨coord⟩, i.e., the right argument—this will be zero if the ⟨coord⟩ is a ⟨vector⟩.

Exercise 1.2: How do you set c to an object the same size as the saved object "ob" but moved

   <X,Y >?

1694 \xydef@\cplusthec@{\advance\X@c\the\X@c \advance\Y@c\the\Y@c}

1.3b. Skewing using ! just means that the reference point of c is moved with as little change to the shape of the object as possible, i.e., the edge of c will remain in the same location except that it will grow larger to avoid moving the reference point outside c.

Exercise 1.3: What does the ⟨pos⟩ … !R-L do? Bug: The result of ! is always a rectangle currently.

Procedure: ! moves the center of c by a temporarily read c′ and then readjusts the extents:

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}

1737 \xydef@\cskewthec@{%
1738 \noexpand\cskew@{\the\Y@c}{\the\X@c}{\the\D@c}{\the\U@c}{\the\L@c}{\the\R@c}}
1740 \xydef@\cskew@#1#2#3#4#5#6{%
1741 \D@c=#3\advance\D@c \Y@c \ifdim\D@c<\z@ \D@c=\z@ \fi
1742 \U@c=#4\advance\U@c-\Y@c \ifdim\U@c<\z@ \U@c=\z@ \fi
1743 \advance\Y@c#1%
1744 \L@c=#5\advance\L@c \X@c \ifdim\L@c<\z@ \L@c=\z@ \fi
1745 \R@c=#6\advance\R@c-\X@c \ifdim\R@c<\z@ \R@c=\z@ \fi
1746 \advance\X@c#2%
1747 \Edge@c={\rectangleEdge}}

1.3c. 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.

Procedure: . takes a temporary object c′ and adjusts the extents of c such that it is covered.

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)

with <A,B> = <X′−X,Y′−Y >. First method 2 of the object is used to convert it into a rectangle.

1782 \xydef@\cmergethec@{%
1783 \noexpand\cmerge@{\the\Y@c}{\the\X@c}{\the\D@c}{\the\U@c}{\the\L@c}{\the\R@c}}

1785 \xydef@\cmerge@#1#2#3#4#5#6{\the\Edge@c4%
1786 \A@=#2\advance\A@-\X@c \B@=#1\advance\B@-\Y@c
1787 \dimen@=#5\advance\L@c \A@ \ifdim\L@c<\dimen@ \L@c=\dimen@ \fi
1788 \dimen@=#6\advance\R@c-\A@ \ifdim\R@c<\dimen@ \R@c=\dimen@ \fi
1789 \dimen@=#3\advance\D@c \B@ \ifdim\D@c<\dimen@ \D@c=\dimen@ \fi
1790 \dimen@=#4\advance\U@c-\B@ \ifdim\U@c<\dimen@ \U@c=\dimen@ \fi
1791 \advance\X@c\A@ \advance\Y@c\B@}

1.3d. 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

[figure: ∘; origin; xbase; ybase; ×; (1,1)]

   while <1cm,.5cm>;<2cm,1.5cm>:<1cm,1cm>::  defines

[figure: ∘; ybase before ::; origin; xbase; ybase; ×; (1,1)]

where in each case the ∘ is at 0, the base vectors have been drawn and the × is at (1,1).

When working with cartesian coordinates these three special ⟨factor⟩s are particularly useful:

\halfroottwo 0.70710678 ≈ \frac{1}{2} \sqrt{2}
\partroottwo 0.29289322 ≈ 1 − \frac{1}{2} \sqrt{2}

               \halfrootthree 0.86602540 ≈ \frac{1}{2} \sqrt{3}

More can be defined using \def (or \newcommand in L^{A}TEX).

1849 \xydef@\halfroottwo{.70710678}
1850 \xydef@\partroottwo{.29289322}
1851 \xydef@\halfrootthree{.8660254}

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.

1863 \xydef@\vfromcartesian@#1{\vfromcartesian@@#1@}
1865 \xydef@\vfromcartesian@@#1,#2@{%
1866 \X@c=\X@origin \advance\X@c#1\X@xbase \advance\X@c#2\X@ybase
1867 \Y@c=\Y@origin \advance\Y@c#1\Y@xbase \advance\Y@c#2\Y@ybase}
1869 \xydef@\setbase@#1#2#3#4{%
1870 \X@origin=#1\relax \Y@origin=#2\relax
1871 \X@xbase=#3\relax \advance\X@xbase-\X@origin

1872 \Y@xbase=#4\relax \advance\Y@xbase-\Y@origin
1873 \X@ybase=-\Y@xbase \Y@ybase=\X@xbase}
1875 \xydef@\setbase@@#1#2{%
1876 \X@ybase=#1\relax \advance\X@ybase-\X@origin
1877 \Y@ybase=#2\relax \advance\Y@ybase-\Y@origin}
1879 \xydef@\basefromthebase@{\X@origin=\the\X@origin \Y@origin=\the\Y@origin
1880 \X@xbase=\the\X@xbase \Y@xbase=\the\Y@xbase
1881 \X@ybase=\the\X@ybase \Y@ybase=\the\Y@ybase}

1.3e. An angle α in XY-pic is the same as the coordinate pair ( cos α, sin α) where α 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.

The translation involves several steps: (l.1956) Normalise the argument to be within [0^{∘} : 360^{∘}[. (l.1959) Flip angle around x-axis and then y-axis to ensure it is in the first quadrant, i.e., within [0^{∘} : 90^{∘}[. (l.1964) Flip around diagonal to ensure angle within [0^{∘} : 45^{∘}[. (l.1967) Find values ϕ ≤ α < ψ from the table in figure 1.2 (using recursive table lookup – at most 3 tests needed). (l.2024) build vector (x, y) interpolated between the sin/cos values for ϕ and ψ using the formula

(cos ϕ + k(cos ψ − cos ϕ), sin ϕ + k(sin ψ − sin ϕ)) , where k = \frac{α − ϕ}{ψ − ϕ}

(l.2035) build the chosen vector.

1955 \xydef@\vfromcartesianangle@#1{\enter@\basefromthebase@ \R@=#1\p@
1956 \B@=360\p@
1957 \loop@ \ifdim\R@<\z@ \advance\R@\B@ \repeat@
1958 \loop@ \ifdim\R@>\B@ \advance\R@-\B@ \repeat@
1959 \ifdim\R@<.5\B@\else \R@=-\R@ \advance\R@\B@
1960 \X@ybase=-\X@ybase \Y@ybase=-\Y@ybase \fi
1961 \B@=180\p@
1962 \ifdim\R@<.5\B@\else \R@=-\R@ \advance\R@\B@
1963 \X@xbase=-\X@xbase \Y@xbase=-\Y@xbase \fi
1964 \B@=90\p@
1965 \ifdim\R@<.5\B@ \let\nextiii@=\literal@
1966 \else \R@=-\R@ \advance\R@\B@ \def\nextiii@##1,##2@{##2,##1@}\fi
1967 \dimen@=\z@ \DN@{1,0@}%
1968 \dimen@ii=45\p@ \DNii@{.70710678,.70710678@}%
1969 \chooseangleinterval@
1970 {\chooseangleinterval@
1971 {\chooseangleinterval@
1972 {\chooseangleinterval@
1973  {\chooseangleinterval@

1974  {}%

1975  {4.090909}{.99677570,.08023846@}%
1976  {}}%
1977  {6}{.99452190,.10452846@}%
1978  {\chooseangleinterval@

1979  {}%

1980  {8.181818}{.98982144,.14231484@}%
1981  {}}}%

32 CHAPTER 1. KERNEL: XY.DOC

Vectors for angles in [0^{∘} : 45^{∘}]: contains all angles required to typeset fractions up to \frac{n}{12} × 2π, \frac{1}{16} × 2π, and \frac{1}{24} × 2π exactly, and two extra low ones to ensure that all gaps are less than 5^{∘} and the precision of all sine/cosines better than \frac{1}{1000}.

α  (cos α, sin α)  fractions of 2π  flipped fractions of 2π
0  (1, 0)  \frac{0}{n}  \frac{1}{2}, \frac{1}{4}, \frac{2}{4}, \frac{2}{8}, \frac{3}{4}, \frac{3}{6}, \frac{3}{12}, \frac{4}{8}, \frac{5}{10}, \frac{6}{8}, \frac{6}{12}, \frac{9}{12}
4.090909 (.99677570, .08023846)  −  −
6  (.99452190, .10452846)  −  −
8.181818 (.98982144, .14231484)  \frac{3}{11}  \frac{8}{11}
10  (.98480775, .17364818)  \frac{7}{9}  \frac{2}{9}
12.857143 (.97492791, .22252093)  \frac{2}{7}  \frac{5}{7}
15  (.96592583, .25881905)  \frac{1}{24}
16.363636 (.95949297, .28173256)  \frac{6}{11}  \frac{5}{11}
18  (.95105652, .30901699)  \frac{3}{10}, \frac{4}{5}, \frac{8}{10}  \frac{1}{5}, \frac{2}{10}, \frac{7}{10}
20  (.93969262, .34202014)  \frac{5}{9}  \frac{4}{9}
22.5  (.92387953, .38268343)  \frac{1}{16}
24.545455 (.90963200, .41541501)  \frac{9}{11}  \frac{2}{11}
25.714286 (.90096887, .43388374)  \frac{4}{7}  \frac{3}{7}
30  (.86602540, .5)  \frac{1}{3}, \frac{1}{12}, \frac{2}{6}, \frac{3}{9}, \frac{4}{12}, \frac{5}{6}, \frac{7}{12}, \frac{10}{12}  \frac{1}{6}, \frac{2}{3}, \frac{2}{12}, \frac{4}{6}, \frac{5}{12}, \frac{6}{9}, \frac{8}{12}, \frac{11}{12}
32.727273 (.84125353, .54064082)  \frac{1}{11}  \frac{10}{11}
36  (.80901699, .58778525)  \frac{1}{10}, \frac{3}{5}, \frac{6}{10}  \frac{2}{5}, \frac{4}{10}, \frac{9}{10}
38.571429 (.78183148, .62348980)  \frac{6}{7}  \frac{1}{7}
40  (.76604444, .64278761)  \frac{1}{9}  \frac{8}{9}
40.909091 (.75574957, .65486073)  \frac{4}{11}  \frac{7}{11}
45  (.70710678, .70710678)  \frac{1}{8}, \frac{3}{8}, \frac{5}{8}, \frac{7}{8}  −

Figure 1.2: Computing angle vectors

1982 {10}{.98480775,.17364818@}%
1983 {\chooseangleinterval@

1984  {}%

1985  {12.857143}{.97492791,.22252093@}%
1986  {}}}%
1987 {15}{.96592583,.25881905@}%
1988 {\chooseangleinterval@
1989 {\chooseangleinterval@

1990  {}%

1991  {16.363636}{.95949297,.28173256@}%
1992  {}}%
1993 {18}{.95105652,.30901699@}%
1994 {\chooseangleinterval@

1995  {}%

1996  {20}{.93969262,.34202014@}%
1997  {}}}}%
1998 {22.5}{.92387953,.38268343@}%
1999 {\chooseangleinterval@
2000 {\chooseangleinterval@
2001 {\chooseangleinterval@

2002  {}%

2003  {24.545455}{.90963200,.41541501@}%
2004  {}}%
2005 {25.714286}{.90096887,.43388374@}%
2006 {}}%
2007 {30}{.86602540,.5@}%
2008 {\chooseangleinterval@
2009 {\chooseangleinterval@

2010  {}%

2011  {32.727273}{.84125353,.54064082@}%
2012  {}}%
2013 {36}{.80901699,.58778525@}%
2014 {\chooseangleinterval@
2015  {\chooseangleinterval@

2016  {}%

2017  {38.571429}{.78183148,.62348980@}%
2018  {}}%
2019  {40.909091}{.75574957,.65486073@}%
2020  {\chooseangleinterval@

2021  {}%

2022  {40}{.76604444,.64278761@}%
2023  {}}}}}%
2024 \A@=\R@ \advance\A@-\dimen@
2025 \ifdim\ifdim\A@<\z@-\fi\A@<.01\p@ \edef\next@{\expandafter\nextiii@\next@}%
2026 \else \B@=\dimen@ii \advance\B@-\R@
2027 \ifdim\A@<\B@ \dimen@=\toradians@\A@
2028 \edef\next@{\next@ \expandafter\removePT@\the\dimen@ @}%
2029 \else \dimen@=-\toradians@\B@
2030 \edef\next@{\nextii@ \expandafter\removePT@\the\dimen@ @}%

2031 \fi

2032 \expandafter\interpolatepoint@\next@
2033 \edef\next@{\expandafter\nextiii@\next@}%

2034 \fi

2035 \expandafter\vfromcartesian@@\next@
2036 \leave@}
2038 \xydef@\chooseangleinterval@#1#2#3#4{%
2039 \B@=#2\p@ \def\next{#3}%
2040 \ifdim\R@<\B@ \dimen@ii=\B@ \let\nextii@=\next #1%
2041 \else \dimen@=\B@ \let\next@=\next \ifdim\B@<\R@ #4\fi\fi}
2043 \xydef@\interpolateinterval@#1,#2@#3,#4@{%
2044 \A@=#1\p@ \dimen@=#3\p@ \advance\dimen@-\A@ \advance\A@\next\dimen@
2045 \B@=#2\p@ \dimen@=#4\p@ \advance\dimen@-\B@ \advance\B@\next\dimen@
2046 \edef\next@{\expandafter\removePT@\the\A@,\expandafter\removePT@\the\B@ @}}
2048 \xydef@\toradians@{0.01745329}
2050 \xydef@\interpolatepoint@#1,#2@#3@{%
2051 \A@=#1\p@ \dimen@ii=#3\A@ \dimen@ii=-.5\dimen@ii \advance\A@#3\dimen@ii
2052 \dimen@=-#2\p@ \advance\A@#3\dimen@
2053 \B@=#2\p@ \dimen@ii=#3\B@ \dimen@ii=-.5\dimen@ii \advance\B@#3\dimen@ii
2054 \dimen@=#1\p@ \advance\B@#3\dimen@
2055 \edef\next@{\expandafter\removePT@\the\A@,\expandafter\removePT@\the\B@ @}}

Figure 1.3 shows all directions.

1.3f. 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 §1.4. The intuition with a drop is that it typesets something at <X_{c},Y_{c}> and sets the edge of c accordingly.

Procedure: (??) sets up the direction to allow for directionals and builds the requested ⟨object⟩ in the (global) \lastobjectbox@ box, (l.2106) adjust the picture size unless it is a hidden object, setting \dimen@ = X_{c} − L_{c}, and (l.2112) drop the object in the picture at the right point by setting box0 and using the \Drop@@ method.

2104 \xydef@\drop@#1#2{%*[drop1]
2105 \global\setbox\lastobjectbox@=\object#1{#2}%
2106 \ifHidden@ \dimen@=\X@c \advance\dimen@-\L@c \else
2107 \dimen@=\Y@c \advance\dimen@ \U@c \ifdim\Y@max<\dimen@ \Y@max=\dimen@ \fi
2108 \dimen@=\Y@c \advance\dimen@-\D@c \ifdim\dimen@<\Y@min \Y@min=\dimen@ \fi
2109 \dimen@=\X@c \advance\dimen@ \R@c \ifdim\X@max<\dimen@ \X@max=\dimen@ \fi
2110 \dimen@=\X@c \advance\dimen@-\L@c \ifdim\dimen@<\X@min \X@min=\dimen@ \fi

2111 \fi

2112 \ifInvisible@\else
2113 \setboxz@h{\kern\dimen@ \raise\Y@c\box\lastobjectbox@}%
2114 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ {\Drop@@}\fi}

Note: All typesetting into a picture should use or emulate \drop@!

1.3g. 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

[figure: ¨⌣; 0; ·; ·; ·; ·; 5; ·; ·; ·; ·; 10; ·; ·; ·; ·; 15; ·; ·; ·; ·; 20; ·; ·; ·; ·; 25; ·; ·; ·; ·; 30; ·; ·; ·; ·; 35; ·; ·; ·; ·; 40; ·; ·; ·; ·; 45; ·; ·; ·; ·; 50; ·; ·; ·; ·; 55; ·; ·; ·; ·; 60; ·; ·; ·; ·; 65; ·; ·; ·; ·; 70; ·; ·; ·; ·; 75; ·; ·; ·; ·; 80; ·; ·; ·; ·; 85; ·; ·; ·; ·; 90; ·; ·; ·; ·; 95; ·; ·; ·; ·; 100; ·; ·; ·; ·; 105; ·; ·; ·; ·; 110; ·; ·; ·; ·; 115; ·; ·; ·; ·; 120; ·; ·; ·; ·; 125; ·; ·; ·; ·; 130; ·; ·; ·; ·; 135; ·; ·; ·; ·; 140; ·; ·; ·; ·; 145; ·; ·; ·; ·; 150; ·; ·; ·; ·; 155; ·; ·; ·; ·; 160; ·; ·; ·; ·; 165; ·; ·; ·; ·; 170; ·; ·; ·; ·; 175; ·; ·; ·; ·; 180; ·; ·; ·; ·; 185; ·; ·; ·; ·; 190; ·; ·; ·; ·; 195; ·; ·; ·; ·; 200; ·; ·; ·; ·; 205; ·; ·; ·; ·; 210; ·; ·; ·; ·; 215; ·; ·; ·; ·; 220; ·; ·; ·; ·; 225; ·; ·; ·; ·; 230; ·; ·; ·; ·; 235; ·; ·; ·; ·; 240; ·; ·; ·; ·; 245; ·; ·; ·; ·; 250; ·; ·; ·; ·; 255; ·; ·; ·; ·; 260; ·; ·; ·; ·; 265; ·; ·; ·; ·; 270; ·; ·; ·; ·; 275; ·; ·; ·; ·; 280; ·; ·; ·; ·; 285; ·; ·; ·; ·; 290; ·; ·; ·; ·; 295; ·; ·; ·; ·; 300; ·; ·; ·; ·; 305; ·; ·; ·; ·; 310; ·; ·; ·; ·; 315; ·; ·; ·; ·; 320; ·; ·; ·; ·; 325; ·; ·; ·; ·; 330; ·; ·; ·; ·; 335; ·; ·; ·; ·; 340; ·; ·; ·; ·; 345; ·; ·; ·; ·; 350; ·; ·; ·; ·; 355; ·; ·; ·; ·; ,360]

Figure 1.3: All directions.

in §1.2.3. The exact details of the connection depend on the actual ⟨object⟩ and are described in general in §1.4. The intuition with a connection is that it typesets something connecting p and c and sets the ? ⟨pos⟩ operator up accordingly.

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@.

2140 \xydef@\connect@#1#2{\setupDirection@ \enter@{\cfromthec@}%
2141 \global\setbox\lastobjectbox@=\object#1{#2}\leave@
2142 \Connect@@}
2144 \xydef@\preconnect@#1#2{\setupDirection@ \enter@{\cfromthec@}%
2145 \global\setbox\lastobjectbox@=\object#1{#2}\leave@ \connectStore@
2146 \ifInvisible@ \Connect@@ \else \Invisible@true\Connect@@\Invisible@false \fi}

The \preconnect command is for internal use by arrow … it makes use of the following:

2153 \xynew@{box}\connectobjectbox@@
2154 \xylet@\connectDrop@@=\empty
2155 \xylet@\connectpreXY@style@=\empty
2156 \xylet@\connectpostXY@style@=\empty
2158 \xylet@\connectRest@@=\empty
2160 \xydef@\connectStore@{%
2161 \global\setbox\connectobjectbox@@=\copy\lastobjectbox@

2162 \let\connectDrop@@=\Drop@@
2163 \let\connectpreXY@style@ =\preXY@style@
2164 \let\connectpostXY@style@=\postXY@style@
2165 \xdef\connectRest@@{%
2166 \def\noexpand\Upness@{\Upness@}%
2167 \def\noexpand\Leftness@{\Leftness@}%
2168 \ifInvisible@ \noexpand\Invisible@true \else \noexpand\Invisible@false \fi
2169 \ifHidden@ \noexpand\Hidden@true \else \noexpand\Hidden@false \fi}}
2171 \xydef@\connectRestore@{%
2172 \ifvbox\connectobjectbox@@
2173 \setbox\lastobjectbox@=\copy\voidb@x
2174 \else
2175 \global\setbox\lastobjectbox@=\copy\connectobjectbox@@

2176 \fi

2177 \let\Drop@@=\connectDrop@@
2178 \global\let\preXY@style@ =\connectpreXY@style@
2179 \global\let\postXY@style@=\connectpostXY@style@
2180 \connectRest@@}

See note ‘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@.

1.3h. 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 \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 ⊗ in figure 1.4 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.)

Procedure: The code for parsing ⟨place⟩ is the following. To get first <> to move to edge and the remaining to move a \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 }!

2274 \xydef@\afterPLACE#1{%
2275 \DN@##1{\def\afterPLACE@{\xy@@\leave@ \def\afterPLACE@{##1}#1}}%
2276 \expandafter\next@\expandafter{\afterPLACE@}%
2277 \def\PLACEf@{{.5}}%
2278 \xy@@{\enter@{\pfromthep@}%

           [figure: p is circular:; c is a ; square ; text!; ⊕; ?(0); ⊕; ?(1); ⊕; ?; ⊕; ?(.7); ⊕; ?<>(.5); ⊕; ?<>(.2)(.5); ⊕; ?<; ⊕; ?<<<; ⊕; ?<<</1cm/; ⊕; ?<(0); ⊕; ?>; ⊕; ?>>>>; ⊕; ?<>(.7); ⊕; ?>(.7)]

Figure 1.4: Example ⟨place⟩s

2279 \Creset@@ \def\PLACEf@{{.5}}%
2280 \let\PLACEedgep@@=\PLACEedgep@ \let\PLACEedgec@@=\PLACEedgec@}%
2281 \xyFN@\PLACE@}
2283 \xydef@\PLACEf@{}
2285 \xydef@\PLACEedgep@@{}
2286 \xydef@\PLACEedgec@@{}
2288 \xydef@\PLACEedgep@{\Cshavep@@ \def\PLACEedgep@@{\Cslidep@@\jot}}
2289 \xydef@\PLACEedgec@{\Cshavec@@ \def\PLACEedgec@@{\Cslidec@@{-\jot}}}
2291 \xylet@\afterPLACE@=\empty
2293 \xydef@\PLACE@{%
2294 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PLACE@}%gobble spaces
2295 \else\addLT@\ifx \next
2296 \addLT@\DN@{\addLT@\xy@{\def\PLACEf@{{0}}\PLACEedgep@@}\xyFN@\PLACE@}%
2297 \else\addGT@\ifx \next
2298 \addGT@\DN@{\addGT@\xy@{\def\PLACEf@{{1}}\PLACEedgec@@}\xyFN@\PLACE@}%
2299 \else\ifx (\next %)
2300 \DN@(##1){\def\PLACEf@{{##1}}\xy@{(##1)}{\def\PLACEf@{{##1}}}\xyFN@\PLACE@}%
2301 \else\ifx !\next
2302 \DN@!{\xyFN@\PLACE@intercept}%
2303 \else
2304 \DN@{\xy@@{\expandafter\Calong@@\PLACEf@ \czeroEdge@}\PLACE@@}%
2305 \fi\fi\fi\fi\fi \next@}
2307 \xydef@\PLACE@intercept{%
2308 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PLACE@intercept}%gobble spaces
2309 \else\ifx \bgroup\next
2310 \DN@##1{\xy@{!{##1}}{}\PLACE@intercept@{##1}}%
2311 \else\ifx (\next %)
2312 \DN@(*##1*){\xy@{!(*##1*)}{}\PLACE@intercept@{##1}}%
2313 \else \DN@{\xyerror@{{<pos>} expected after ! in <place>}{}}%
2314 \fi\fi\fi \next@}
2316 \xydef@\PLACE@intercept@#1{%

2317 \xy@@{\enter@{\pfromthep@\basefromthebase@}\begingroup}%
2318 \xy@@ix@{#1}\xy@@{\plainxy@ \expandafter\POS\the\toks9\relax
2319 \edef\next@{\endgroup
2320 \X@c =\the\X@c \Y@c=\the\Y@c \X@p=\the\X@p \Y@p=\the\Y@p}%
2321 \next@ \Cintercept@@ \leave@}%
2322 \PLACE@@}
2324 \xydef@\PLACE@@{%
2325 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PLACE@@}%gobble spaces
2326 \else\ifx /\next \DN@/##1/{\xy@{/##1/}{\Cslidec@@{##1}}\afterPLACE@}%
2327 \else \let\next@=\afterPLACE@
2328 \fi\fi \next@}

1.3i. 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, i.e., ? … /A/ is the same as ? … +/A/.

1.3j. 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⟩}^{4}, for example, Bug: Only works for straight arrows at present.

   \xy <1cm,0cm>:
    (0,0)*=0{+}="+" ;
    (2,1)*=0{\times}="*" **@{.} ,
    (1,0)*+{A} ; (2,2)*+{B} **@{-}
    ?!{"+";"*"} *{\bullet}
   \endxy

will typeset

[figure: +; ×; A; B; •]

1.3k. The positions denoted by the axis intersection ⟨coord⟩inates x and y are the points where the line through p and c intersects with each axis. The following figure illustrates this:

[figure: origin; xbase; ybase; ∘; p; ∘; c; x; •; y; •]

Exercise 1.4: 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):

4The braces can be replaced by (*… *) once, i.e., there can be no other braces nested inside it.

[figure: A; B; C; D]

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) with zero size 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:

<dX,dY > := <X_{c},Y_{c}> − <X_{p}, Y_{p}>
<A,B> := <X_{c},Y_{c}> − <X_{origin},Y_{origin}>
<D_{c},L_{c}> := <| \begin{matrix}R & dX \\ U & dY \end{matrix} |,| \begin{matrix}R & A \\ U & B \end{matrix} | >
<X_{c},Y_{c}> := <X_{c},Y_{c}> − (L_{c}/D_{c}) × <dX,dY >

where we really do D := (R/pt)dY − (U/pt)dX and similarly for L.

2450 \xydef@\intersect@{
2451 \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p
2452 \A@=\X@c \advance\A@-\X@origin \B@=\Y@c \advance\B@-\Y@origin
2453 \edef\next@{\expandafter\removePT@\the\R@c}%
2454 \edef\nextii@{\expandafter\removePT@\the\U@c}%
2455 \D@c=\next@\d@Y \advance\D@c-\nextii@\d@X \divide\D@c\KK@
2456 \L@c=\next@\B@ \advance\L@c-\nextii@\A@ \divide\L@c\KK@
2457 \ifdim\D@c=\z@\zeroDivide@\else \quotient@\next@\L@c\D@c \fi
2458 \advance\X@c-\next@\d@X \advance\Y@c-\next@\d@Y
2459 \czeroEdge@}

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@.

2468 \xydef@\zeroDivide@@{\zeroDivide@message{\intersect@}{treated as 0}\DN@{0}}
2469 \xydef@\zeroDivide@message#1#2{\xywarning@{division by 0 in \string#1, #2}}
2470 \xylet@\zeroDivide@=\zeroDivide@@
2472 \xydef@\zeroDivideLimit@@{\ifdim\L@c=\z@ \DN@{0}%
2473 \else\ifdim\L@c<\z@\DN@{-\zeroDivide@Limit}%
2474 \else\DN@{\zeroDivide@Limit}\fi\fi
2475 \zeroDivide@message{\intersect@}{replaced by \zeroDivide@Limit}}
2476 \xydef@\zeroDivideLimit@#1{\edef\zeroDivide@Limit{#1}%
2477 \let\zeroDivide@=\zeroDivideLimit@@}
2478 \xylet@\zeroDivideLimit=\zeroDivideLimit@

By specifying \zeroDivideLimit\{⟨num⟩\} the user can locally establish that \frac{x}{0} = sgn(x)⟨num⟩, whenever such a division by zero would otherwise occur in an intersection calculation.

1.3l. A ⟨pos⟩ ⟨decor⟩ grouped in {}-braces^{5} 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.

Exercise 1.5: What effect is achieved by using the ⟨coord⟩inate “{;}”?

The code is inside \POS@.

1.3m. The vector /Z/, where Z is a ⟨dimen⟩sion, is the same as the vector <Z cos α,Z sin α> where α is the angle of the last direction set by a connection (i.e., with **) or subsequent placement (?) position.

2514 \xydef@\vfromslide@#1{\enter@\DirectionfromtheDirection@ \begingroup
2515 \plainxy@\afterDIRECTIONorEMPTY\vfromslide@i\vfromslide@i#1@}
2517 \xydef@\vfromslide@i#1@{\DN@{#1}%
2518 \edef\next{\endgroup
2519 \ifx\next@\empty \dimen@=.5pc \else \dimen@=#1\relax \fi
2520 \X@c=\cosDirection\dimen@ \Y@c=\sinDirection\dimen@}\next
2521 \leave@}

It is possible to give a ⟨direction⟩ as described in the next section (figure 1.5, note 1.4l in particular) that will then be used to set the value of α. It is also possible to omit the ⟨dimen⟩ in which case it is set to a default value of .5pc.

1.3n. 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):

                                [figure: c; L; R; D; U; LD; RD; LU; RU; CL; CR; DC; UC; C; P; p; E]

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.

Exercise 1.6: What is the difference between the ⟨pos⟩itions c?< and c+E?

Exercise 1.7: What does this typeset?

\xy *=<3cm,1cm>\txt{Box}*\frm{-}
 !U!R(.5) *\frm{..}*{\bullet} \endxy

5One can use (*… *) instead also here.

Hint: \frm is defined by the frame extension and just typesets a frame of the kind indicated by the argument.

Bug: Currently only the single-letter corners (L, R, D, U, C, E, and P) will work for any shape—the others silently assume that the shape is rectangular.

1.3o. The stack is a special construction useful for storing a sequence of ⟨pos⟩itions that are accessible using the special ⟨coord⟩inates sn, 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 sn 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:

@⟨stacking⟩ Action
@+⟨coord⟩ push ⟨coord⟩
@-⟨coord⟩ c ← ⟨coord⟩ then pop
@=⟨coord⟩ load stack with ⟨coord⟩
@@⟨coord⟩ do ⟨coord⟩ for c ← stack
@i  initialise
@(  enter new frame
@)  leave current frame

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:

\xy
 @={(0,-10),(10,3),(20,-5)} @@{*{P}}
\endxy

will typeset

P P P

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 @(.

Exercise 1.8: How would you change the example above to connect the points as shown below?

[figure]

First the stack top and bottom, both initially −1:

2673 \xydef@\s@bot{-1}
2674 \xydef@\s@top{-1}

Next the function to set c ← sn, i.e., test that bot < n + bot < top and then run the associated stack element.

2681 \xydef@\cfroms@#1{\tests@{#1}\runs@\outofranges@}
2683 \xydef@\tests@#1#2#3{\DN@{#3}%
2684 \count@=\s@top \advance\count@-#1\relax
2685 \ifnum\count@>\s@bot\relax \ifnum\count@>\s@top\else\DN@{#2}\fi\fi
2686 \next@}
2688 \xydef@\runs@{\csname S@\the\count@\endcsname}
2690 \xydef@\outofranges@{\count@=\s@top \advance\count@-\s@bot
2691 \xyerror@{stack index out of range (should be 0..\the\count@)}{}}

Finally the actual code to do the stack operations: it depends on the ‘code’ passed after @; spaces are not allowed:

2698 \xydef@\STACK@{%
2699 \addPLUS@\ifx\next
2700 \addPLUS@\DN@{\xy@{@+}{}\afterCOORD{\xy@@\spushc@ \xyFN@\POS@}}%
2701 \else\addDASH@\ifx\next
2702 \addDASH@\DN@{\xy@{@-}{}\afterCOORD{\xy@@\spop@ \xyFN@\POS@}}%
2703 \else \ifx i\next \DN@ i{\xy@{@i}\sinit@ \xyFN@\POS@}%
2704 \else \ifx (\next \DN@ ({\xy@{@(}\senter@ \xyFN@\POS@}%
2705 \else \ifx )\next \DN@ ){\xy@{@)}\sleave@ \xyFN@\POS@}%
2706 \else\addEQ@\ifx\next \addEQ@\DN@{\STACK@load}%
2707 \else\addAT@\ifx\next \addAT@\DN@{\xy@{@@}{}\smap@}%
2708 \else \DN@##1{\xyerror@{illegal stack command ##1}{}\afterCOORD{\xyFN@\POS@}}%
2709 \fi\fi\fi\fi\fi\fi\fi \next@}
2711 \xydef@\STACK@load{\xy@{@=}{%
2712 \if\sempty@\else \xywarning@{loading on top of non-empty stack}\sinit@ \fi
2713 \let\comma@@=\spushc@}%
2714 \afterCOORD{\xy@@{\spushc@ \let\comma@@=\relax}\xyFN@\POS@}}
2716 \xydef@\spushc@{%
2717 \count@=\s@top \advance\count@\@ne \edef\s@top{\the\count@}%
2718 \expandafter\edef\csname S@\s@top\endcsname{\cfromthec@}}
2720 \xydef@\spushid@#1{\DNii@{#1}\edef\nextii@{\codeof\nextii@}%
2721 \expandafter\let\expandafter\next@\csname Q@\nextii@\endcsname
2722 \ifx\next@\relax \xyerror@{<pos> \string"\nextii@\string" not defined}{}%
2723 \else
2724 \count@=\s@top \advance\count@\@ne \edef\s@top{\the\count@}%
2725 \DNii@##1{\expandafter\def\csname S@\s@top\endcsname{##1}}%
2726 \expandafter\nextii@\expandafter{\next@}%
2727 \fi}
2729 \xydef@\idfroms@#1#2{%

2730 \tests@{#2}{\DN@{\idfromxy@{#1}}%
2731 \expandafter\expandafter\expandafter\next@
2732 \expandafter\expandafter\expandafter{\csname S@\the\count@\endcsname}%
2733 }\outofranges@}
2735 \xydef@\spop@{\count@=\s@top
2736 \ifnum\count@>\s@bot \advance\count@\m@ne \edef\s@top{\the\count@}%
2737 \else \xyerror@{nothing to pop from stack}{}\fi}
2739 \xydef@\sinit@{\edef\s@top{\s@bot}}
2741 \xydef@\senter@{%
2742 \count@=\s@top \advance\count@\@ne
2743 \expandafter\edef\csname S@\the\count@\endcsname{\s@bot}%
2744 \edef\s@bot{\the\count@}\edef\s@top{\the\count@}}
2746 \xydef@\sleave@{%
2747 \ifnum\s@bot=\s@top\else \xywarning@{leaving non-empty stack}\sinit@ \fi
2748 \ifnum\s@bot>\m@ne \edef\s@bot{\csname S@\s@top\endcsname}%
2749 \count@=\s@top \advance\count@\m@ne \edef\s@top{\the\count@}%
2750 \edef\sbot{\the\count@}\fi}
2752 \xydef@\sempty@{\ifnum\s@top=\s@bot TT\else TF\fi}

\smap@ maps a ⟨coord⟩ over a stack:

2758 \xydef@\xytotoks@#1#2{\addtotoks@{#2}}
2759 \xydef@\xytotoks@@toksix@#1{\addtotoks@{\toks9={#1}}}
2761 \xydef@\smap@{%
2762 \begingroup \toks@={}\let\xy@=\xytotoks@ \change@oxy@\xy@
2763 \let\xy@@ix@=\xytotoks@@toksix@
2764 \afterCOORD{\expandafter\endgroup
2765 \expandafter\smapxy@@\expandafter{\the\toks@}\xyFN@\POS@}}
2767 \xydef@\smapxy@@#1{\xy@@{\edef\smapp@@{\s@bot}\smapxy@i{#1}}}
2769 \xylet@\smapp@@=\empty
2771 \xydef@\smapxy@i#1{%
2772 \ifnum\smapp@@<\s@top
2773 \count@=\smapp@@ \advance\count@\@ne \edef\smapp@@{\the\count@}%
2774 \DN@{\csname S@\smapp@@\endcsname #1\relax \smapxy@i{#1}}%
2775 \else \let\next@=\relax
2776 \fi \next@}

1.3p. It is possible to define new ⟨coord⟩inates on the form "⟨id⟩" by saving the current c using the … ="⟨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, i.e., "⟨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

@:"⟨id⟩"      "⟨id⟩" restores current base
@⟨coord⟩"⟨id⟩" "⟨id⟩" reinterprets ⟨coord⟩

@@"⟨id⟩"      @="⟨id⟩" reloads this stack

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⟩"}.

Exercise 1.9: Write a macro "dbl" to double the size of the current c object, e.g., changing it from the dotted to the dashed outline in this figure:

[figure: +]

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.

This parser distinguishes between the cases:

2843 \xydef@\saveid@{%
2844 \ifx \space@\next \expandafter\DN@\space{\xyFN@\saveid@}%gobble spaces
2845 \else \ifx "\next\DN@"##1"{\xy@{="##1"}{\idfromc@{##1}}\xyFN@\POS@}%
2846 \else \ifx :\next\DN@:##1"##2"{\xy@{=:"##2"}{\idfrombase@{##2}}\xyFN@\POS@}%
2847 \else\addAT@\ifx\next
2848 \addAT@\DN@"##1"{\xy@{=@"##1"}{\idfromstack@{##1}}\xyFN@\POS@}%
2849 \else \ifx s\next
2850 \DN@ s##1"##2"{\xy@{=s##1"##2"}{\idfroms@{##2}{##1}}\xyFN@\POS@}%
2851 \else\addEQ@\ifx\next \let\saveid@COORD@@=\saveid@COORDii
2852 \addEQ@\DN@{\xyFN@\saveid@COORD}%
2853 \else \let\saveid@COORD@@=\saveid@COORDi \let\next@=\saveid@COORD
2854 \fi\fi\fi\fi\fi\fi \next@}
2856 \xylet@\saveid@COORD@@=\relax

Here is the code for saving/restoring a position and a base.

2862 \xydef@\idfromc@#1{\DN@{#1}%
2863 \expandafter\edef\csname Q@\codeof\next@\endcsname{\cfromthec@}}
2865 \xydef@\idfrombase@#1{\DN@{#1}%
2866 \expandafter\edef\csname Q@\codeof\next@\endcsname{\basefromthebase@}}
2868 \xydef@\idfromstack@#1{%
2869 \toks@={\if\sempty@\else
2870 \xywarning@{loading on top of non-empty stack}\sinit@ \fi}%
2871 \count@=\s@bot \advance\count@\@ne
2872 \ifnum\count@>\s@top\else
2873 \loop@

2874 \expandafter\let\expandafter\next@\csname S@\the\count@\endcsname
2875 \expandafter\addtotoks@\expandafter{\next@}%
2876 \ifnum\count@<\s@top \advance\count@\@ne \addtotoks@{\spushc@}\repeat@

2877 \fi

2878 \DN@{#1}\edef\next@##1{%
2879 \def\expandafter\noexpand\csname Q@\codeof\next@\endcsname{##1}}%
2880 \expandafter\next@\expandafter{\the\toks@}}
2882 \xydef@\saveid@COORD{%
2883 \begingroup \toks@={}\let\xy@=\xytotoks@ \change@oxy@\xy@
2884 \let\xy@@ix@=\xytotoks@@toksix@
2885 \afterCOORD{\expandafter\saveid@COORDi\expandafter{\the\toks@}}}
2887 \xydef@\saveid@COORDi#1#2"#3"{\endgroup \xy@@{\idfromxy@{#3}{#1}}\xyFN@\POS@}
2888 \xydef@\saveid@COORDii#1#2"#3"{\endgroup \xy@@{\idfromcxy@{#3}{#1}}\xyFN@\POS@}
2890 \xydef@\idfromxy@#1#2{\DN@{#1}%
2891 \expandafter\def\csname Q@\codeof\next@\endcsname{#2}}
2893 \xydef@\idfromcxy@#1#2{\DN@{#1}%
2894 \expandafter\edef\csname Q@\codeof\next@\endcsname{\cfromthec@#2}}
2896 \xydef@\cfromid@#1{\DNii@{#1}\edef\nextii@{\codeof\nextii@}%
2897 \expandafter\let\expandafter\next@\csname Q@\nextii@\endcsname
2898 \ifx\next@\relax \xyerror@{<pos> \string"\nextii@\string" not defined}{}%
2899 \else \expandafter\next@\fi}

1.4 Objects

2914 \message{objects,}

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 1.5 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 {… } then check in this manual whether you can use (*… *) instead. If not then you will have to use a different construction!

We first discuss the parser and then summarise the required methods. The entry point to use of objects is \object described in note 1.4c. 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⟩!

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 \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

Syntax  Action
⟨object⟩  ⟶ ⟨modifier⟩ ⟨object⟩  apply ⟨modifier⟩ to ⟨object⟩
| ⟨objectbox⟩  build ⟨objectbox⟩ then apply its ⟨modifier⟩s
⟨objectbox⟩ ⟶ { ⟨text⟩ }  build default1.4a object
| ⟨library object⟩ | @⟨dir⟩  use ⟨library object⟩ or ⟨dir⟩ectional (see §1.6)

| ⟨TEX box⟩ { ⟨text⟩ } build box1.4b object with ⟨text⟩ using the given

⟨TEX box⟩ command, e.g., \hbox

| \object ⟨object⟩  wrap up the ⟨object⟩ as a finished object box1.4c
| \composite { ⟨composite⟩ } build composite object box1.4d
| \xybox { ⟨pos⟩ ⟨decor⟩ }  package entire XY-picture as object1.4e

⟨modifier⟩ ⟶ ! ⟨vector⟩ ⟨object⟩ has its reference point shifted1.4f by

⟨vector⟩

| !  ⟨object⟩ has the original reference point reinstated
| ⟨add op⟩ ⟨size⟩  change ⟨object⟩ size1.4g
| h | i  ⟨object⟩ is hidden1.4h, invisible1.4i
| [ ⟨shape⟩ ]  ⟨object⟩ is given the specified ⟨shape⟩1.4j

| [= ⟨shape⟩ ] define ⟨shape⟩1.4k to reestablish current object

style

| ⟨direction⟩  set current direction for this ⟨object⟩
⟨add op⟩ ⟶ + | - | = | += | -=  grow, shrink, set, grow to, shrink to
⟨size⟩  ⟶ ⟨empty⟩  default size1.4g
| ⟨vector⟩  size as sides of rectangle covering the ⟨vector⟩
⟨direction⟩ ⟶ ⟨diag⟩  ⟨diag⟩onal direction1.4l
| v ⟨vector⟩  direction1.4l of ⟨vector⟩
| q{ ⟨pos⟩ ⟨decor⟩ }  direction1.4l from p to c after ⟨pos⟩ ⟨decor⟩
| ⟨direction⟩ : ⟨vector⟩  vector relative to ⟨direction⟩1.4m
| ⟨direction⟩ _| ⟨direction⟩ ^90^{∘} clockwise/anticlockwise to ⟨direction⟩1.4m
⟨diag⟩ ⟶ ⟨empty⟩ last used direction (not necessarily diagonal1.4l)
| l | r | d | u  left, right, down, up diagonal1.4l
| ld | rd | lu | ru  left/down, … diagonal1.4l
⟨composite⟩ ⟶ ⟨object⟩  first object is required
| ⟨composite⟩ * ⟨object⟩  add ⟨object⟩ to composite object box1.4d

Figure 1.5: ⟨object⟩s.

⟨modifier⟩s afterwards.

3074 \xydef@\OBJECT@{%
3075 \ifx \space@\next \expandafter\DN@\space{\xyFN@\OBJECT@}%gobble spaces
3076 \else\ifcat A\noexpand\next \let\next@=\OBJECT@letter
3077 \else \let\next@=\OBJECT@other \fi\fi \next@}
3079 \xydef@\OBJECT@letter{%
3080 \ifx i\next \DN@ i{\addtotoks@\Invisible@true \xyFN@\OBJECT@}%
3081 \else\ifx h\next\DN@ h{\addtotoks@\Hidden@true \xyFN@\OBJECT@}%
3082 \else\ifx o\next\DN@ o{\xywarning@{Obsolete o modifier used}\OBJECT@shape{o}}%
3083 \else\ifx x\next\DN@ x{\xywarning@{Obsolete x modifier used}\OBJECT@shape{}}%
3084 \else\ifx @\next\DN@ @##1##{%

3085 %

3086 \xywarning@{Impossible @ (letter) should not be here!!}

3087 %

3088 \OBJECT@@{\dir##1}}%
3089 \else \let\next@=\OBJECT@direction
3090 \fi\fi\fi\fi\fi \next@}
3092 \xydef@\OBJECT@other{%
3093 \ifx !\next \DN@!{\OBJECT@shift}%
3094 \else\addPLUS@\ifx \next \DN@{\OBJECT@change}%
3095 \else\addDASH@\ifx \next \DN@{\OBJECT@change}%
3096 \else\addEQ@\ifx \next \DN@{\OBJECT@set}%
3097 \else\ifx [\next %]
3098 \DN@[##1]{\xy@{[##1]}{\OBJECT@shape{##1}}}%
3099 \else\ifx ^\next \let\next@=\OBJECT@direction
3100 \else\ifx _\next \let\next@=\OBJECT@direction
3101 \else\ifx :\next \let\next@=\OBJECT@direction
3102 \else\ifx ?\next
3103 \DN@ ?{\xywarning@{\string? modifier used}\xyFN@\OBJECT@direction}%
3104 \else\ifx (\next %)
3105 \let\next@=\OBJECT@direction
3106 \else\addAT@\ifx\next \addAT@\DN@##1##{\OBJECT@@{\dir##1}}%
3107 \else \DN@##1##{\OBJECT@@{##1}}%
3108 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}

\OBJECT@@ is where we actually build the box by first l.3126 saving the previous edge in case it is needed, then l.3127 setting the defaults (including temporarily resetting \xy@ to execute in case any \xy@s are used internally), l.3132 building the object box (which might change them) using \objectbox if no other command specified and setting the D, U, L, R dimensions ad required using the \Leftness@ and \Upness@ methods, and finally l.3136 setting up the R_{p}, U_{p} dimensions (as discussed above) and applying the ⟨modifier⟩s stored in \toks@ and dumping the modified box.

3123 \xydef@\prevEdge@@{\zeroEdge}
3125 \xydef@\OBJECT@@#1#2{%
3126 \expandafter\def\expandafter\prevEdge@@\expandafter{\the\Edge@c}
3127 \expandafter\Edge@c\expandafter{\objectEdge}
3128 \Invisible@false\Hidden@false
3129 \def\Leftness@{.5}\def\Upness@{.5}%
3130 \gdef\preXY@style@{}\gdef\postXY@style@{}%

3131 \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@\relax}%
3132 \DN@{#1}\ifx\next@\empty \DNii@{#2}
3133 \ifx\nextii@\empty \DN@{\hbox\bgroup\no@}\else \let\next@=\objectbox \fi\fi
3134 \setbox\z@=\next@{#2}\L@c=\Leftness@\wdz@ \R@c=\wdz@ \advance\R@c-\L@c
3135 \D@c=\dp\z@ \advance\D@c\ht\z@ \U@c=\Upness@\D@c \advance\D@c-\U@c
3136 \R@p=\z@ \L@p=\L@c \U@p=\U@c \advance\U@p-\ht\z@ \D@p=-\U@p
3137 \the\toks@\toks@={}\setboxz@h{\kern\R@p \raise\U@p\boxz@}%
3138 \checkZeroEdge@
3139 \dimen@=\L@c \advance\dimen@\R@c \wdz@=\dimen@ \ht\z@=\U@c \dp\z@=\D@c \boxz@
3140 \OBJECT@x}
3142 \xydef@\adjustLR@{%
3143 \ifdim\zz@\wdz@ \L@c=\z@ \R@c=\z@ \dimen@=\Leftness@\p@
3144 \ifdim\dimen@<\z@ \L@c=\dimen@ \R@c=-\L@c
3145 \else\ifdim\dimen@>\p@ \L@c=\dimen@ \advance\L@c-\p@ \R@c=-\L@c \fi\fi
3146 \else \L@c=\Leftness@\wdz@ \R@c=\wdz@ \advance\R@c-\L@c \fi}
3148 \xydef@\adjustUD@{\dimen@=\ht\z@ \advance\dimen@\dp\z@
3149 \ifdim\zz@\dimen@ \U@c=\z@ \D@c=\z@ \dimen@=\Upness@\p@
3150 \ifdim\dimen@<\z@ \U@c=\dimen@ \D@c=-\L@c
3151 \else\ifdim\dimen@>\p@ \U@c=\dimen@ \advance\U@c-\p@ \D@c=-\L@c \fi\fi
3152 \else \D@c=\dimen@ \U@c=\Upness@\dimen@ \advance\D@c-\U@c \fi}
3154 \def\checkZeroEdge@{%
3155 \DN@{}%
3156 \ifdim\zz@\L@c \ifdim\zz@\R@c \ifdim\zz@\U@c \ifdim\zz@\D@c
3157 \DN@{\Edge@c={\zeroEdge}}\fi\fi\fi\fi
3158 \next@}

As an optimisation \OBJECT@@ sets the edge type of all zero-sized objects to \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@@{… }\def\Connect@@{… }\D@c=… \U@c=…

\L@c=. . . \R@c=. . . \Invisible@. . . \Hidden@. . . \def\Leftness@{. . . } \def\Upness@{. . . }” where

each … 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… ◯_{¨⌣}

3176 \xydef@\OBJECT@x{\toks@={\egroup\def\Drop@@}%
3177 \expandafter\addtotoks@\expandafter{\expandafter{\Drop@@}\def\Connect@@}%
3178 \expandafter\addtotoks@\expandafter{\expandafter{\Connect@@}}%
3179 \edef\tmp@{\D@c=\the\D@c \U@c=\the\U@c \L@c=\the\L@c \R@c=\the\R@c
3180 \Edge@c={\expandafter\noexpand\the\Edge@c}%
3181 \ifInvisible@\noexpand\Invisible@true\else\noexpand\Invisible@false\fi
3182 \ifHidden@\noexpand\Hidden@true\else\noexpand\Hidden@false\fi
3183 \def\noexpand\Leftness@{\Leftness@}\def\noexpand\Upness@{\Upness@}}%
3184 \expandafter\addtotoks@\expandafter{\tmp@}\the\toks@}

Methods: In addition to the “current object properties” for c (cf. 1.2.5) the following methods are set up by all objects:

    \Invisible@true or \Invisible@false whether object is invisible1.4i

\Hidden@true or \Hidden@false  whether object is hidden1.4h

\def\Leftness@{⟨factor⟩}  the desired L/(L + R)
\def\Upness@{⟨factor⟩}  the desired U/(D + U)

\def\Drop@@{… } 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@

\def\Connect@@{… } code that builds a connection from p to c, assuming \lastobjectbox@ contains the object

It is important to \def and not \let the last four methods since the TEXnique 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 1.8.3.

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 1.4a below.

Here are the declarations:

3219 \xynew@{if}\ifInvisible@
3220 \xynew@{if}\ifHidden@
3222 \xydef@\Leftness@{}
3223 \xydef@\Upness@{}
3225 \xydef@\Drop@@{\styledboxz@}
3226 \xydef@\Connect@@{}

Notes

1.4a. An ⟨object⟩ is built using \objectbox {⟨text⟩}. \objectbox is initially defined as

   \def\objectbox#1{%
    \hbox{$\objectstyle{#1}$}}
   \let\objectstyle=\displaystyle

but may be redefined by options or the user. The ⟨text⟩ should thus be in the mode required by the \objectbox command—with the default \objectbox shown above it should be in math mode.

Actually it is

3253 \xydef@\objectbox#1{\hbox{$\m@th\objectstyle{#1}$}}
3255 \xylet@\objectstyle=\textstyle

1.4b. 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 1.4f). 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.

TEXnical remark: Any macro that expands to something that starts with a ⟨box⟩ may be used as a ⟨TEX box⟩ here.

This is done by the parsing above.

1.4c. 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 ofXY-pictures) because a finished object is always also a box.

This macro is the main entry point to the ⟨object⟩ parser. It furthermore initialises the modifier list and the previous object edge.

3291 %\xydef@\object{\hbox\bgroup\object@}
3292 \xydef@\object{\hbox\bgroup\resetStyle@\object@}
3294 \xydef@\object@{%
3295 \edef\next@{={\DirectionfromtheDirection@}}\expandafter\toks@\next@
3296 % \resetStyle@\plainxy@ \xyFN@\OBJECT@}
3297 \plainxy@ \xyFN@\OBJECT@}

The initial value of \toks@ ⟨modifier⟩ list is explained in note 1.4l below.

1.4d. Several ⟨object⟩s can be combined into a single object using the special command \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.

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.

3319 \xydef@\composite#1#{\hbox\bgroup\composite@{#1}}
3321 \xydef@\composite@#1#2{%
3322 \DN@{#1}\ifx\next@\empty\else\xywarning@{no variants of
3323  \string\composite\space allowed}\fi
3324 \global\setbox9=\hbox\bgroup
3325 \D@p=-\maxdimen \U@p=-\maxdimen \L@p=-\maxdimen \R@p=-\maxdimen
3326 \xyFN@\composite@i#2@}
3328 \xydef@\composite@i{%
3329 \ifx \space@\next \expandafter\DN@\space{\xyFN@\composite@i}%gobble spaces
3330 \else\ifx *\next \DN@ *{\xyFN@\composite@i}%
3331 \else\ifx @\next \DN@ @{\composite@x}%
3332 \xyerror@{<composite> object expected}{}\czeroEdge@
3333 \else \DN@{\composite@ii}\fi\fi\fi \next@}
3335 \xydef@\composite@ii#1#{\composite@iii{#1}}
3337 \xydef@\composite@iii#1#2{%
3338 \setbox\z@=\object#1{#2}%
3339 \ifInvisible@ \setboxz@h{}\else
3340 \setboxz@h{\kern-\L@c \boxz@}\ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ {\Drop@@}\fi
3341 \ifHidden@\else
3342 \ifdim\U@p<\U@c \U@p=\U@c \fi \ifdim\D@p<\D@c \D@p=\D@c \fi
3343 \ifdim\R@p<\R@c \R@p=\R@c \fi \ifdim\L@p<\L@c \L@p=\L@c \fi

3344 \fi

3345 \xyFN@\composite@iv}
3347 \xydef@\composite@iv{%
3348 \ifx \space@\next \expandafter\DN@\space{\xyFN@\composite@iv}%gobble spaces
3349 \else \ifx @\next \DN@ @{\composite@x}%
3350 \else \let\next@=\composite@i \fi\fi \next@}
3352 \xydef@\composite@x{%
3353 \edef\tmp@{\egroup
3354 \D@c=\the\D@p \U@c=\the\U@p \L@c=\the\L@p \R@c=\the\R@p}\tmp@
3355 \setboxz@h{\kern\L@c\box9}\ht\z@=\U@c \dp\z@=\D@c

3356 \dimen@=\L@c \advance\dimen@\R@c \wdz@=\dimen@
3357 \Edge@c={\rectangleEdge}\computeLeftUpness@ \boxz@
3358 \OBJECT@x}
3360 \xydef@\computeLeftUpness@{%
3361 \dimen@=\L@c \advance\dimen@\R@c
3362 \ifdim\zz@\dimen@ \def\Connect@@{\straight@{\dottedSpread@\jot}}%
3363 \ifdim\zz@\L@c\else
3364 \DN@{\zeroEdge}\expandafter\DNii@\expandafter{\the\Edge@c}%
3365 \ifx\next@\nextii@\Edge@c={\rectangleEdge}\fi\fi
3366 \else \quotient@\Leftness@\L@c\dimen@ \fi
3367 \dimen@=\U@c \advance\dimen@\D@c
3368 \ifdim\zz@\dimen@ \def\Connect@@{\straight@{\dottedSpread@\jot}}%
3369 \ifdim\zz@\U@c\else
3370 \DN@{\zeroEdge}\expandafter\DNii@\expandafter{\the\Edge@c}%
3371 \ifx\next@\nextii@\Edge@c={\rectangleEdge}\fi\fi
3372 \else \quotient@\Upness@\U@c\dimen@ \fi}

1.4e. Take an entire XY-picture and wrap it up as a box as described in §1.2.1. 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.

This is simple exploiting the fact that \endxy actually sets up the extents of the ‘object’:

3390 \xydef@\xybox#1{\xy#1\endxy \Edge@c={\rectangleEdge}\computeLeftUpness@}

1.4f. 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.

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… hence \xytotoks@ is used to delay execution.

3410 \xydef@\OBJECT@shift{%
3411 \let\xy@=\xytotoks@ \afterVECTORorEMPTY
3412 {\OBJECT@shift@}%
3413 {\addtotoks@{\X@c=-\L@c \advance\X@c\R@p \advance\X@c\L@p \Y@c=\U@p}%
3414 \OBJECT@shift@}}
3416 \xydef@\OBJECT@shift@{%
3417 \addtotoks@{\advance\U@p-\Y@c
3418 \advance\L@c\X@c \advance\R@c-\X@c \advance\D@c\Y@c \advance\U@c-\Y@c
3419 \computeLeftUpness@}%
3420 \let\xy@=\oxy@ \xyFN@\OBJECT@}

Exercise 1.10: What is the difference between the ⟨pos⟩itions 0*{a}!DR and 0*!DR{a}?

1.4g. 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, i.e., 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.

⟨add op⟩ description
+     grow
-     shrink
=     set to

                               +=

grow to at least

                               -=

shrink to at most

In each case the ⟨vector⟩ may be omitted which invokes the “default size” for the particular ⟨add op⟩:

⟨add op⟩ default
+     +<2 × objectmargin>
-     -<2 × objectmargin>
=     =<objectwidth,objectheight>
+=    +=< max(L_{c} + R_{c}, D_{c} + U_{c})>
-=    -=< min(L_{c} + R_{c}, D_{c} + U_{c})>

The defaults for the first three are set with the commands

                         \objectmargin ⟨add op⟩ {⟨dimen⟩}
                         \objectwidth ⟨add op⟩ {⟨dimen⟩}
                         \objectheight ⟨add op⟩ {⟨dimen⟩}

where ⟨add op⟩ is interpreted in the same way as above.

3484 \xylet@\objectmargin@=\jot
3485 \xylet@\objectwidth@=\z@
3486 \xylet@\objectheight@=\z@
3488 \xydef@\objectmargin{\afterADDOP{\Addop@@\objectmargin@}}
3489 \xydef@\objectwidth{\afterADDOP{\Addop@@\objectwidth@}}
3490 \xydef@\objectheight{\afterADDOP{\Addop@@\objectheight@}}

The defaults for +=/-= are such that the resulting object will be the smallest containing/largest contained square.

Exercise 1.11: How are the objects typeset by the ⟨pos⟩itions “*+UR{\sum}” and “*+DL{\sum}” enlarged?

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.

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 1.4f:

3522 \xydef@\OBJECT@change{%
3523 \afterADDOP{%
3524 \addEQ@\ifx \next
3525 \addtotoks@{\X@c=\D@c \advance\X@c\U@c \Y@c=\L@c \advance\Y@c\R@c}%
3526 \else
3527 \addtotoks@{\X@c=\objectmargin@ \advance\X@c\X@c \Y@c=\X@c}%

3528 \fi

3529 \let\xy@=\xytotoks@
3530 \afterVECTORorEMPTY\OBJECT@change@\OBJECT@change@}}
3532 \xydef@\OBJECT@set{%
3533 \afterADDOP{%
3534 \let\xy@=\xytotoks@ \afterVECTORorEMPTY\OBJECT@change@
3535 {\addtotoks@{\X@c=\objectwidth@ \Y@c=\objectheight@}\OBJECT@change@}}}

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.

3543 \xydef@\OBJECT@change@{%
3544 \addtotoks@{\advance\R@c\L@c \advance\R@p-\L@c \let\tmp@=\R@c}%
3545 \expandafter\addtotoks@\expandafter{\Addop@@\tmp@\X@c\R@c=\tmp@
3546 \L@c=\Leftness@\R@c \advance\R@p\L@c \advance\R@c-\L@c}%
3547 \addtotoks@{\advance\D@c\U@c \let\tmp@=\D@c}%
3548 \expandafter\addtotoks@\expandafter{\Addop@@\tmp@\Y@c\D@c=\tmp@
3549 \U@c=\Upness@\D@c \advance\D@c-\U@c}%
3550 \let\xy@=\oxy@ \xyFN@\OBJECT@}

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, i.e., R_{p}.

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:

⟨add op⟩

effect of \Addop@@ cs D

+  cs ← cs + D
-  cs ← cs − D
=  cs ← D
+=  cs ← \{ \begin{matrix}D & if D ≤ cs \\ cs & if D > cs \end{matrix}
-=  cs ← \{ \begin{matrix}D & if D ≥ cs \\ cs & if D < cs \end{matrix}

Furthermore \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 \afterADDOP macro is relatively simple because ⟨add op⟩s don’t nest:

3591 \xydef@\afterADDOP#1{\def\afterADDOP@{#1}\xyFN@\ADDOP@}
3593 \xylet@\afterADDOP@=\empty
3595 \xydef@\ADDOP@{%
3596 \ifx \space@\next \expandafter\DN@\space{\xyFN@\ADDOP@}%gobble spaces
3597 \else\addPLUS@\ifx \next \addPLUS@\DN@{\xyFN@\ADDOP@plus}%
3598 \else\addDASH@\ifx \next \addDASH@\DN@{\xyFN@\ADDOP@minus}%
3599 \else\addEQ@\ifx \next
3600 \addEQ@\DN@{\def\Addop@@{\Addop@0+=}\afterADDOP@}%
3601 \else
3602 \DN@{\def\Addop@@{\Addop@0+=}\afterADDOP@}%
3603 \fi\fi\fi\fi \next@}
3605 \xydef@\ADDOP@plus{%

3606 \addEQ@\ifx \next
3607 \addEQ@\DN@{\def\Addop@@{\Addop@0+<}\afterADDOP@}%
3608 \else
3609 \DN@{\def\Addop@@{\Addop@1+=}\afterADDOP@}%
3610 \fi \next@}
3612 \xydef@\ADDOP@minus{%
3613 \addEQ@\ifx \next
3614 \addEQ@\DN@{\def\Addop@@{\Addop@0+>}\afterADDOP@}%
3615 \else
3616 \DN@{\def\Addop@@{\Addop@1-=}\afterADDOP@}%
3617 \fi \next@}

The work is done by the general \Addop@ {f} {±} {▷◁} {cs} D that defines

cs ≡ \{ \begin{matrix}f × cs ± D & if ¬((f × cs ± D) ▷◁ D) \\ cs & otherwise \end{matrix}

and also leaves the dimension in \dimen@.

3631 \xydef@\Addop@#1#2#3#4#5{%
3632 \dimen@=#4\relax \edef#4{\the\dimen@}%
3633 \dimen@=#1\dimen@ \advance\dimen@#2#5\relax %\advance\dimen@ 1sp %HACK
3634 \ifdim\dimen@#3#4\else \edef#4{\the\dimen@}\fi
3635 \ifx\xy@\xyinitial@\else \DN@##1{\xy@@{\edef#4{##1}\checkZeroEdge@}}%
3636 \expandafter\next@\expandafter{#4}\fi}

1.4h. 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 §1.2.1.

This is handled by the \ifHidden@ conditional allocated with the methods.

1.4i. An invisible object will be treated completely normal except that it won’t be typeset, i.e., XY-pic will behave as if it was.

This is handled by the \ifInvisible@ conditional allocated with the methods.

1.4j. 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 [.], [], and [o], corresponding to the outlines

× ,  ^{×}^{L}  ^{R}_{D}^{U}  , and [figure: ×; L; R; D; U]

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 [] and for plain coordinates it is [.].

3698 \xydef@\objectEdge{\rectangleEdge}

Furthermore the ⟨shape⟩s [r], [l], [u], and [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, e.g., the object [r]\hbox{Wide text} has reference point at the × in Wide text × but the object [d]\hbox{Wide text} has reference point at the × in Wide text × . Finally, [c] puts the reference point at the center.

3713 \xydefcsname@{shape [r]}{\advance\U@p\D@c \centerobject@
3714 \ifdim\L@c>\D@c
3715 \advance\R@c\L@c \L@c=.5\U@c \advance\L@c.5\D@c \advance\R@c-\L@c \fi
3716 \advance\U@p-\D@c}
3717 \xydefcsname@{shape [l]}{\advance\U@p\D@c \centerobject@
3718 \ifdim\L@c>\D@c
3719 \advance\L@c\R@c \R@c=.5\U@c \advance\R@c.5\D@c \advance\L@c-\R@c \fi
3720 \advance\U@p-\D@c}
3721 \xydefcsname@{shape [u]}{\advance\U@p\D@c \centerobject@
3722 \ifdim\D@c>\L@c
3723 \advance\U@c\D@c \D@c=.5\L@c \advance\D@c.5\R@c \advance\U@c-\D@c \fi
3724 \advance\U@p-\D@c}
3725 \xydefcsname@{shape [d]}{\advance\U@p\D@c \centerobject@
3726 \ifdim\D@c>\L@c
3727 \advance\D@c\U@c \U@c=.5\L@c \advance\U@c.5\R@c \advance\D@c-\U@c \fi
3728 \advance\U@p-\D@c}
3729 \xydefcsname@{shape [c]}{\advance\U@p\D@c \centerobject@ \advance\U@p-\D@c}
3731 \xydef@\centerobject@{%
3732 \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}

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.

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).

3749 \xydef@\OBJECT@shape#1{\DN@{shape [#1]}%
3750 \expandafter\let\expandafter\nextii@\csname\codeof\next@\endcsname
3751 \ifx\nextii@\relax\DN@{style [#1]}%
3752 \expandafter\let\expandafter\nextii@\csname\codeof\next@\endcsname
3753 \ifx\nextii@\relax \DN@{\OBJECT@shapei[#1]}%
3754 \else\DN@{\nextii@\xyFN@\OBJECT@}\fi
3755 \else \expandafter\addtotoks@\expandafter{\nextii@}%
3756 \DN@{\xyFN@\OBJECT@}%
3757 \fi \next@}
3759 \xydefcsname@{shape []}{\the\Edge@c5\relax}%
3760 \xydefcsname@{shape [Outer]}{\the\Edge@c5\relax}%
3761 \xydefcsname@{shape [Inner]}{\the\Edge@c4\relax}%
3762 \xydefcsname@{shape [o]}{\Edge@c={\circleEdge}\the\Edge@c5\relax
3763 \Edge@c={\circleEdge}\def\prevEdge@@{\circleEdge}}
3764 \xydefcsname@{shape [.]}{\czeroEdge@}

Add more simple shapes by defining more commands like these and proceed with coding the \… Edge command as described in §1.8.2.

Alternatively it is a “complex shape” of which none are defined in the kernel but some options like more variation… It is characterised by its first token and the rest of the contents of the []s is the argument (remember: no {}[] characters!); it is searched for as control sequence \[⟨shape⟩...] overridden in the same way by \*stylechar@⟨shape⟩@.

3779 \def\OBJECT@shapei[#1#2]{\DN@{shape [#1...]}%
3780 \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
3781 \ifx\next\relax\DN@{*stylechar@#1@}%
3782 \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
3783 \ifx\next\relax\DNii@{shape [#1#2]}%
3784 \xywarning@{illegal [<shape>] ignored: \codeof\nextii@\space not defined}%
3785 \DN@{\xyFN@\OBJECT@}%
3786 \else% Delete this: \expandafter\addtotoks@\expandafter{\next{#2}}%
3787 \DN@{\next{#2}\xyFN@\OBJECT@}%

3788 \fi

3789 \else
3791 \expandafter\addtotoks@\expandafter{\next{#2}}\DN@{\next{#2}\xyFN@\OBJECT@}%
3792 \fi \next@}

Bug: The above is messy!

1.4k. While typesetting an object, some of the properties are considered part of the ‘current object style’. Initially this means nothing but some of the ⟨style⟩s defined by extensions have this status, e.g., 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).

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 \specials 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 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@.

3853 \xydef@\preXY@style@{}
3854 \xydef@\postXY@style@{}
3856 \xydef@\resetStyle@{\gdef\preXY@style@{}\gdef\postXY@style@{}}

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⟩. To Do: 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 \⟨setcolor⟩ 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 PostScript back-end is even more efficient. Since PostScript is itself a programming language, the ⟨data⟩ can be just the PostScript code. A single \special command is sufficient to accommodate 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.

3894 \xynew@{toks}{\styletoks@}
3895 \xydef@\addtostyletoks@#1{%
3896 \expandafter\styletoks@\expandafter{\the\styletoks@#1}}

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.

3908 \xydef@\styledboxz@{%

3909 %

3910 %\W@{STYLED BOX:}%
3911 %\W@{: PRE={\meaning\xypre@Style@@}}%

3912 %

3913 \xypre@Style@@

3914 %

3915 %{\expandafter\DN@\expandafter{\the\styletoks@}\W@{: STYLTOKS={\codeof\next@}}}%

3916 %

3917 \boxz@

3919 %\W@{: POST={\meaning\xypost@Style@@}}%

3920 %

3921 \xypost@Style@@}
3923 \xydef@\xypre@Style@{\styletoks@={}\saveXyStyle@\preXY@style@
3924 \expandafter\DN@\expandafter{\the\styletoks@}%
3925 \ifx\next@\empty \DN@{\let\xypre@Style@@=\relax
3926 \let\xypost@Style@@=\relax \xypre@skipStyle@}%
3927 \else
3928 \let\xypre@Style@@=\relax \let\xypost@Style@@=\xypost@Style@
3929 \DN@{\expandafter\xydoprestyles@\expandafter{\the\styletoks@}}%
3930 \fi \next@ }
3932 \xydef@\xypost@Style@{\styletoks@={}\postXY@style@
3933 \expandafter\xydopoststyles@\expandafter{\the\styletoks@}%
3934 \let\xypost@Style@@=\relax \let\xypre@Style@@=\xypre@Style@ }
3936 \xydef@\xypre@skipStyle@#1\xypost@Style@@{#1\relax
3937 \let\xypre@Style@@=\xypre@Style@ }
3939 \xydef@\xydoprestyles@@{\literal@}
3940 \xydef@\xydopoststyles@@{\literal@}
3941 \xylet@\xydoprestyles@=\xydoprestyles@@
3942 \xylet@\xydopoststyles@=\xydopoststyles@@

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.

3953 \xydef@\modXYstyle@{%
3954 \ifx\xy@style@\empty\resetStyle@\fi \checkXyStyle@
3955 \expandafter\expandafter\expandafter\DN@
3956 \expandafter\expandafter\expandafter{\preXYstyle@@}%
3957 \ifx\next@\empty\else\DN@{\modXYstyle@@}\fi \next@ }
3959 \xydef@\modXYstyle@@{%
3960 \DN@##1{\expandafter\def\expandafter\tmp@\expandafter{##1}}%
3961 \expandafter\next@\expandafter{\preStyle@@}%
3962 \DN@##1{\expandafter\gdef\expandafter\preXY@style@\expandafter{%
3963 \preXY@style@ ##1}}\expandafter\next@\expandafter{\tmp@}%
3964 \DN@##1{\expandafter\def\expandafter\tmp@\expandafter{##1}}%
3965 \expandafter\next@\expandafter{\postStyle@@}%
3966 \DN@##1{\expandafter\gdef\expandafter\postXY@style@\expandafter{%
3967 \tmp@ ##1}}\expandafter\next@\expandafter{\postXY@style@}}
3969 \xydef@\xy@style@{}
3970 \xydef@\checkXyStyle@{\ifx\xy@style@\empty\resetStyle@\fi
3971 \let\xy@style@=\relax}

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.

3980 \xydef@\preStyle@@{}

3981 \xydef@\postStyle@@{}
3982 \xydef@\preXYstyle@@{\relax}
3984 \xydef@\loadxystyle@{%
3985 \let\xypre@Style@@=\xypre@Style@ \def\preXYstyle@@{\preStyle@@}}
3987 \loadxystyle@

Initially styles are activated but can be suppressed using \Unloadstyle@.

3994 \xydef@\Unloadstyle@{%
3995 \let\xypre@Style@@=\relax \let\xypost@Style@@=\relax
3996 \def\preXYstyle@@{\relax}}

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.

Saving styles: Once specified for an ⟨object⟩, the collection of ⟨style⟩s can be assigned a name, using [=⟨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 \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 \ar. The following illustrates how to avoid these messages by defining the style without typesetting anything.

    \setbox0=\hbox{%
     \xy\drop[OrangeRed][=A]{}\endxy}

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.

4040 \xydefcsname@{shape [=...]}#1{\checkXyStyle@ \addtotoks@{\xynamestyle@{#1}}}
4042 \xydef@\xynamestyle@#1{\checkXyStyle@
4043 \expandafter\DNii@\expandafter{\csname shape [#1]\endcsname}%
4044 \expandafter\ifx\nextii@\relax %%\xywarning@{Defining new style [#1]}%
4045 \else\xywarning@{Redefining style [#1]}\fi
4046 \expandafter\xynamestyle@@\csname shape [#1]\endcsname }
4048 \xydef@\xynamestyle@@#1{%
4049 \expandafter\def\expandafter\tmp@\expandafter{\preXY@style@}%
4050 \DN@##1{\def\tmp@{\checkXyStyle@\gdef\preXY@style@{##1}}}%
4051 \expandafter\next@\expandafter{\preXY@style@}%
4052 \DN@##1{\expandafter\gdef\expandafter#1\expandafter{\tmp@
4053 \gdef\postXY@style@{##1}}}%
4054 \expandafter\next@\expandafter{\postXY@style@}\DN@{}}

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.

4064 \xydef@\prevXypreStyle@@{}
4065 \xydef@\prevXypostStyle@@{}
4067 \xydef@\saveXyStyle@{\expandafter
4068 \def\expandafter\prevXypreStyle@@\expandafter{\preXY@style@}%
4069 \expandafter\def\expandafter\prevXypostStyle@@\expandafter{%
4070 \postXY@style@}}
4072 \xydef@\recoverXyStyle@{\expandafter
4073 \gdef\expandafter\preXY@style@\expandafter{\prevXypreStyle@@}%
4074 \expandafter\gdef\expandafter\postXY@style@\expandafter{%
4075 \prevXypostStyle@@}}

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.

4088 \xydef@\newxystyle#1#2#3{%
4089 \DN@{#3}\ifx\next@\empty
4090 \xydefcsname@{shape [#1]}{\csname xyshape@#1@\endcsname}%
4091 \else \expandafter\def\csname shape [#1]\endcsname{%
4092 \csname xyshape@#1@\endcsname}\fi
4093 \DN@{#2}\ifx\next@\empty
4094 \expandafter\def\csname xyshape@#1@\endcsname{%
4095 \xyundefinedStyle@{#1}{}@@}%
4096 \else \expandafter\def\csname xyshape@#1@\endcsname{#2}\fi}
4098 \xydef@\xyundefinedStyle@#1#2@@{%
4099 \xywarning@{style #1 not defined, nothing to apply}}

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@.)
   \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@@

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.

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 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:

4162 \xydef@\applyFIFOstyle@#1#2#3#4{\bgroup
4163 \styletoks@={\egroup\gdef\preXY@style@}%
4164 \expandafter\toks@\expandafter{\preXY@style@}%
4165 \expandafter\addtotoks@\expandafter{\expandafter#1\expandafter{#2}}%
4166 \expandafter\addtostyletoks@\expandafter{\expandafter{\the\toks@}%
4167 \gdef\postXY@style@}%
4168 \expandafter\toks@\expandafter{\expandafter#3\expandafter{#4}}%
4169 \expandafter\addtotoks@\expandafter{\postXY@style@}%
4170 \expandafter\addtostyletoks@\expandafter{\expandafter{\the\toks@}}%
4171 \the\styletoks@ }

Use this via: \applyLIFOstyle@\prestyle@{\thestyle@}\poststyle@{\prevstyle@}.

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:

4190 \xydef@\applyLIFOstyle@#1#2#3#4{\bgroup
4191 \styletoks@={\egroup\gdef\preXY@style@}%
4192 \expandafter\toks@\expandafter{\expandafter#1\expandafter{#2}}%
4193 \expandafter\addtotoks@\expandafter{\preXY@style@}%
4194 \expandafter\addtostyletoks@\expandafter{\expandafter{\the\toks@}%
4195 \gdef\postXY@style@}%
4196 \expandafter\toks@\expandafter{\postXY@style@}%
4197 \expandafter\addtotoks@\expandafter{\expandafter#3\expandafter{#4}}%
4198 \expandafter\addtostyletoks@\expandafter{\expandafter{\the\toks@}}%
4199 \the\styletoks@ }

Use this via: \applyLIFOstyle@\prestyle@{\thestyle@}\poststyle@{\prevstyle@}.

The advantage here is that only two pieces of data need be output to the dvi-file, no matter how many modifications are requested.

1.4l. 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.

The code just calls the general ⟨direction⟩ parser below:

4223 \xydef@\OBJECT@direction{\afterDIRECTIONorEMPTY{%
4224 \edef\next@{{\DirectionfromtheDirection@}}\expandafter\addtotoks@\next@
4225 \xyFN@\OBJECT@}%
4226 {\xyFN@\OBJECT@}}

Here is the ⟨direction⟩ parser: first the parts parsing the ⟨diag⟩ part then the parts parsing the ⟨trailer⟩ part:

4233 \xydef@\afterDIRECTIONorEMPTY#1#2{%
4234 \DN@##1{\def\afterDIRECTION@{\def\afterDIRECTION@{##1}%
4235 \ifDIRECTIONempty@\DN@{#2}\else\DN@{#1}\fi \next@}}%
4236 \expandafter\next@\expandafter{\afterDIRECTION@}%
4237 \xyFN@\DIRECTION@}
4239 \xylet@\afterDIRECTION@=\empty
4240 \xynew@{if}\ifDIRECTIONempty@
4242 \xydef@\DIRECTION@{%
4243 \ifx \space@\next \expandafter\DN@\space{\xyFN@\DIRECTION@}%gobble spaces
4244 \else\ifx v\next \DN@ v{\DIRECTION@v}%
4245 \else\ifx \bgroup\next \let\next@=\DIRECTION@group
4246 \else\ifx (\next \DN@({\xyFN@\DIRECTION@open}%))
4247 \else
4248 \DN@{\count@=8 %
4249 \afterDIAG{\ifnum\count@=8 \DN@{\DIRECTIONempty@true \xyFN@\DIRECTION@i}%
4250  \else \DN@{\xy@@{\dimen@=\xydashl@}\Directionfromdiag@}\fi \next@}}%
4251 \fi\fi\fi\fi \next@}
4253 \xydef@\DIRECTION@open{%
4254 \ifx *\next \DN@*##1*){\DIRECTION@group{##1}}%
4255 \else \DN@{\xyerror@{(* <pos> *) expected}{} \xyFN@\DIRECTION@i}%
4256 \fi \next@}

Diagonal directions. It is particularly easy to set ⟨diag⟩onal directions:

                                      [figure: dl = ld; d; dr = rd; r; ur = ru; u; ul = lu; l]

More to the point, ⟨diag⟩onals are stored internally as

                                        [figure: 0; 1; 2; 3; 4; 5; 6; 7]

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⟩.

4297 \def\afterDIAG#1{\def\afterDIAG@{#1}\xyFN@\DIAG@}
4299 \xydef@\DIAG@{%
4300 \ifx d\next \DN@ d{\count@=1 \xyFN@\DIAG@@}%
4301 \else\ifx r\next \DN@ r{\count@=3 \xyFN@\DIAG@@}%
4302 \else\ifx u\next \DN@ u{\count@=5 \xyFN@\DIAG@@}%
4303 \else\ifx l\next \DN@ l{\count@=7 \xyFN@\DIAG@@}%
4304 \else \let\next@=\afterDIAG@
4305 \fi\fi\fi\fi \next@}
4307 \xydef@\DIAG@@{\ifcase\count@ \or
4308 %\count@=1            3                   5                   7
4309 \DIAG@@@ l0r2\or\or \DIAG@@@ d2u4\or\or \DIAG@@@ r4l6\or\or \DIAG@@@ u6d0%
4310 \else\xybug@{impossible <diag> number}\fi
4311 \next@}
4313 \xydef@\DIAG@@@#1#2#3#4{%
4314 \ifx #1\next \count@=#2\DN@#1{\afterDIAG@}%
4315 \else \ifx #3\next \count@=#4\DN@#3{\afterDIAG@}%
4316 \else \let\next@=\afterDIAG@ \fi\fi}

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@:

4324 \xydef@\Directionfromdiag@{\ifcase\count@
4325  \xy@@{\dlDirection@\dimen@}%
4326 \or \xy@@{\dDirection@\dimen@}%
4327 \or \xy@@{\drDirection@\dimen@}%
4328 \or \xy@@{\rDirection@\dimen@}%
4329 \or \xy@@{\urDirection@\dimen@}%
4330 \or \xy@@{\uDirection@\dimen@}%
4331 \or \xy@@{\ulDirection@\dimen@}%
4332 \or \xy@@{\lDirection@\dimen@}%
4333 \or % 8 is legal and means change nothing
4334 \else\xybug@{impossible <diag>}\fi
4335 \DIRECTIONempty@false \xyFN@\DIRECTION@i}

Vector directions. 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, i.e., is the direction of the connection from (0,0) to (x,y).

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.

4356 \xydef@\DIRECTION@v{%
4357 \xy@{v}{\enter@{\cfromthec@ \X@origin=\the\X@origin \Y@origin=\the\Y@origin
4358 \X@p=\the\X@p \Y@p=\the\Y@p}%
4359 \X@origin=\z@ \Y@origin=\z@}%
4360 \afterVECTORorEMPTY
4361 {\xy@@{\X@p=\z@ \Y@p=\z@ \setupDirection@ \leave@}%
4362 \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
4363 {\xy@@\leave@ \xyerror@{<vector> expected after v}{}%
4364 \DIRECTIONempty@false \xyFN@\DIRECTION@i}}

Complex direction. 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 (*… *) form if this is to appear in an object ⟨modifier⟩!

The code for this is rather like the one for ⟨vector⟩s.

4381 \xydef@\DIRECTION@group#1{%
4382 \xy@@{\begingroup}\xy@@ix@{#1}\xy@@{\plainxy@\expandafter\POS\the\toks9\relax
4383 \setupDirection@\edef\next@{\endgroup \DirectionfromtheDirection@}\next@}%
4384 \DIRECTIONempty@false \xyFN@\DIRECTION@i}

Exercise 1.12: What effect is achieved by using ⟨modifier⟩s v/1pc/ and v/-1pc/?

1.4m. 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, i.e., anti-/clockwise, respectively. Note: Do not use ^^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.

4414 \xydef@\DIRECTION@i{%
4415 \ifx ^\next \DN@ ^{\xy@^{\aboveDirection@\xydashl@}%
4416 \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
4417 \else\ifx _\next \DN@ _{\xy@_{\belowDirection@\xydashl@}%
4418 \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
4419 \else\ifx :\next \DN@ :{%
4420 \xy@{:}{\enter@{\cfromthec@ \basefromthebase@ \X@p=\the\X@p \Y@p=\the\Y@p}%
4421 \X@origin=\z@ \Y@origin=\z@
4422 \X@xbase=\cosDirection\xydashl@ \Y@xbase=\sinDirection\xydashl@
4423 \X@ybase=-\Y@xbase \Y@ybase=\X@xbase}%
4424 \afterVECTORorEMPTY
4425 {\xy@@{\X@p=\z@ \Y@p=\z@ \setupDirection@ \leave@}%
4426  \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
4427 {\xy@@\leave@ \xyerror@{<vector> expected after :}{}%
4428  \DIRECTIONempty@false \xyFN@\DIRECTION@i}}%
4429 \else

Syntax  Action
⟨decor⟩  ⟶ ⟨command⟩ ⟨decor⟩  either there is a command…
| ⟨empty⟩  … or there isn’t.
⟨command⟩ ⟶ \save ⟨pos⟩  save state1.5a, then do ⟨pos⟩
| \restore  restore state1.5a saved by matcing \save
| \POS ⟨pos⟩  interpret ⟨pos⟩
| \afterPOS { ⟨decor⟩ } ⟨pos⟩  interpret ⟨pos⟩ and then perform ⟨decor⟩
| \drop ⟨object⟩  drop ⟨object⟩ as the ⟨pos⟩ * operation
| \connect ⟨object⟩  connect with ⟨object⟩ as the ⟨pos⟩ ** operation
| \relax  do nothing

| ⟨TEX commands⟩ any TEX commands1.5b and user-defined macros

that neither generates output (watch out for stray spaces!), nor changes the grouping, may be used

             | \xyverbose | \xytracing | \xyquiet tracing1.5c commands

| \xyignore {⟨pos⟩ ⟨decor⟩}  ignore1.5d XY-code
| \xycompile {⟨pos⟩ ⟨decor⟩}  compile1.5e to file ⟨prefix⟩⟨no⟩.xyc
| \xycompileto{⟨name⟩}{⟨pos⟩⟨decor⟩} compile1.5e to file ⟨name⟩.xyc

Figure 1.6: ⟨decor⟩ations.

4430 \let\next@=\afterDIRECTION@
4431 \fi\fi\fi \next@}

Exercise 1.13: What effect is achieved by using ⟨modifier⟩s v/1pc/:(1,0) and v/-1pc/__?

1.5 Decorations

4454 \message{decorations;}

⟨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 \xy… \endxy or inside {… }. The possibilities are given in figure 1.6 with notes below.

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⟩.

Simple decorations: \POS and \afterPOS have already been defined; the following are just simple applications of previously defined commands:

4531 \xydef@\drop#1#{\DN@##1{\xy@@ix@{{#1}{##1}}%
4532 \xy@{\drop#1{##1}}{\expandafter\drop@\the\toks9 }\ignorespaces}\next@}
4534 \xydef@\connect#1#{\DN@##1{\xy@@ix@{{#1}{##1}}%
4535 \xy@{\connect#1{##1}}{\expandafter\connect@\the\toks9 }\ignorespaces}\next@}
4537 \xydef@\preconnect#1#{\DN@##1{\xy@@ix@{{#1}{##1}}%
4538 \xy@{\connect#1{##1}}{\expandafter\preconnect@\the\toks9 }\ignorespaces}\next@}

Notes

1.5a. Saving and restoring allows ‘excursions’ where lots of things are added to the picture without affecting the resulting XY-pic state, i.e., c, p, and base, and without requiring matching {}s. The independence of {} is particularly useful in conjunction with the \afterPOS command, for example, the definition

   \def\ToPOS{\save\afterPOS{%
     \POS**{}?>*@2{>}**@{-}\restore};p,}

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 \xy *{A} \ToPOS +<10mm,2mm>\endxy will typeset the picture[figure: A] .

Note: Saving this way in fact uses the same state as the {} ‘grouping’, so the code p_{1},{p_{2}\save}, … {\restore} will have c = p_{1} both at the … and at the end!

4576 \xydef@\save{\relax\saveC}
4577 \xydef@\saveC{\xy@\save\save@ \POS}
4579 \xydef@\save@{\enter@{\cfromthec@ \pfromthep@ \basefromthebase@}}
4581 \xydef@\restore{\xy@\restore\leave@ \ignorespaces}

1.5b. 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 [15] for details about this!

Macros that expand to ⟨decor⟩ will always do the same, though.

TEX hackers like the author may enjoy changing the XY-pic state directly using ⟨decor⟩ of the form \xy@{⟨id⟩}{⟨code⟩}…

1.5c. \xyecho will turn on echoing of all interpreted XY-pic ⟨pos⟩ characters. Bug: Not completely implemented yet. \xyverbose will switch on a tracing of all XY-pic commands executed, with line numbers. \xytracing traces even more: the entire XY-pic state is printed after each modification. \xyquiet restores default quiet operation.

The trick is to replace the \xy@ command such that it calls the ‘normal’ one between writing out a trace message and the state.

4619 \xydef@\xyecho{%
4620 \xy@\xyecho{\let\xy@=\xyecho@ \message{\string\xyecho}}\POS}
4622 \xydef@\xyecho@#1#2{{\def\1{#1}\ifx\1\empty\else\message{\codeof\1}\fi}%
4623 \oxy@{#1}{#2}}
4625 \xydef@\xyverbose{%
4626 \xy@\xyverbose{\let\xy@=\xyverbose@
4627 \W@{Xy: \string\xyverbose\xytracelineno@}}\POS}
4629 \xydef@\xyverbose@#1#2{%
4630 {\def\1{#1}\ifx\1\empty\else\W@{Xy: \codeof\1\xytracelineno@}\fi}%
4631 \oxy@{#1}{#2}}
4633 \xydef@\xytracing{%
4634 \xy@\xytracing{\let\xy@=\xytracing@

4635 \W@{Xy TRACE: \string\xytracing\xytracelineno@}\xystatus@:}\POS}
4637 \xydef@\xytracing@#1#2{{\def\1{#1}\def\2{#2}%
4638 \W@{Xy TRACE: \codeof\1 {\codeof\2}\xytracelineno@}}\oxy@{#1}{#2}\xystatus@:}
4640 \xydef@\xystatus@#1{\xystatus@cp{#1}%
4641 \W@{#1 d=<\the\d@X,\the\d@Y>
4642  Direction=\the\Direction=\string(\cosDirection,\sinDirection\string)}%
4643 \W@{#1 base=<\the\X@origin,\the\Y@origin>+%
4644  <\the\X@xbase,\the\Y@xbase>x+<\the\X@ybase,\the\Y@ybase>y}%
4645 \W@{#1 min/max=<\the\X@min,\the\Y@min>/<\the\X@max,\the\Y@max>
4646  S=\the\csp@}}
4648 \xydef@\xystatus@cp#1{%
4649 \W@{#1 c=<\the\X@c,\the\Y@c> \expandafter\string\the\Edge@c
4650  \string[\the\L@c+\the\R@c,\the\D@c+\the\U@c\string]
4651  \ifInvisible@ I\fi\ifHidden@ H\fi}%
4652 \W@{#1 p=<\the\X@p,\the\Y@p> \expandafter\string\the\Edge@p
4653  \string[\the\L@p+\the\R@p,\the\D@p+\the\U@p\string]}}
4655 \xydef@\xystatus@c#1{%
4656 \W@{#1<\the\X@c,\the\Y@c> \expandafter\string\the\Edge@c
4657  \string[\the\L@c+\the\R@c,\the\D@c+\the\U@c\string]}}
4659 \xydef@\xyquiet{\xy@\xyquiet{\let\xy@=\oxy@}}

1.5d. Ignoring means that the ⟨pos⟩ ⟨decor⟩ is still parsed the usual way but nothing is typeset and the XY-pic state is not changed. We ignore in a group to ensure that nothing done inside ‘leaks’ to the outside.

4675 \xydef@\xyignore#1{\xy@\xyignore{\xyignore@{#1}}\ignorespaces}
4677 \xydef@\xyignore@#1{{\let\xy@=\xyeat@ \change@oxy@\xy@ \POS#1\relax}}
4679 \xydef@\xyeat@#1#2{}

1.5e. 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 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⟩}|{… } – this dumps the compiled code into the file ⟨name⟩.xyc. When many diagrams are compiled then it is easier to add \xycompile{… } 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

                                 \CompilePrefix{⟨prefix⟩}

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 AMS-L^{A}TEX equation constructs) then the declaration

                                 \CompileFixPoint{⟨id⟩}

can be used inside the environment to fix the counter to have the same value at every passage.

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.

4731 \xydef@\xycompile@@{\jobname-}
4732 \xydef@\xycompileno@@{0}
4734 \xydef@\CompilePrefix#1{%
4735 \def\xycompile@@{#1}\xdef\xycompile@@{\codeof\xycompile@@}%
4736 \xdef\xycompileno@@{0}}
4738 \xydef@\xycompile{%
4739 \count@=\xycompileno@@ \advance\count@\@ne
4740 \xdef\xycompileno@@{\ifnum10>\count@ 0\fi \the\count@}%
4741 \edef\next{\noexpand\xycompileto{\xycompile@@\xycompileno@@}}\next}
4743 \xylet@\compilename@@=\empty
4744 \xylet@\xyrecompile@@=\relax
4746 \xydef@\xycompileto#1#2{%
4747 \if\inxy@ \DN@{\xy@@{\nter@{}}}%
4748 \else \DN@{\xy \xy@@{\nter@{\endxy}}}\fi \next@
4749 \ifxysaving@ \xyerror@{Compilations can not be nested}{}\fi
4750 \DN@{#1}\edef\compilename@@{\codeof\next@}\DNii@{#2}%
4751 \def\xyrecompile@@{recompiling TRUNCATED}%
4752 \expandafter\xyinputorelse@@\expandafter{\compilename@@.xyc}%
4753 {\def\xyrecompile@@{compiling to}}%
4754 \ifx\xyrecompile@@\relax \else \expandafter\xyrecompile@ \fi
4755 \xy@@\leave@ \ignorespaces}

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.

4764 \xydef@\xyrecompile@{%
4765 \message{(\xyrecompile@@\space\string`\compilename@@.xyc\string'}%
4766 \DN@{\immediate\openout\xywrite@=}\expandafter\next@\compilename@@.xyc
4767 \immediate\write\xywrite@{%
4768 \string\xycompiled{\compilename@@}%
4769 {\the\year/\the\month/\the\day\string:\the\time\xytracelineno@}%
4770 {Xy-pic \xyversion}\xycomment@}%
4771 \immediate\write\xywrite@{{\codeof\nextii@}\relax}%
4772 {\xysaving@ \expandafter\POS\nextii@ \relax}%
4773 \immediate\write\xywrite@{\string\xyendcompiled}%
4774 \immediate\closeout\xywrite@ \message{done)}%
4775 \expandafter\input\compilename@@.xyc
4776 \outlines@@\writeoutline@\writeoutline@}
4778 \xydef@\xysaving@{\let\xy@=\xysave@ \change@oxy@\xy@
4779 \let\xy@@ix@=\xysave@@toksix@ \xysaving@true}
4781 \xynew@{if}\ifxysaving@ \xysaving@false
4783 \xydef@\xysave@#1#2{{\DN@{{#1}{#2}}%
4784 \immediate\write\xywrite@{\string\xy@\codeof\next@\xycomment@}}}

4786 \xydef@\xysave@@toksix@#1{{\DN@{{#1}}%
4787 \immediate\write\xywrite@{\string\xy@@ix@\codeof\next@\relax}}}
4789 \xywarnifdefined\xycomment@
4790 {\catcode`\%=12 \catcode`\(=1 \catcode`\)=2 \gdef\xycomment@(%)}

Hack1: 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!!

Hack2: \xysave@@toksix@ is not doing the catcode jive because it can never be invoked while loading a file (knock, knock ◯_{¨⌣}).

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:

4805 \xydef@\xycompiled#1#2#3#4{\DN@{#1}\edef\next@{\codeof\next@}%
4806 \ifx\next@\compilename@@\else
4807 \xywarning@{This file does not contain the result of
4808  \string\xycompileto{\compilename@@}{...}^^J%
4809  but of \string\xycompileto{\next@}}\fi
4810 \edef\next{Xy-pic \xyversion}\DN@{#3}\ifx\next\next@
4811 \DN@{#4}\ifx\next@\nextii@ \xycatcodes \outlines@@\relax\readoutline@
4812 \else \def\xyrecompile@@{recompiling to}\endinput \fi
4813 \else \def\xyrecompile@@{Xy-pic version change - recompiling}\endinput \fi}
4815 \xydef@\xyendcompiled{\let\xyrecompile@@=\relax \xyuncatcodes\endinput}

Finally the fix-point thing.

4821 \xydef@\CompileFixPoint#1{%
4822 \expandafter\ifx\csname#1FIX@@\endcsname\relax
4823 \expandafter\xdef\csname#1FIX@@\endcsname{\xycompileno@@}%
4824 \else
4825 \xdef\xycompileno@@{\csname#1FIX@@\endcsname}\fi}

Finally, when many ‘administrative typesetting runs’ are needed, e.g., readjusting L^{A}TEX 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 .xyd containing just the size of the picture:

                                     \MakeOutlines
                                     \OnlyOutlines
                                     \ShowOutlines
                                     \NoOutlines

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.

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’.

4860

4861 \xydef@\outlines@no#1#2{}

4862 \xydef@\outlines@make#1#2{#1}
4863 \xydef@\outlines@only#1#2{#2}
4865 \xylet@\outlines@@=\outlines@no
4866 \xylet@\writeoutline@@=\relax
4867 \xylet@\readoutline@@=\relax
4869 \xydef@\MakeOutlines{\let\outlines@@=\outlines@make}
4871 \xydef@\OnlyOutlines{\xywarning@{Compiled pictures only shown as outlines}%
4872 \let\outlines@@=\outlines@only}
4874 \xydef@\ShowOutlines{\let\readoutline@@=\typesetoutline@}
4876 \xydef@\NoOutlines{\let\outlines@@=\outlines@no}
4878 \xydef@\writeoutline@{%
4879 \DN@{\immediate\openout\xywrite@=}\expandafter\next@\compilename@@.xyd
4880 \immediate\write\xywrite@{\xycomment@\space\compilename@@.xyd}
4881 \immediate\write\xywrite@{%
4882 \string\X@min=\the\X@min \string\X@max=\the\X@max
4883 \string\Y@min=\the\Y@min \string\Y@max=\the\Y@max \string\relax}%
4884 \writeoutline@@
4885 \immediate\closeout\xywrite@}
4887 \xynew@{if}\ifoutlineread@
4889 \xydef@\readoutline@{\outlineread@true
4890 \expandafter\xyinputorelse@@\expandafter{\compilename@@.xyd}%
4891 {\def\xyrecompile@@{outline missing - recompiling to}\outlineread@false}%
4892 \ifoutlineread@ \readoutline@@
4893 \writeoutline@\expandafter\xyendcompiled\fi}
4895 \xydef@\typesetoutline@{%
4896 \xy@@{\czeroEdge@ \U@p=\z@ \D@p=\z@ \L@p=\z@ \R@p=\z@ \Edge@p={\zeroEdge}%
4897 \X@p=\X@min \Y@p=\Y@min \X@c=\X@min \Y@c=\Y@max \connect@\dir{.}%
4898 \X@p=\X@c \Y@p=\Y@c \X@c=\X@max \Y@c=\Y@max \connect@\dir{.}%
4899 \X@p=\X@c \Y@p=\Y@c \X@c=\X@max \Y@c=\Y@min \connect@\dir{.}%
4900 \X@p=\X@c \Y@p=\Y@c \X@c=\X@min \Y@c=\Y@min \connect@\dir{.}}}

1.6 Kernel object library

4915 \message{kernel objects:}

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 §1.6.1. The remaining kernel library objects are circles of §1.6.2 and text of §1.6.3.

1.6.1 Directionals

4933 \message{directionals,}

The kernel provides a selection of directionals: objects that depend on the current direction. They all take the form

\dir⟨dir⟩

to typeset a particular ⟨dir⟩ectional object. All have the structure

⟨dir⟩ ⟶ ⟨variant⟩{⟨main⟩}

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.

Figure 1.7 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 ◯ to a (typeset by **\dir⟨dir⟩) and as a tip at the end of a dotted connection of the same variant (i.e., 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 \object.

Setup: \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 §1.8.3.

5035 \xydef@\dir{\hbox\bgroup\xyFN@\dir@i}
5037 \xydef@\dir@i{\ifx *\next \DN@*{\resetStyle@\object@}%
5038 \else \let\next@=\dir@ii \fi \next@}
5040 \xydef@\dir@ii#1#{\dir@{#1}}
5042 \xydef@\dir@#1#2{\DN@{dir#1{#2}}%
5043 \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
5044 \ifx\next\relax \DN@{dir{#2}}%
5045 \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
5046 \ifx\next\relax \DN@{\dir#1{#2}}%
5047 \xyerror@{illegal <dir>: \codeof\next@\space not defined}{}%
5048 \let\next=\no@ \fi\fi \next}

Notes

1.6a. 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, e.g., making the ? ⟨pos⟩ able to find a point on the straight line from p to c without actually typesetting anything.

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:

5070 \xydefcsname@{dir{}}{\no@}
5072 \xyletcsnamecsname@{dir0{}}{dir{}}
5073 \xyletcsnamecsname@{dir1{}}{dir{}}
5074 \xyletcsnamecsname@{dir^{}}{dir{}}
5075 \xyletcsnamecsname@{dir_{}}{dir{}}

72 CHAPTER 1. KERNEL: XY.DOC

Dummy1.6a

                                    \dir{}

Plain connectors1.6b

   [figure: \dir{-}; \dir2{-}; \dir3{-}]
   [figure: \dir{.}; \dir2{.}; \dir3{.}]
   [figure: \dir{~}; \dir2{~}; \dir3{~}]
  [figure: \dir{--}; \dir2{--}; \dir3{--}]
  [figure: \dir{~~}; \dir2{~~}; \dir3{~~}]

Plain tips1.6c

[figure: \dir{>}; \dir^{>}; \dir_{>}; \dir2{>}; \dir3{>}]
[figure: \dir{<}; \dir^{<}; \dir_{<}; \dir2{<}; \dir3{<}]
[figure: \dir{|}; \dir^{|}; \dir_{|}; \dir2{|}; \dir3{|}]
[figure: \dir{(}; \dir^{(}; \dir_{(}]
[figure: \dir{)}; \dir^{)}; \dir_{)}]
               [figure: \dir^{`}; \dir_{`}]
               [figure: \dir^{'}; \dir_{'}]

Constructed tips1.6d

[figure: \dir{>>}; \dir^{>>}; \dir_{>>}; \dir2{>>}; \dir3{>>}]
[figure: \dir{<<}; \dir^{<<}; \dir_{<<}; \dir2{<<}; \dir3{<<}]
[figure: \dir{||}; \dir^{||}; \dir_{||}; \dir2{||}; \dir3{||}]
[figure: \dir{|-}; \dir^{|-}; \dir_{|-}; \dir2{|-}; \dir3{|-}]
[figure: \dir{>|}; \dir{>>|}; \dir{|<}; \dir{|<<}; \dir{*}; •]
 [figure: \dir{+}; \dir{x}; \dir{/}; \dir{//}; \dir{o}; ∘]

Figure 1.7: Kernel library ⟨dir⟩ectionals

5076 \xyletcsnamecsname@{dir2{}}{dir{}}
5077 \xyletcsnamecsname@{dir3{}}{dir{}}
5079 \xyletcsnamecsname@{dir{ }}{dir{}}
5081 \xydef@\no@{\egroup \czeroEdge@ %\Invisible@false \Hidden@false %%%%HACK?
5082 \def\Leftness@{.5}\def\Upness@{.5}%
5083 \def\Drop@@{\setbox\z@=\copy\voidb@x}\def\Connect@@{\no@@}}

1.6b. The plain connectors group contains basic directionals that lend themself to simple connections.

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.

Lines: A single \dir{-} object is a dash in the current direction: build box with character C of the semidirectional \xydashfont; use the characters natural width w and construct a height/depth from d = |sin(\Direction)| em (where 1em is the dash length, cf. xydash10.mf) as follows:

\begin{matrix}C & L & R & D & U & flip if \\ 0 … 30 & 0 & w & 0 & d & dY < 0 \\ 31 … 63 & 0 & w & d & 0 & dY > 0 \\ 64 … 95 & 0 & w & d & 0 & dX < 0 \\ 96 … 127 & 0 & w & 0 & d & dX < 0 \end{matrix}

where flip means shift the box opposite vertically and horizontally, i.e., (L, R, D, U) := (R, L, U, D), and then lower the box D − U.

Procedure: (l.5132) Compute d, (l.5133) set D, U, and flip condition, (l.5137) build box to get w, L, R, (l.5139) dump box that is flipped if condition holds, and (l.5148) finally setup the required parameters properly.

5125 \xydefcsname@{dir1{-}}{\line@}
5126 \xydefcsname@{dir2{-}}{\line@ \double@\xydashh@}
5127 \xydefcsname@{dir3{-}}{\line@ \triple@\xydashh@}
5128 \xyletcsnamecsname@{dir0{-}}{dir{}}
5129 \xyletcsnamecsname@{dir{-}}{dir1{-}}
5130 \xyletcsnamecsname@{dir{=}}{dir2{-}}
5132 \xydef@\line@{\dimen@=\sd@Y\sinDirection\xydashl@
5133 \ifnum\SemiDirectionChar<31 \D@c=\z@ \U@c=\dimen@ \DN@{\d@Y<\z@}%
5134 \else\ifnum\SemiDirectionChar<64 \D@c=\dimen@ \U@c=\z@ \DN@{\z@<\d@Y}%
5135 \else\ifnum\SemiDirectionChar<96 \D@c=\dimen@ \U@c=\z@ \DN@{\d@X<\z@}%
5136 \else \D@c=\z@ \U@c=\dimen@ \DN@{\d@X<\z@}\fi\fi\fi
5137 \setboxz@h{\line@@}\ht\z@=\U@c \dp\z@=\D@c
5138 \L@c=\z@ \R@c=\wdz@
5139 \ifdim\next@ \dimen@=\R@c \R@c=\L@c \L@c=\dimen@
5140 \dimen@=\U@c \U@c=\D@c \D@c=\dimen@ \advance\dimen@-\U@c
5141 \lower\dimen@\boxz@
5142 \else \boxz@ \fi

5143 %

5144 %\ifnum\SemiDirectionChar=31\relax
5145 % \W@{LINE@(\the\SemiDirectionChar): WH=<\the\L@c+\the\R@c,\the\D@c+\the\U@c>;
5146 %       d=<\the\d@X,\the\d@Y>}\fi

5148 \edef\tmp@{\egroup \U@c=\the\U@c \D@c=\the\D@c \L@c=\the\L@c \R@c=\the\R@c}%
5149 \tmp@
5150 \Edge@c={\rectangleEdge}%%%%%\Invisible@false\Hidden@false
5151 \ifdim\z@<\U@c \def\Upness@{1}\else \def\Upness@{0}\fi
5152 \ifdim\z@<\L@c \def\Leftness@{1}\else \def\Leftness@{0}\fi
5153 \def\Drop@@{\styledboxz@}\def\Connect@@{\solid@}}
5155 \xydef@\line@@{{\xydashfont\SemiDirectionChar\/}}

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.

5166 \xydef@\solid@{%

5167 %

5168 %\W@{SOLID}\xystatus@:%

5169 %

5170 \checkXy@rules@\solidhrule@\solidvrule@{\straight@\solidSpread@}}
5172 \xydef@\checkXy@rules@#1#2#3{%
5173 \dimen@=\Y@c \advance\dimen@-\Y@p
5174 \ifjusthvtest@.05pt>\ifdim\dimen@<\z@-\fi\dimen@ \DN@{#1}%
5175 \else \dimen@=\X@c \advance\dimen@-\X@p
5176 \ifjusthvtest@.05pt>\ifdim\dimen@<\z@-\fi\dimen@ \DN@{#2}%
5177 \else \DN@{#3}\fi\fi \next@}

Finally, we give the algorithm for ‘spreading’ the dashes along a solid line: just add an extra dash so they always overlap (see §1.8.3 for a proper defintion of the requirements to spreading).

5186 \xydef@\solidSpread@{\ifnum\z@<\count@@ \advance\count@@\@ne \fi}

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

                                       \NoRules
                                       \UseRules

that will switch the use of such off and on.

They simply redefine the conditional used to select typesetting with rules in \solid@ above:

5212 \xylet@\ifjusthvtest@=\ifdim
5214 \xydef@\NoRules{\let\ifjusthvtest@=\iffalse}
5215 \xydef@\UseRules{\let\ifjusthvtest@=\ifdim}

The actual typesetting essentially means calling \drop@ to box with a rule of the appropriate length and with line width set to that of \xydashfont (as stored in \xydashw@).

5223 \xydef@\solidvrule@{\no@@ \solidvrule@typeset \ifHidden@\else\noinsert@\fi
5224 \solidvrule@pre}
5226 \xydef@\solidvrule@pre{%

5227 %

5228 %\W@{VRULE SETUP}%

5229 %

5230 \def\Cbreak@@{%

5231 %

5232 %\W@{VRULE Cbreak}%

5233 %

5234 \connectRestore@ \swap@\lastbreak@@\swap@
5235 \solidvrule@typeset \edef\lastbreak@@{\cfromthec@}\Creset@@}%
5236 \def\Clast@@{%

5237 %

5238 %\W@{VRULE Clast}%
5239 %\let\Clast@@=\undefined

5240 %

5241 \connectRestore@ \Creset@@\swap@\lastbreak@@\swap@
5242 \solidvrule@typeset \Creset@@ \edef\lastbreak@@{\cfromthep@}}%

5243 }

5245 \xydef@\solidvrule@typeset{%

5246 %

5247 %\W@{VRULE TYPESET}\xystatus@cp:%

5248 %

5249 \ifInvisible@ \let\next@=\relax \else \let\next@=\solidvrule@typeset@ \fi
5250 \checkoverlap@@ \next@}
5252 \xydef@\solidvrule@typeset@{{%

5253 %

5254 \advance\X@c\X@p \X@c=.5\X@c \X@p=\X@c
5255 \advance\X@c-.5\xydashw@ \advance\X@p.5\xydashw@

5256 %

5257 \ifdim\Y@c<\Y@p \advance\Y@c\U@c \advance\Y@p-\D@p
5258 \else \swapdimen@\Y@c\Y@p \advance\Y@c\U@p \advance\Y@p-\D@c \fi

5259 %

5260 \Droprule@}}
5262 \xydef@\solidhrule@{\no@@ \solidhrule@typeset \ifHidden@\else\noinsert@\fi
5263 \solidhrule@pre}
5265 \xydef@\solidhrule@pre{%

5266 %

5267 %\W@{HRULE SETUP}%

5268 %

5269 \def\Cbreak@@{%

5270 %

5271 %\W@{HRULE Cbreak}%

5272 %

5273 \connectRestore@ \swap@\lastbreak@@\swap@
5274 \solidhrule@typeset \edef\lastbreak@@{\cfromthec@}\Creset@@}%
5275 \def\Clast@@{%

5276 %

5277 %\W@{HRULE Clast}%
5278 %\let\Clast@@=\undefined

5279 %

5280 \connectRestore@ \Creset@@\swap@\lastbreak@@\swap@

5281 \solidhrule@typeset \Creset@@ \edef\lastbreak@@{\cfromthep@}}%

5282 }

5284 \xydef@\solidhrule@typeset{%

5285 %

5286 %\W@{HRULE TYPESET}\xystatus@cp:%

5287 %

5288 \ifInvisible@ \let\next@=\relax \else \let\next@=\solidhrule@typeset@ \fi
5289 \checkoverlap@@ \next@}
5291 \xydef@\solidhrule@typeset@{{%
5292 \ifdim\X@c<\X@p \advance\X@c\R@c \advance\X@p-\L@p
5293 \else \swapdimen@\X@c\X@p \advance\X@c\R@p \advance\X@p-\L@c \fi
5294 \advance\Y@c\Y@p \Y@c=.5\Y@c \Y@p=\Y@c
5295 \advance\Y@c-.5\xydashw@ \advance\Y@p.5\xydashw@
5296 \Droprule@}}

\Droprule@ puts the actual ink on the page: with lower left corner at c and upper right corner at p.

5303 \xydef@\Droprule@{\advance\X@p-\X@c

5304 %

5305 %\W@{: kern\the\X@c\space width\the\X@p\space depth-\the\Y@c\space
5306 %       height\the\Y@p}%

5307 %

5308 \setboxz@h{\kern\X@c \vrule width\X@p depth-\Y@c height\Y@p}%
5309 \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ \Drop@@}

Dots: \dir{.} creates a very boring dot when used as an ⟨object⟩, but interesting dotted lines when used to connect. \zerodot should expand to a zero-sized box with a dot (initialised to use \zerodotbox@); the ⟨object⟩ is built using \pointlike@ ⟨text⟩ ⟨spread-dimen⟩ that we will use again later.

5321 \xydef@\zerodot{\copy\zerodotbox@}
5323 \xydefcsname@{dir1{.}}{\point@}
5324 \xydefcsname@{dir2{.}}{\point@ \double@\xydashh@}
5325 \xydefcsname@{dir3{.}}{\point@ \triple@\xydashh@}
5326 \xyletcsnamecsname@{dir0{.}}{dir{}}
5327 \xyletcsnamecsname@{dir{.}}{dir1{.}}
5328 \xyletcsnamecsname@{dir{:}}{dir2{.}}
5330 \xydef@\point@{\pointlike@\zerodot\p@}
5332 \xydef@\pointlike@#1#2{%
5333 \setboxz@h{#1}\wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@\egroup
5334 % \Invisible@false \Hidden@false
5335 \def\Leftness@{.5}\def\Upness@{.5}\ctipEdge@
5336 \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@{\dottedSpread@{#2}}}}

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

l.5366  A := |cos \Direction| × radius

B := |sin \Direction| × radius

l.5369  if A + B > |\d@X| + |\d@Y| then N = 0 and exit
l.5374  <A,B> := 2 × <A,B>

Filler := ⟨box with the original filler centered...⟩

                 l.5377 <\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>

l.5379 N := ⌊if |\d@X| > |\d@Y| then |\d@X| /Aelse |\d@Y| /B⌋ + 1

as realised below:

5366 \xydef@\dottedSpread@#1{%\setupDirection@
5367 \dimen@=#1\relax \DN@{\A@=2\A@ \B@=2\B@ \dottedSpread@i}%
5368 \A@=\sd@X\cosDirection\dimen@ \B@=\sd@Y\sinDirection\dimen@
5369 \dimen@=\A@ \advance\dimen@\B@
5370 \dimen@ii=\sd@X\d@X \advance\dimen@ii\sd@Y\d@Y
5371 \ifdim\dimen@>\dimen@ii \DN@{\count@@=\z@}\fi
5372 \next@}
5374 \xydef@\dottedSpread@i{%\setupDirection@
5375 \global\setbox8=\hbox to\A@{\hss
5376 \kern.5\A@\box\lastobjectbox@\kern.5\A@\hss}\dp8=.5\B@ \ht8=.5\B@
5377 \advance\d@X\sd@X\A@ \advance\d@Y\sd@Y\B@
5378 \advance\X@c\sd@X.5\A@ \advance\Y@c\sd@Y.5\B@
5379 \ifdim\sd@Y\d@Y<\sd@X\d@X \dimen@=\sd@X\d@X
5380 \ifdim\zz@\A@\else \divide\dimen@\A@ \fi \count@@=\dimen@
5381 \else \dimen@=\sd@Y\d@Y
5382 \ifdim\zz@\B@\else \divide\dimen@\B@ \fi \count@@=\dimen@
5383 \fi \advance\count@@\@ne}

A particular aspect of this is that we have to enlarge and recenter the actual box used for the

   typesetting (\lastobjectbox@).

Squiggles: These are just a lot of box maneuvering using the directional characters of \xybsqlfont (see xybsql10.mf for details):

5396 \xydefcsname@{dir1{~}}{\squiggle@}
5397 \xydefcsname@{dir2{~}}{\squiggle@ \double@\xybsqlh@}
5398 \xydefcsname@{dir3{~}}{\squiggle@ \triple@\xybsqlh@}
5399 \xyletcsnamecsname@{dir0{~}}{dir{}}
5400 \xyletcsnamecsname@{dir{~}}{dir1{~}}
5402 \xydef@\squiggle@{\xybsqlfont
5403 \dimen@=\sd@X\cosDirection\xybsqll@ \advance\dimen@.1\p@
5404 \dimen@ii=\sd@Y\sinDirection\xybsqll@
5405 \kern\dimen@\squiggle@@
5406 \edef\tmp@{\egroup \U@c=\the\dimen@ii \L@c=\the\dimen@}\tmp@
5407 \wdz@=2\L@c \R@c=\L@c \ht\z@=\U@c  \D@c=\U@c \dp\z@=\U@c
5408 \Edge@c={\rectangleEdge}%
5409 % \Invisible@false \Hidden@false
5410 \def\Leftness@{.5}\def\Upness@{.5}%

5411 \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@\squiggledSpread@}}
5413 \xydef@\squiggle@@{\DirectionChar \count@=\DirectionChar
5414 \advance\count@-64 \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}

The interesting bit is that they spread by not spreading, i.e., by centering between the endpoints— this means

X := X − d/2, dX := dX − d where d = \sd@X(|dX| − N × A + .1pt)
Y := Y − d/2, dY := dY − d where d = \sd@Y(|dY | − N × B + .1pt)

5429 \xydef@\squiggledSpread@{%
5430 \dimen@=\d@X \advance\dimen@-\sd@X\count@@\A@ \advance\dimen@\sd@X.3\p@
5431 \advance\X@c-.5\dimen@ \advance\d@X-\dimen@
5432 \dimen@=\d@Y \advance\dimen@-\sd@Y\count@@\B@ \advance\dimen@\sd@Y.3\p@
5433 \advance\Y@c-.5\dimen@ \advance\d@Y-\dimen@}

Double and triple directionals: 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{--}.

This is very simple, really: \double@ and \triple@ do the work by redefining the \Drop@@ method to do its job twice and thrice. To Do: should probably extend any already defined \Drop@@ method?

5455 %\xydef@\double@#1{\edef\Drop@@{\dimen@=#1\relax
5456 %  \dimen@=.5\dimen@ \A@=-\sinDirection\dimen@ \B@=\cosDirection\dimen@
5457 %  \setbox2=\hbox{\kern\A@\raise\B@\copy\z@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 %
5458 %  \setbox2=\hbox{\kern-\A@\raise-\B@\boxz@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 }}
5460 %\xydef@\triple@#1{\edef\Drop@@{\dimen@=#1\relax
5461 %  \A@=-\sinDirection\dimen@ \B@=\cosDirection\dimen@
5462 %  \setbox2=\hbox{\kern\A@\raise\B@\copy\z@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 %
5463 %  \setbox2=\hbox{\kern-\A@\raise-\B@\copy\z@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2
5464 %  \dp\z@=\z@ \ht\z@=\z@ \wdz@=\z@ \boxz@}}
5466 \xydef@\double@#1{\edef\Drop@@{\dimen@=#1\relax
5467 \dimen@=.5\dimen@ \A@=-\sinDirection\dimen@ \B@=\cosDirection\dimen@
5468 \setboxz@h{\setbox2=\hbox{\kern\A@\raise\B@\copy\z@}%
5469 \dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 %
5470 \setbox2=\hbox{\kern-\A@\raise-\B@ \noexpand\boxz@}%
5471 \dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 }%
5472 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \noexpand\styledboxz@}}
5474 \xydef@\triple@#1{\edef\Drop@@{\dimen@=#1\relax
5475 \A@=-\sinDirection\dimen@ \B@=\cosDirection\dimen@
5476 \setboxz@h{\setbox2=\hbox{\kern\A@\raise\B@\copy\z@}%
5477 \dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 %
5478 \setbox2=\hbox{\kern-\A@\raise-\B@\copy\z@}%
5479 \dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 %
5480 \dp\z@=\z@ \ht\z@=\z@ \wdz@=\z@ \noexpand\boxz@}%
5481 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \noexpand\styledboxz@}}

Dashing directionals: First traditional dashing:

5491 \xydefcsname@{dir1{--}}{\dash@}
5492 \xydefcsname@{dir2{--}}{\dash@ \double@\xydashh@}
5493 \xydefcsname@{dir3{--}}{\dash@ \triple@\xydashh@}
5494 \xyletcsnamecsname@{dir0{--}}{dir{}}
5495 \xyletcsnamecsname@{dir{--}}{dir1{--}}
5496 \xyletcsnamecsname@{dir{==}}{dir2{--}}
5498 \xydef@\dash@{\line@ \wdz@=2\wdz@ \ht\z@=2\ht\z@ \dp\z@=2\dp\z@
5499 \multiply\D@c\tw@ \multiply\U@c\tw@ \multiply\L@c\tw@ \multiply\R@c\tw@
5500 \def\Connect@@{\straight@\dashedSpread@}}

Since the dashes should reach the endpoints we do this:

if N > 0 then N := N + 1
dX := dX + d/2 where d = \sd@XA
dY := dY + d/2 where d = \sd@YB
if dX > 0 then X := X + A/2
Y := Y + \sd@YA/2

5514 \xydef@\dashedSpread@{\ifnum\z@<\count@@ \advance\count@@\@ne \fi
5515 \advance\d@X\sd@X.5\A@ \advance\d@Y\sd@Y.5\B@
5516 \ifdim\z@<\d@X \advance\X@c.5\A@ \fi \advance\Y@c\sd@Y.5\B@}

Dashed dashing of squiggled lines are simpler since squiggles are symmetric:

5523 \xydefcsname@{dir1{~~}}{\dashsquiggle@}
5524 \xydefcsname@{dir2{~~}}{\dashsquiggle@ \double@\xybsqlh@}
5525 \xydefcsname@{dir3{~~}}{\dashsquiggle@ \triple@\xybsqlh@}
5526 \xyletcsnamecsname@{dir0{~~}}{dir{}}
5527 \xyletcsnamecsname@{dir{~~}}{dir1{~~}}
5529 \xydef@\dashsquiggle@{\squiggle@
5530 \multiply\D@c\tw@ \multiply\U@c\tw@ \multiply\L@c\tw@ \multiply\R@c\tw@
5531 \dimen@=\L@c \advance\dimen@\R@c \wdz@=\dimen@ \ht\z@=\U@c \dp\z@=\D@c
5532 \def\Connect@@{\straight@\dashsquiggledSpread@}}

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:

5540 \xydef@\dashsquiggledSpread@{\ifnum\z@<\count@@ \advance\count@@\@ne \fi
5541 \advance\X@c.5\A@ \advance\d@X.5\A@ \advance\Y@c.25\B@ \advance\d@Y.5\B@}

Finally “dashed dotting” synonyms:

5547 \xyletcsnamecsname@{dir1{..}}{dir{.}}
5548 \xyletcsnamecsname@{dir2{..}}{dir2{.}}
5549 \xyletcsnamecsname@{dir3{..}}{dir3{.}}
5550 \xyletcsnamecsname@{dir{..}}{dir1{.}}
5551 \xyletcsnamecsname@{dir{::}}{dir2{.}}

1.6c. 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. e.g., **@{>} typesets

[figure]

Exercise 1.14: Typeset the following two +s and a tilted square:

[figure: +; +]

Hint: the dash created by \dir{-} has the length 5pt (here).

5595 \xylet@\ctipEdge@=\czeroEdge@

To Do: 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, e.g., ‘arrow’).

Arrow heads: The ones intended for single connections are just characters from \xyatipfont

   and \xybtipfont.

5608 \xydefcsname@{dir1{>}}{\tip@}
5609 \xydefcsname@{dir^{>}}{\atip@}
5610 \xydefcsname@{dir_{>}}{\btip@}
5611 \xyletcsnamecsname@{dir0{>}}{dir{}}
5612 \xyletcsnamecsname@{dir{>}}{dir1{>}}
5614 \xydefcsname@{dir1{<}}{\reverseDirection@\tip@}
5615 \xydefcsname@{dir^{<}}{\reverseDirection@\btip@}
5616 \xydefcsname@{dir_{<}}{\reverseDirection@\atip@}
5617 \xyletcsnamecsname@{dir0{<}}{dir{}}
5618 \xyletcsnamecsname@{dir{<}}{dir1{<}}
5620 \xydef@\tip@{\tip@x\tip@@}
5621 \xydef@\atip@{\tip@x\atip@@}
5622 \xydef@\btip@{\tip@x\btip@@}
5624 \xydef@\tip@x#1{#1\egroup
5625 \ctipEdge@ %\Invisible@false \Hidden@false
5626 \def\Leftness@{.5}\def\Upness@{.5}%
5627 \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
5629 \xydef@\tip@@{\atip@@\btip@@}
5630 \xydef@\atip@@{\xyatipfont\DirectionChar}
5631 \xydef@\btip@@{\xybtipfont\DirectionChar}

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 \DirectionChar; maybe this should be

   using \vDirection@?

5641 \xydefcsname@{dir2{>}}{\Tip@}
5642 \xydefcsname@{dir2{<}}{\reverseDirection@\Tip@}
5644 \xydef@\Tip@{\kern2.5pt \vrule height2.5pt depth2.5pt width\z@
5645 \Tip@@ \kern2.5pt \egroup

5646 \U@c=2.5pt \D@c=2.5pt \L@c=2.5pt \R@c=2.5pt \Edge@c={\circleEdge}%
5647 % \Invisible@false \Hidden@false
5648 \def\Leftness@{.5}\def\Upness@{.5}%
5649 \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
5651 \xydef@\Tip@@{\count@=\DirectionChar
5652 \advance\count@-4 \ifnum\count@<\z@ \advance\count@128 \fi
5653 \xyatipfont\char\count@
5654 \advance\count@ 8 \ifnum127<\count@ \advance\count@-128 \fi
5655 \xybtipfont\char\count@}
5657 \xydefcsname@{dir3{>}}{\Ttip@}
5658 \xydefcsname@{dir3{<}}{\composite@{}{:(-1,0)\dir3{>}}}
5660 \xydef@\Ttip@{\kern3.2pt \vrule height3.2pt depth3.2pt width\z@
5661 \Ttip@@ \kern3.2pt \egroup
5662 \U@c=3.2pt \D@c=3.2pt \L@c=3.2pt \R@c=3.2pt \Edge@c={\circleEdge}%
5663 % \Invisible@false \Hidden@false
5664 \def\Leftness@{.5}\def\Upness@{.5}%
5665 \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
5667 \xydef@\Ttip@@{%
5668 \setboxz@h\bgroup\reverseDirection@\line@ \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@
5669 \kern-\L@c \boxz@ \kern\L@c
5670 {\vDirection@(1,-.31)\xydashl@ \xyatipfont\char\DirectionChar}%
5671 {\vDirection@(1,+.31)\xydashl@ \xybtipfont\char\DirectionChar}}

Stopper: \dir{|} makes a ‘stopper’ using just the appropriate \xydashfont character rotated 90^{∘} and centered; the ^and _variants are just shifted appropriately and two are used to make the 2 and 3 variants longer.

5682 \xydefcsname@{dir1{|}}{\stopper@}
5683 \xydefcsname@{dir^{|}}{\aboveDirection@\xydashl@
5684 \shiftdir@\line@\z@ \pointlike@{}\xydashh@}
5685 \xydefcsname@{dir_{|}}{\belowDirection@\xydashl@
5686 \shiftdir@\line@\z@ \pointlike@{}\xydashh@}
5687 \xydefcsname@{dir2{|}}{\stopper@ \double@\xydashh@}
5688 \xydefcsname@{dir3{|}}{\stopper@ \double@{2\xydashh@}}
5690 \xyletcsnamecsname@{dir0{|}}{dir{}}
5691 \xyletcsnamecsname@{dir{|}}{dir1{|}}
5693 \xydef@\stopper@{\tip@x\stopper@@}
5695 \xydef@\stopper@@{\setboxz@h{\count@=\SemiDirectionChar \advance\count@64 %
5696 \ifnum127<\count@ \advance\count@-128 \fi \xydashfont\char\count@\/}%
5697 \setboxz@h{\kern-.5\wdz@ \dimen@=\sd@Y\cosDirection\xydashl@
5698 \ifnum\SemiDirectionChar=95 \dimen@=\sd@X\sd@Y\dimen@ \fi
5699 \raise.5\dimen@\boxz@}%
5700 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}

Hooks: These are halfcircles opening towards or opposite \Direction and fastened by their center or either endpoint. Build by lots of box manipulation with the \xybsqlfont quarter

circles… ◯_{¨⌣}

5710 \xydefcsname@{dir1{(}}{\hook@}
5711 \xydefcsname@{dir^{(}}{\ahook@}
5712 \xydefcsname@{dir_{(}}{\bhook@}
5713 \xyletcsnamecsname@{dir0{(}}{dir{}}
5714 \xyletcsnamecsname@{dir{(}}{dir1{(}}
5716 \xydefcsname@{dir1{)}}{\reverseDirection@\hook@}
5717 \xydefcsname@{dir^{)}}{\reverseDirection@\bhook@}
5718 \xydefcsname@{dir_{)}}{\reverseDirection@\ahook@}
5719 \xyletcsnamecsname@{dir0{)}}{dir{}}
5720 \xyletcsnamecsname@{dir{)}}{dir1{)}}
5722 \xydef@\hook@{\tip@x\hook@@}
5723 \xydef@\hook@@{\setboxz@h{\xybsqlfont
5724 \vDirection@(1,-1){.707107\xybsqll@}%
5725 \hbox{\DirectionChar
5726 \kern-\d@Y\raise\d@X\hbox{\count@=\DirectionChar \advance\count@-32 %
5727  \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}}}%
5728 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
5730 \xydef@\ahook@{\tip@x\ahook@@}
5731 \xydef@\ahook@@{\setboxz@h{\xybsqlfont
5732 \vDirection@(1,-1){.707107\xybsqll@}\kern-\d@X
5733 \lower\d@Y\hbox{\DirectionChar
5734 \kern-\d@Y\raise\d@X\hbox{\count@=\DirectionChar \advance\count@-32 %
5735  \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}}}%
5736 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
5738 \xydef@\bhook@{\tip@x\bhook@@}
5739 \xydef@\bhook@@{\setboxz@h{\xybsqlfont
5740 \vDirection@(-1,-1){.707107\xybsqll@}\DirectionChar
5741 \kern\d@X\raise\d@Y\hbox{\count@=\DirectionChar \advance\count@-96 %
5742 \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}}%
5743 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}

Quarter turns: These are quarter circles fastened by their start or end point in \Direction. Build by box manipulation of the \xybsqlfont quarter circles. The intention is that the `' directionals are half the corresponding () directional.

5754 \xydefcsname@{dir^{'}}{\reverseDirection@\bturn@}
5755 \xydefcsname@{dir_{'}}{\reverseDirection@\aturn@}
5757 \xydefcsname@{dir^{`}}{\aturn@}
5758 \xydefcsname@{dir_{`}}{\bturn@}
5760 \xydef@\aturn@{\tip@x\aturn@@}
5761 \xydef@\aturn@@{\setboxz@h{\xybsqlfont
5762 \vDirection@(1,-1){.707107\xybsqll@}\kern-\d@X
5763 \lower\d@Y\hbox{\DirectionChar}}%
5764 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
5766 \xydef@\bturn@{\tip@x\bturn@@}

5767 \xydef@\bturn@@{\setboxz@h{\xybsqlfont
5768 \vDirection@(-1,-1){.707107\xybsqll@}\DirectionChar}%
5769 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}

1.6d. These tips are combinations of the plain tips provided for convenience (and optimised for efficiency). New ones can be constructed using \composite and by declarations of the form

\newdir ⟨dir⟩ {⟨composite⟩}

which defines \dir⟨dir⟩ as the ⟨composite⟩ (see note 1.4d for the details).

\newdir is simple:

5795 \xydef@\newdir#1#{\newdir@{#1}}
5797 \xydef@\newdir@#1#2#3{\xydefcsname@{dir#1{#2}}{\composite@{}{#3}}}

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{.

5810 \xydef@\shiftdir@#1#2{%
5811 \setbox\z@=\hbox\bgroup#1\relax
5812 \setboxz@h{\dimen@ii=#2\relax
5813 \dimen@=-\cosDirection\dimen@ii \advance\dimen@-\L@c
5814 \kern\dimen@ \lower\sinDirection\dimen@ii\boxz@}%
5815 \wdz@\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}

Then the tips, with the \tipjot@ hook allowing changing the spacing of tips used for single lines.

5822 \xylet@\tipjot@=\jot
5824 \xydefcsname@{dir1{>>}}{\shiftdir@\tip@\tipjot@ \tip@}
5825 \xydefcsname@{dir^{>>}}{\shiftdir@\atip@\tipjot@ \atip@}
5826 \xydefcsname@{dir_{>>}}{\shiftdir@\btip@\tipjot@ \btip@}
5827 \xydefcsname@{dir2{>>}}{\composite@{}{h!/\tipjot@/\dir2{>}*\dir2{>}}}
5828 \xydefcsname@{dir3{>>}}{\composite@{}{h!/\tipjot@/\dir3{>}*\dir3{>}}}
5829 \xyletcsnamecsname@{dir0{>>}}{dir{}}
5830 \xyletcsnamecsname@{dir{>>}}{dir1{>>}}
5832 \xydefcsname@{dir1{<<}}{\reverseDirection@ \shiftdir@\tip@\tipjot@ \tip@}
5833 \xydefcsname@{dir^{<<}}{\reverseDirection@ \shiftdir@\btip@\tipjot@ \btip@}
5834 \xydefcsname@{dir_{<<}}{\reverseDirection@ \shiftdir@\atip@\tipjot@ \atip@}
5835 \xydefcsname@{dir2{<<}}{\composite@{}{h!/-\tipjot@/\dir2{<}*\dir2{<}}}
5836 \xydefcsname@{dir3{<<}}{\composite@{}{h!/-\tipjot@/\dir3{<}*\dir3{<}}}
5837 \xyletcsnamecsname@{dir0{<<}}{dir{}}
5838 \xyletcsnamecsname@{dir{<<}}{dir1{<<}}
5840 \xydefcsname@{dir1{||}}{\shiftdir@\stopper@\xydashh@ \shiftdir@\stopper@\z@
5841 \pointlike@{}\jot}
5842 \xydefcsname@{dir^{||}}{\shiftdir@{\aboveDirection@\xydashl@\line@}\xydashh@
5843 \shiftdir@{\aboveDirection@\xydashl@\line@}\z@ \pointlike@{}\jot}

5844 \xydefcsname@{dir_{||}}{\shiftdir@{\belowDirection@\xydashl@\line@}\xydashh@
5845 \shiftdir@{\belowDirection@\xydashl@\line@}\z@ \pointlike@{}\jot}
5846 \xydefcsname@{dir2{||}}{\shiftdir@\stopper@\xydashh@ \shiftdir@\stopper@\z@
5847 \pointlike@{}\jot \double@\xydashh@}
5848 \xydefcsname@{dir3{||}}{\shiftdir@\stopper@\xydashh@ \shiftdir@\stopper@\z@
5849 \pointlike@{}\jot \double@{2\xydashh@}}
5850 \xyletcsnamecsname@{dir0{||}}{dir{}}
5851 \xyletcsnamecsname@{dir{||}}{dir1{||}}
5853 \xydefcsname@{dir1{>|}}{\shiftdir@\stopper@\z@ \tip@}
5854 \xydefcsname@{dir2{>|}}{\composite@{}{\dir2{>}*\dir2{|}}}
5855 \xydefcsname@{dir3{>|}}{\composite@{}{\dir3{>}*\dir3{|}}}
5856 \xyletcsnamecsname@{dir0{>|}}{dir{}}
5857 \xyletcsnamecsname@{dir{>|}}{dir1{>|}}
5859 \xydefcsname@{dir1{>>|}}{\shiftdir@\stopper@\z@ \shiftdir@\tip@\tipjot@ \tip@}
5860 \xydefcsname@{dir2{>>|}}{\composite@{}{h!/\tipjot@/\dir2{>}*\dir2{>}*\dir2{|}}}
5861 \xydefcsname@{dir3{>>|}}{\composite@{}{h!/\tipjot@/\dir3{>}*\dir3{>}*\dir3{|}}}
5862 \xyletcsnamecsname@{dir0{>>|}}{dir{}}
5863 \xyletcsnamecsname@{dir{>>|}}{dir1{>>|}}
5865 \xydefcsname@{dir1{|<}}{\reverseDirection@ \shiftdir@\stopper@\z@ \tip@}
5866 \xydefcsname@{dir2{|<}}{\reverseDirection@ \shiftdir@\stopper@\z@ \Tip@}
5867 \xydefcsname@{dir3{|<}}{\reverseDirection@ \shiftdir@\stopper@\z@ \Ttip@}
5868 \xyletcsnamecsname@{dir0{|<}}{dir{}}
5869 \xyletcsnamecsname@{dir{|<}}{dir1{|<}}
5871 \xydefcsname@{dir1{|<<}}{\reverseDirection@
5872 \shiftdir@\stopper@\z@ \shiftdir@\tip@\tipjot@ \tip@}
5873 \xydefcsname@{dir2{|<<}}{%
5874 \composite@{}{h!/-\tipjot@/\dir2{<}*\dir2{<}*\dir2{|}}}
5875 \xydefcsname@{dir3{|<<}}{%
5876 \composite@{}{h!/-\tipjot@/\dir3{<}*\dir3{<}*\dir3{|}}}
5877 \xyletcsnamecsname@{dir0{|<<}}{dir{}}
5878 \xyletcsnamecsname@{dir{|<<}}{dir1{|<<}}
5880 \xydefcsname@{dir1{|-}}{\shiftdir@\stopper@\z@
5881 \shiftdir@\line@\z@ \pointlike@{}\jot}
5882 \xydefcsname@{dir^{|-}}{\shiftdir@{\aboveDirection@\xydashl@ \line@}\z@
5883 \shiftdir@\line@\z@ \pointlike@{}\jot}
5884 \xydefcsname@{dir_{|-}}{\shiftdir@{\belowDirection@\xydashl@ \line@}\z@
5885 \shiftdir@\line@\z@ \pointlike@{}\jot}
5886 \xydefcsname@{dir2{|-}}{\shiftdir@\stopper@\z@
5887 \shiftdir@\line@\z@ \pointlike@{}\jot \double@\xydashh@}
5888 \xydefcsname@{dir3{|-}}{\shiftdir@\stopper@\z@
5889 \shiftdir@\line@\z@ \pointlike@{}\jot \triple@\xydashh@}
5890 \xyletcsnamecsname@{dir0{|-}}{dir{}}
5891 \xyletcsnamecsname@{dir{|-}}{dir1{|-}}
5892 \xyletcsnamecsname@{dir{|=}}{dir2{|-}}
5894 \xydefcsname@{dir{+}}{%
5895 \DN@##1{\composite@{}{##10\dir{|}*!C##10\dir{-}}}\addEQ@\next@}
5896 \xyletcsnamecsname@{dir0{+}}{dir{}}

5898 \xydefcsname@{dir{x}}{\vDirection@(1,1)\jot
5899 \DN@##1{\composite@{}{##10\dir{|}*!C##10\dir{-}}}\addEQ@\next@}
5900 \xyletcsnamecsname@{dir0{x}}{dir{}}
5902 \xydefcsname@{dir{/}}{\vDirection@(1,-.3)\jot \stopper@}
5903 \xyletcsnamecsname@{dir0{/}}{dir{}}
5905 \xydefcsname@{dir{//}}{\vDirection@(1,-.3)\jot
5906 \shiftdir@\stopper@\xydashh@ \stopper@}
5907 \xyletcsnamecsname@{dir0{//}}{dir{}}
5909 \xydefcsname@{dir{*}}{\solidpoint@}
5910 \xydef@\solidpoint@{%
5911 \pointlike@{\kern-1.8pt\lower1.8pt\hbox{$\scriptstyle\bullet$}}\jot}
5912 \xyletcsnamecsname@{dir0{*}}{dir{}}
5914 \xydefcsname@{dir{o}}{\hollowpoint@}
5915 \xydef@\hollowpoint@{%
5916 \pointlike@{\kern-1.8pt\lower1.8pt\hbox{$\scriptstyle\circ$}}\jot}
5917 \xyletcsnamecsname@{dir0{o}}{dir{}}

Syntax  Action
\cir ⟨radius⟩ { ⟨cir⟩ }  ⟨cir⟩cle segment with ⟨radius⟩
⟨radius⟩ ⟶ ⟨empty⟩  use R_{c} as the radius
|  ⟨vector⟩  use X of the ⟨vector⟩ as radius
⟨cir⟩  ⟶ ⟨empty⟩  full circle of ⟨radius⟩
|

⟨diag⟩ ⟨orient⟩ ⟨diag⟩ partial circle from first ⟨diag⟩onal through to the

second ⟨diag⟩onal in the ⟨orient⟩ation

⟨orient⟩ ⟶ ^anticlockwise
|  _clockwise

Figure 1.8: ⟨cir⟩cles.

1.6.2 Circle segments

5972 \message{circles,}

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 1.8 with explanations below.

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:

5986 \xydef@\cir#1#{\hbox\bgroup
5987 \afterVECTORorEMPTY{\xy@@{\R@=\X@c}\cir@}{\xy@@{\R@=\R@c}\cir@}#1@}
5989 \xydef@\cir@#1@#2{%
5990 \DN@{#1}\ifx\next@\empty\else \xyerror@{illegal circle <radius>: must be
5991  <vector> or <empty>}{}\fi
5992 \afterCIRorDIAG{\xyFN@\cir@cir}{\xyFN@\cir@diag}#2@}

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:

6000 \xydef@\cir@cir{%
6001 \ifx \space@\next \expandafter\DN@\space{\xyFN@\cir@cir}%gobble spaces
6002 \else \ifx @\next \DN@ @{\cir@i}%
6003 \else \xyerror@{illegal <cir>: must have form <diag><orient><diag> or
6004  <empty>}{}%
6005 \fi\fi \next@}

Similarly when an ⟨empty⟩ one was given—the parser will recognise this as a ⟨diag⟩ but we hack that here:

6012 \xydef@\cir@diag{%
6013 \DN@{\xyerror@{illegal <cir>: must have form <diag><orient><diag> or
6014  <empty>}{}}%
6015 \ifx @\next \ifnum\count@=8 %
6016 \DN@ @{\def\CIRin@@{0}\def\CIRorient@@{\CIRfull@}\def\CIRout@@{7}\cir@i}%
6017 \fi\fi \next@}

… and then use the constructed methods to build it:

6023 \xydef@\cir@i{%
6024 \ifnum\CIRin@@=8 \xyerror@{incomplete <cir> specification}{%
6025 The <cir> you specified as <diag><orient><diag> is not sufficiently specific.}%
6026 \def\CIRin@@{0}\fi
6027 \ifdim\R@<.5\p@ \R@=\z@ \zerodot
6028 \else \CIRorient@@ \cirbuild@ \fi
6029 \L@c=\R@ \R@c=\R@ \D@c=\R@ \U@c=\R@ \def\Leftness@{.5}\def\Upness@{.5}%
6030 \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@\relax}%
6031 \Edge@c={\circleEdge}\OBJECT@x}

Parsing: The \afterCIRorDIAG parser handles the parsing: it either

• parses the ⟨cir⟩ and sets in, orient, and out, and passes control to the first argument continuation, or

• parses the single ⟨diag⟩ specified, store it in \count@ (as 8 if an ⟨empty⟩ one given), and pass control to the second continuation argument,

where the ⟨diag⟩ internal representation number of note 1.4l 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 (To Do: Rename all non-method control sequences that end in @@… to use @⟨romannumeral⟩ suffixes…):

6064 \xydef@\CIRin@@{3}
6065 \xydef@\CIRout@@{3}
6066 \xylet@\CIRorient@@=\empty
6068 \xydef@\afterCIRorDIAG#1#2{\def\afterCIR@{#1}\def\afterCIRDIAG@{#2}\xyFN@\CIR@}
6070 \xylet@\afterCIR@=\empty
6071 \xylet@\afterCIRDIAG@=\empty
6073 \xydef@\CIR@{\count@=8 \afterDIAG{\edef\CIRin@@{\the\count@}\xyFN@\CIR@@}}

6075 \xydef@\CIR@@{%
6076 \ifx \space@\next \expandafter\DN@\space{\xyFN@\CIR@@}%gobble spaces
6077 \else\ifx ^\next
6078 \DN@ ^{\def\CIRorient@@{\CIRacw@}%
6079 \afterDIAG{\edef\CIRout@@{\the\count@}\afterCIR@}}%
6080 \else\ifx _\next
6081 \DN@_{\def\CIRorient@@{\CIRcw@}%
6082 \afterDIAG{\edef\CIRout@@{\the\count@}\afterCIR@}}%
6083 \else
6084 \DN@{\def\CIRorient@@{\relax}\afterCIRDIAG@}%
6085 \fi\fi\fi \next@}

The default is to generate a full circle with the specified radius, e.g.,

                        \xy*\cir<4pt>{}\endxy typesets “[figure]”
                         \xy*{M}*\cir{}\endxy  —  “[figure: M]”

All the other circle segments are subsets of this and have the shape that the full circle outlines.

Finally we present the orient methods. They use these ‘internal methods’ to actually draw the circles

6111 \xylet@\CIRtest@@=\relax
6112 \xydef@\CIRlo@@{0}
6113 \xydef@\CIRhi@@{0}

Below we call them lo, hi, and test; the first two are coded as described in note 1.4l 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:

6125 \xydef@\CIRfull@{\def\CIRtest@@##1##2{##2}}

The kernel \cirbuild@ builds the actual ⟨object⟩ using characters from the \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@].

6135 \xydef@\cirbuild@{\cirrestrict@@ \multiply\count@8 %
6136 \circhar@0\circhar@7\kern\dimen@
6137 \circhar@1\circhar@6\kern\dimen@
6138 \circhar@2\circhar@5\kern\dimen@
6139 \circhar@3\circhar@4\kern\dimen@}
6141 \xydef@\circhar@#1{%
6142 \setboxz@h{\circhar@@{#1}}\dimen@=\wdz@ \wdz@=\z@ \ht\z@=\R@ \dp\z@=\R@
6143 \CIRtest@@#1{\styledboxz@}\setbox\z@=\copy\voidb@x}
6145 \xydef@\circhar@@#1{{\xycircfont \advance\count@#1\relax \char\count@}}

\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)

g = \{ \begin{matrix}⌊\frac{r}{1pt}⌋ − 1 & if 1pt ≤ r < 8pt \\ ⌊\frac{r}{2pt}⌋ + 3 & if 8pt ≤ r < 16pt \\ ⌊\frac{r}{4pt}⌋ + 7 & if 16pt ≤ r < 32pt \\ 15 & if 32pt ≤ r \end{matrix}

(where we know from \cir@i that r ≥ \frac{1}{2}pt), and then adjusts the radius to be exactly the one chosen through the use of group g using the formula in xycirc10.mf… 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.

6168 \xydef@\cirrestrict@@{\begingroup \dimen@=\R@
6169 \setboxz@h{\xycircfont\char\z@\char\@ne}\A@=\wdz@
6170 \ifdim\R@<8\A@ \count@=\dimen@ \divide\count@\A@ \advance\count@\m@ne
6171 \else\ifdim\R@<16\A@ \count@=\dimen@
6172 \dimen@=2\A@ \divide\count@\dimen@ \advance\count@3 %
6173 \else\ifdim\R@<32\A@ \count@=\dimen@
6174 \dimen@=4\A@ \divide\count@\dimen@ \advance\count@7 %
6175 \else \count@=15 \fi\fi\fi
6176 \R@=\A@
6177 \ifnum\count@<8 \multiply\R@\count@ \advance\R@\A@
6178 \else\ifnum\count@<12 \multiply\R@\count@ \multiply\R@\tw@ \advance\R@-6\A@
6179 \else\ifnum\count@<16 \multiply\R@\count@ \multiply\R@ 4 \advance\R@-28\A@
6180 \else \multiply\R@ 32 \fi\fi\fi
6181 \edef\@tmp{\endgroup \R@=\the\R@ \count@=\the\count@}\@tmp}

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 1.4l) and ends with a tangent vector in the direction of the other ⟨diag⟩onal after a clockwise (for _) or anticlockwise (for ^) turn, e.g.,

                      \xy*\cir<4pt>{l^r}\endxy typesets “[figure]”
                      \xy*\cir<4pt>{l_r}\endxy  —  “[figure]”
                      \xy*\cir<4pt>{dl^u}\endxy  —  “[figure]”
                      \xy*\cir<4pt>{dl_u}\endxy  —  “[figure]”
                     \xy*+{M}*\cir{dr_ur}\endxy  —  “[figure: M]”

If the same ⟨diag⟩ is given twice then nothing is typeset, e.g.,

                       \xy*\cir<4pt>{u^u}\endxy typesets “ ”

Special care is taken to setup the ⟨diag⟩onal defaults:

• After ^the default is the diagonal 90^{∘} anticlockwise from the one before the ^.

• After _the default is the diagonal 90^{∘} clockwise from the one before the _.

The ⟨diag⟩ before ^or _is required for \cir ⟨objects⟩.

Exercise 1.15: Typeset the following shaded circle with radius 5pt:

[figure]

These two macros implement the defaults and setup of lo and hi for anticlockwise and clockwise segments. Here is what they set:

⟨cir⟩  lo  hi  test(s)
d_{1}^d_{2}, d_{1} ≤ d_{2} d_{1} −_{8} 1 d_{2} −_{8} 1 lo ≤ s ∧ s < hi
d_{1}^d_{2}, d_{1} > d_{2} d_{2} −_{8} 1 d_{1} −_{8} 1 s < lo ∨ hi ≤ s
d_{1}_d_{2}, d_{1} < d_{2} d_{1} +_{8} 3 d_{2} +_{8} 3 s < lo ∨ hi ≤ s
d_{1}_d_{2}, d_{1} ≥ d_{2} d_{2} +_{8} 3 d_{1} +_{8} 3 lo ≤ s ∧ s < hi

where +_{8} and −_{8} are + and − modulo 8; d_{1} and d_{2} are in \count@@ and \count@, respectively.

6273 \xydef@\CIRacw@{\count@@=\CIRin@@ \count@=\CIRout@@
6274 \ifnum\count@=8 \count@=\count@@
6275 \ifnum\count@<6 \advance\count@\tw@ \else \advance\count@-6 \fi \fi
6276 \ifnum\count@@<\@ne \advance\count@@7 \else \advance\count@@\m@ne \fi
6277 \ifnum\count@<\@ne \advance\count@7 \else \advance\count@\m@ne \fi
6278 \ifnum\count@@>\count@ \let\CIRtest@@=\CIRtest@outside
6279 \edef\CIRlo@@{\the\count@}\edef\CIRhi@@{\the\count@@}%
6280 \else \let\CIRtest@@=\CIRtest@inside
6281 \edef\CIRlo@@{\the\count@@}\edef\CIRhi@@{\the\count@}%
6282 \fi}
6284 \xydef@\CIRcw@{\count@@=\CIRin@@ \count@=\CIRout@@
6285 \ifnum\count@=8 \count@=\count@@
6286 \ifnum\count@>\@ne \advance\count@-\tw@ \else \advance\count@6 \fi \fi
6287 \ifnum\count@@<5 \advance\count@@\thr@@ \else \advance\count@@-5 \fi
6288 \ifnum\count@<5 \advance\count@\thr@@ \else \advance\count@-5 \fi
6289 \ifnum\count@@<\count@ \let\CIRtest@@=\CIRtest@outside
6290 \edef\CIRlo@@{\the\count@@}\edef\CIRhi@@{\the\count@}%
6291 \else \let\CIRtest@@=\CIRtest@inside
6292 \edef\CIRlo@@{\the\count@}\edef\CIRhi@@{\the\count@@}%
6293 \fi}
6295 \xydef@\CIRtest@inside#1#2{\let\next@=\relax
6296 \ifnum\CIRlo@@>#1\else \ifnum#1<\CIRhi@@\DN@{#2}\fi\fi \next@}
6298 \xydef@\CIRtest@outside#1#2{\let\next@=\relax
6299 \ifnum\CIRlo@@>#1\DN@{#2}\else \ifnum#1<\CIRhi@@\else\DN@{#2}\fi\fi \next@}

1.6.3 Text

6309 \message{text;}

Text in pictures is supported through the ⟨object⟩ construction

\txt ⟨width⟩ ⟨style⟩ {⟨text⟩}

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⟩.

The code just parses the ⟨width⟩ defaulting it to <\maxdimen> which is recognised as ‘free form’.

6331 \xydef@\txt{\hbox\bgroup \xyFN@\txt@}
6333 \xydef@\txt@{%
6334 \addLT@\ifx\next \addGT@{\addLT@\DN@##1}{\A@=##1\txt@i}%
6335 \else \DN@{\A@=\maxdimen \txt@i}\fi \next@}
6337 \xydef@\txt@i#1#{%
6338 \setboxz@h{#1\mathstrut}\dimen@=\ht\z@ \advance\dimen@\dp\z@
6339 \baselineskip=1.1\dimen@ \lineskip=.2\dimen@ \lineskiplimit=\lineskip
6340 \def\txtline@@##1{\txtline@{#1}{##1}}\object@\txt@ii}
6342 \xylet@\txtline@@=\eat@

6343 \xydef@\txtline@#1#2{\relax\setboxz@h{#1{\ignorespaces #2\unskip}}%
6344 \ifdim\A@<\wdz@ \setboxz@h{\hsize=\A@
6345 \leftskip=0pt plus4em \rightskip=\leftskip
6346 \parfillskip=0pt \parindent=0pt %
6347 \spaceskip=.3333em \xspaceskip=.5em %
6348 \pretolerance=9999 \tolerance=9999 %
6349 \hyphenpenalty=9999 \exhyphenpenalty=9999 %
6350 \vbox{#1\noindent\ignorespaces #2\unskip}}%
6351 \else\ifdim\A@<\maxdimen\setboxz@h to\A@{\hfil\boxz@\hfil}\fi\fi
6352 \boxz@}
6354 \xydef@\txt@ii#1{\vbox{%
6355 \let\\=\cr
6356 \tabskip=\z@skip \halign{\relax\hfil\txtline@@{##}\hfil\cr\leavevmode#1\crcr}}}

1.7 XY-pic options

Note: L^{A}TEX 2ε users should also consult the paragraph on “xy.sty” in §1.1.1.

1.7.1 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.

                                \xyoption { ⟨option⟩ }
                                \xyrequire { ⟨option⟩ }

\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 [18].

\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.).

6400 \message{options;}
6402 \xylet@\xyoption@@=\relax
6404 \xydef@\xyoption#1{\DN@{#1}\edef\next@{\codeof\next@}%
6405 \csname xyeveryrequest@\next@ @\endcsname
6406 \xyinputorelse@{xy#1}{\xyoption@truncated#1@@@@@@@@@,#1@}%
6407 \def\xyoption@@{#1}\edef\xyoption@@{\codeof\xyoption@@}
6408 \expandafter\let\expandafter\next@\csname xy\xyoption@@ version\endcsname
6409 \expandafter\let\csname xy\xyoption@@ loaded\endcsname=\next@
6410 \runxywith@ \ignorespaces}
6412 \xydef@\xyoption@truncated#1#2#3#4#5#6#7@#8,#9@{%
6413 \DN@{#7}\ifx\next@\empty \DN@##1##2{##2}\else\let\next@=\xyinputorelse@ \fi
6414 \next@{xy#1#2#3#4#5#6}%
6415 {\DN@{#1#2#3#4#5#6}\edef\next@{\codeof\next@}%
6416 \xyerror@{No `\next@' option}{%
6417 Your \xyoption{#9} request could not be granted: the required^^J%
6418 file `xy#9.tex' could not be located. Please make sure that it is^^J%

6419 properly installed before continuing.}}}
6421 \xydef@\xyrequire#1{\DN@{#1}\edef\next@{\codeof\next@}%
6422 \csname xyeveryrequest@\next@ @\endcsname
6423 \expandafter\let\expandafter\next@\csname xy\codeof\next@ loaded\endcsname
6424 \ifx \next@\relax \DN@{\xyoption{#1}}\else \DN@{\ignorespaces}\fi \next@}

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

                          \xywithoption { ⟨option⟩ } { ⟨code⟩ }

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

\xywithoption command.

6443 \xylet@\xywith@@=\empty
6445 \xydef@\runxywith@{\let\xywithdo@@=\xywithtest@ \xywith@@}
6447 \xydef@\xywithoption#1#2{\DN@{#1}\edef\next@{\codeof\next@}%
6448 \expandafter\let\expandafter\nextii@\csname xy\next@ loaded\endcsname
6449 \ifx \nextii@\relax
6450 \expandafter\def\expandafter\xywith@@\expandafter{\xywith@@
6451 \xywithdo@@{#1}{#2}}%
6452 \else \expandafter\xywithrun@\expandafter{\next@}{#2}\fi}
6454 \xydef@\xywithtest@#1#2{\DN@{#1}\edef\next@{\codeof\next@}%
6455 \ifx\next@\xyoption@@ \expandafter\xywithrun@\expandafter{\next@}{#2}\fi}
6457 \xydef@\xywithrun@#1#2{\csname xyeverywithoption@#1@\endcsname #2}

Finally, it is possible to declare ⟨code⟩ as some commands to be executed before every actual execution of \xywithoption{⟨option⟩}{… }, and similarly ⟨code⟩ to be executed before every \xyoption{⟨option⟩} and \xyrequire{⟨option⟩} (collectively called ‘requests’)::

                       \xyeverywithoption { ⟨option⟩ } { ⟨code⟩ }
                       \xyeveryrequest { ⟨option⟩ } { ⟨code⟩ }

This is most often used by an option to activate some hook every time it is requested itself.

These last two use the usual expansion trickery to define or append to the control sequences named \xyeveryrequest@⟨option⟩@ and \xyeverywithoption@⟨option⟩@ used in the definitions above.

6483 \xydef@\xyevery@#1#2#3{\DN@{#2}\edef\next@{\codeof\next@}%
6484 \expandafter\ifx\csname xyevery#1@\next@ @\endcsname\relax
6485 \expandafter\let\csname xyevery#1@\next@ @\endcsname=\empty \fi
6486 \DNii@##1{\expandafter\def\expandafter##1\expandafter{##1#3}}%
6487 \expandafter\nextii@\csname xyevery#1@\next@ @\endcsname}
6489 \xydef@\xyeveryrequest{\xyevery@{request}}
6490 \xydef@\xyeverywithoption{\xyevery@{withoption}}

1.7.2 Option file format

Option files must have the following structure:

%% ⟨identification⟩ %% ⟨copyright, etc.⟩

     \ifx\xyloaded\undefined \input xy \fi

\xyprovide{⟨option⟩}{⟨name⟩}{⟨version⟩}% {⟨author⟩}{⟨email⟩}{⟨address⟩}

⟨body of the option⟩

     \xyendinput

The 6 arguments to \xyprovide should contain the following:

⟨option⟩ Option load name as used in the \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.

⟨name⟩ Descriptive name for the option.

⟨version⟩ Identification of the version of the option.

⟨author⟩ The name(s) of the author(s).

⟨email⟩ The electronic mail address(es) of the author(s) or the affiliation if no email is available.

⟨address⟩ The postal address(es) of the author(s).

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.

The \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 \xycatcodes such that the option internals are loaded in ‘TEX programming mode’.

\xyendinput undoes this.

6558 \xydef@\xyprovide#1#2#3#4#5#6{%
6559 \def\xyoption@@{#1}\edef\xyoption@@{\codeof\xyoption@@}\edef\next@{#3}%
6560 \message{ Xy-pic option: #2 v.\next@}%
6561 \expandafter\let\expandafter\nextii@\csname xy\xyoption@@ loaded\endcsname
6562 \ifx \next@\nextii@ \message{not reloaded}\endinput
6563 \else
6564 \ifx \nextii@\relax\else \xyerror@{Option `\xyoption@@' version mismatch}{%
6565 You previously loaded, or the format has preloaded, a different version^^J%
6566 of this option.  Just continue to try to load this version instead (and^^J%
6567 be prepared for a lot of warnings about redefinitions).}%

6568 \fi

6569 \expandafter\let\csname xy\xyoption@@ version\endcsname=\next@
6570 \expandafter\let\expandafter\xyenddocmode@\csname DOCMODE\endcsname
6571 \expandafter\let\csname DOCMODE\endcsname\xyprovidedocmode@
6572 \xycatcodes
6573 \fi \ignorespaces}
6575 \xydef@\xyendinput{\expandafter\let\csname DOCMODE\endcsname=\xyenddocmode@
6576 \message{loaded}\xyuncatcodes\endinput}

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.

6585 \expandafter\xylet@\expandafter\xyprovidedocmode@\csname DOCMODE\endcsname
6586 \xylet@\xyenddocmode@=\relax

The ‘dummy’ option described in §3.2 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.

1.7.3 Driver options

The ⟨driver⟩ options described in chapter ?? require special attention because each driver can support several extension options, and it is sometimes desirable to change ⟨driver⟩ or even mix the support provided by several.^{6}

A ⟨driver⟩ option is loaded as other options with \xyoption{⟨driver⟩} (or through L^{A}TEX 2ε class or package options as described in §1.1.1). 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:

\UseSingleDriver forces one driver only
\MultipleDrivers allows multiple drivers
\xyReloadDrivers resets driver information

The first command restores the default behaviour: that ony one ⟨driver⟩ is allowed, i.e., 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.

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).

6655 \xydef@\xydriversloaded@@{\do{unload}}
6656 \xylet@\xydriversselected@@=\empty

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:

6668 \xylet@\xydriver@unload@support@@=\empty

6The kernel support described here is based on the (now defunct) xydriver include file by Ross Moore.

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 ◯_{¨⌣} ): 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.

6684 \xydef@\selectdriver@#1{\DN@{#1}\edef\next@{\codeof\next@}%
6685 \expandafter\selectdriver@@\expandafter{\next@}}
6687 \xydef@\selectdriver@single#1{\xysetup@@{\def\xydriversselected@@{\do{#1}}%
6688 \xyLoadDrivers@}\let\selectdriver@@=\changedriver@single}
6690 \xydef@\changedriver@single#1{\xysetup@@{\def\xydriversselected@@{\do{#1}}%
6691 \xyReloadDrivers@}}
6693 \xydef@\selectdriver@multiple#1{\expandafter\xysetup@@\expandafter{%
6694 \expandafter\def\expandafter\xydriversselected@@\expandafter{%
6695 \xydriversselected@@ \do{#1}}%
6696 \let\do=\activatedriver@ \xydriversselected@@}}
6698 \xydef@\UseSingleDriver{\let\selectdriver@@=\selectdriver@single}
6699 \xydef@\MultipleDrivers{\let\selectdriver@@=\selectdriver@multiple}
6701 \xydef@\xyLoadDrivers@{\let\do=\activatedriver@ \xydriversselected@@}
6702 \xydef@\xyReloadDrivers@{\activatedriver@{unload}\xyLoadDrivers@}
6703 \xylet@\xyReloadDrivers=\xyReloadDrivers@
6705 \xydef@\activatedriver@#1{%
6706 \let\doii=\activatedriversupport@ \csname xydriver@#1@support@@\endcsname}
6708 \xydef@\activatedriversupport@#1#2{%
6709 \expandafter\ifx\csname xy#1loaded\endcsname\relax\DN@{}%
6710 \else\DN@{#2}\fi \next@}
6712 \UseSingleDriver

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:

6721 \xydef@\xyselectoptionsupport@{\let\do=\activatedriver@ \xydriversselected@@}

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 \xyReloadDrivers is used when there is doubt about the state of affairs. In case of confusion the special command \xyShowDrivers will list all the presently supported and selected driver-extension pairs to the TEX log.

6735 \xydef@\xyShowDrivers{{\W@{Loaded:}\let\do=\doShow \xydriversloaded@@
6736 \let\next@=\empty
6737 \def\do##1{\ifx\next@\empty \DN@{##1}%
6738  \else \expandafter\DN@\expandafter{\next@, ##1}\fi}%
6739 \xydriversselected@@\W@{Selected: \next@.}}}
6741 \def\doShow#1{\let\next@=\empty
6742 \def\doii##1##2{\ifx\next@\empty \DN@{##1}%

6743 \else \expandafter\DN@\expandafter{\next@, ##1}\fi}%
6744 \csname xydriver@#1@support@@\endcsname
6745 \W@{ <driver> #1 supports \next@.}}

Driver internals. A ⟨driver⟩ option files must have the following structure:

%% ⟨identification⟩ %% ⟨copyright, etc.⟩

     \ifx\xyloaded\undefined \input xy \fi

\xyprovide{⟨option⟩}{⟨name⟩}{⟨version⟩}% {⟨author⟩}{⟨email⟩}{⟨address⟩}

     \newdriver{%
     \xyaddsupport{⟨extension⟩}⟨cs⟩

⋮

     }

⟨body of the ⟨driver⟩ option⟩

     \xyendinput

There should be an \xyaddsupport command for each supported ⟨extension⟩ which specicifies the ⟨cs⟩ (control sequence) with which the indicated support is activated.

The \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

                           \xyaddunsupport {⟨extension⟩} ⟨cs⟩

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: (l.6809) add the driver and clear its support control sequence unless it is already defined, (l.6815) execute the support commands, and (l.6816) setup to select it after loading.

6808 \xydef@\newdriver#1{%
6809 \def\nextiii@##1{
6810 \expandafter\def\expandafter\xydriversloaded@@
6811 \expandafter{\xydriversloaded@@\do{##1}}%
6812 \expandafter\let\csname xydriver@\xyoption@@ @support@@\endcsname=\empty}%
6813 \def\do##1{\DNii@{##1}\ifx\xyoption@@\nextii@ \let\nextiii@=\eat@ \fi}%
6814 \xydriversloaded@@ \expandafter\nextiii@\expandafter{\xyoption@@}%
6815 #1\relax
6816 \DN@##1{\xywithoption{##1}{
6817 \selectdriver@{##1}\xyeveryrequest{##1}{\selectdriver@{##1}}}}%
6818 \expandafter\next@\expandafter{\xyoption@@}\ignorespaces}

The support commands merely add to the support \do-lists which in turn (l.6845) adds \doii{⟨extension⟩}{… } to the \xydriver@⟨driver⟩@support@@ control sequence and adds a check for when to apply it every time that ⟨extension⟩ is requested!

6828 \xydef@\xyaddsupport{\expandafter\xyadddriversupport@\expandafter{\xyoption@@}}
6829 \xydef@\xyaddunsupport{\xyadddriversupport@{unload}}
6831 \xydef@\xyadddriversupport@#1#2#3{%
6832 \DNii@{#1}\edef\nextii@{\codeof\nextii@}%
6833 \def\nextiii@{#2}\edef\nextiii@{\codeof\nextiii@}%

6834 %

6835 % CHECK that the <driver> is loaded!
6836 \def\next{\xybug@{<driver> \nextii@\space not loaded}}%
6837 \def\do##1{\DN@{##1}\edef\next@{\codeof\next@}%
6838 \ifx\next@\nextii@ \let\next=\relax \fi}\xydriversloaded@@ \next

6839 %

6840 % CHECK that the specified <extension> is not already supported!
6841 \def\next{\xybug@{<driver> \nextii@\space already supports \nextiii@}}%
6842 \def\doii##1##2{\DN@{##1}\edef\next@{\codeof\next@}%
6843 \ifx\next@\nextiii@ \let\next=\relax \fi}\xydriversloaded@@ \next

6844 %

6845 \DN@##1##2{\ifx##1\relax \let##1=\empty \fi
6846 \expandafter\def\expandafter##1\expandafter{##1\doii{##2}{#3}}}%
6847 \expandafter\expandafter\expandafter\next@
6848 \expandafter\expandafter\csname xydriver@\nextii@ @support@@\endcsname
6849 \expandafter{\nextiii@}%
6850 \DN@##1{\expandafter\xyeverywithoption\expandafter{\nextiii@}{%
6851 \xytestforsupport@{##1}}}%
6852 \expandafter\next@\expandafter{\nextii@}\xydriversloaded@@
6853 \ignorespaces}
6855 \xydef@\xytestforsupport@#1{\def\do##1{\DN@{##1}\DNii@{#1}%
6856 \ifx\next@\nextii@ \expandafter\xyselectoptionsupport@ \fi}}

Driver related messages. 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.

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

                    \xyununsupportwarning@ {⟨extension⟩} {⟨message⟩}
                    \xyunsupportwarning@ {⟨driver⟩} {⟨extension⟩}

6882 \xynew@{if}\ifunsupportwarnings@
6884 \xydef@\xyunsupportwarning@#1#2{{%
6885 \DN@{#1}\edef\next@{\codeof\next@}
6886 \expandafter\ifx\csname xywarn@unload@\next@ @\endcsname\relax
6887 \expandafter\gdef\csname xywarn@unload@\next@ @\endcsname{}%
6888 \ifunsupportwarnings@ \xyclosedown@@\xyunsupportwarnings@@ \fi
6889 \global\unsupportwarnings@true
6890 \expandafter\gdef\expandafter\xyunsupportwarnings@@\expandafter{%
6891 \xyunsupportwarnings@@ \W@{ #2.}}%
6892 \W@{}%

1.8. ALGORITHMS 97

6893 \W@{Xy-pic Warning: `\next@' reproduction is NOT EXACT\xytracelineno@:}%
6894 \W@{ #2.}%
6895 \W@{}%
6896 \fi}}
6898 \xydef@\xyunsupportwarnings@@{\W@{}%
6899 \W@{Xy-pic Warning: The produced DVI file is NOT EXACT:}}
6901 \xynew@{if}\ifsupportwarnings@
6903 \xydef@\xysupportwarning@#1#2{{%
6904 \DN@{#1}\edef\next@{\codeof\next@}\DNii@{#2}\edef\nextii@{\codeof\nextii@}%
6905 \expandafter\ifx\csname xywarn@\next@ @\nextii@ @\endcsname\relax
6906 \expandafter\gdef\csname xywarn@\next@ @\nextii@ @\endcsname{}%
6907 \ifsupportwarnings@ \xyclosedown@@\xysupportwarnings@@ \fi
6908 \global\supportwarnings@true
6909 \expandafter\gdef\expandafter\xysupportwarnings@@\expandafter{%
6910 \xysupportwarnings@@ \driverextensioncomplain@{#1}{#2}}%
6911 \W@{}%
6912 \W@{Xy-pic Warning: The produced DVI file is NOT PORTABLE\xytracelineno@:}%
6913 \driverextensioncomplain@{#1}{#2}%
6914 \W@{}%
6915 \fi}}
6917 \xydef@\xysupportwarnings@@{%
6918 \W@{Xy-pic Warning: The produced DVI file is NOT PORTABLE:}}
6920 \xydef@\driverextensioncomplain@#1#2{%
6921 \DN@{#1}\edef\next@{\codeof\next@}\DNii@{#2}\edef\nextii@{\codeof\nextii@}%
6922 \W@{ It contains <driver> `\next@' \string\special s for the `\nextii@'
6923  extension.}}

Backwards compatibility…

6929 \xydef@\dvimessage@#1#2{\xysupportwarning@{#1}{#2}}
6931 \xynew@{if}\ifxydrivernoloads@
6932 \xydef@\xydrivernoload@#1{\xyerror@{Could not load xy#1.tex}{}%
6933 \xydrivernoloads@true}
6935 \xydef@\xydriverfail@#1{\xyerror@{Sorry, #1 not supported.}{}}
6937 \xydef@\xyunload@#1{\xywarning@{Unloading #1.}}

1.8 Algorithms

This section presents the more complicated algorithms used in XY-pic.

1.8.1 Directions

6957 \message{algorithms: directions,}

The direction state is described by the following parameters:

Direction  ‘angle’ of the direction on ]−4K … 4K] unit square
dX ,dY  the vector c − p

sdX ,sdY  sign of dX and dY
\K@dXdY,\K@dYdX  quotients K \frac{dX}{dY} and K \frac{dY}{dX} (as dimensions in sp)
DirectionChar,SemiDirectionChar \chardefs for directional and semidirectional fonts

cosDirection,sinDirection factors in the range ] − 1 … 1] corresponding to cos and sin of Direction

where the “] − 4K … 4K] unit square” has the following angles:

[figure: 0; K; 2K; 3K; 4K; −3K; −2K; −K]

where the intermediate K angle in each interval correspond to equidistant points on the unit square. Thus only for n ∈ {−3, 2, 1, 0, 1, 2, 3, 4} the angle of direction n × K is exactly n × 45^{∘} − 135^{∘} (0^{∘} being the direction straight right).

As usual \DirectionfromtheDirection@ expands to code setting the current direction.

6997 \xydef@\DirectionfromtheDirection@{\noexpand\Direction=\the\Direction
6998 \noexpand\d@X=\the\d@X \noexpand\d@Y=\the\d@Y
6999 \def\noexpand\sd@X{\sd@X}\def\noexpand\sd@Y{\sd@Y}%
7000 \noexpand\K@dXdY=\the\K@dXdY \noexpand\K@dYdX=\the\K@dYdX
7001 \chardef\noexpand\DirectionChar=\the\DirectionChar
7002 \chardef\noexpand\SemiDirectionChar=\the\SemiDirectionChar
7003 \def\noexpand\cosDirection{\cosDirection}%
7004 \def\noexpand\sinDirection{\sinDirection}%
7005 \noexpand\resetupDirection@}

The actual direction computation is done using \setupDirection@.

Procedure: Is really not so complicated. [l.7024] 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); [l.7027] if the direction is one of the principal ones then proceed with an optimised special case for those; otherwise proceed with the generic code.

7021 \xydef@\Directiontest@@#1#2{#2}
7023 \xydef@\setupDirection@{%
7024 \d@X=\X@c\advance\d@X-\X@p \d@Y=\Y@c\advance\d@Y-\Y@p
7025 \Directiontest@@\relax\setupDirection@i}
7027 \xydef@\setupDirection@i{\DN@{\setupDirection@ii}
7028 \ifdim\d@X=\d@Y
7029 \ifdim\zz@\d@Y \DN@{}%
7030 \else\ifdim\d@X<\z@ \DN@{\dlDirection@{-1.4142\d@X}}%
7031 \else \DN@{\urDirection@{1.4142\d@X}}\fi\fi
7032 \else\ifdim\d@X<\d@Y
7033 \ifdim\zz@\d@X \DN@{\uDirection@\d@Y}%
7034 \else\ifdim\zz@\d@Y \DN@{\lDirection@{-\d@X}}%
7035 \else\ifdim-\d@X=\d@Y \DN@{\ulDirection@{-1.4142\d@X}}\fi\fi\fi

7036 \else
7037 \ifdim\zz@\d@X \DN@{\dDirection@{-\d@Y}}%
7038 \else\ifdim\zz@\d@Y \DN@{\rDirection@\d@X}%
7039 \else\ifdim\d@X=-\d@Y \DN@{\drDirection@{1.4142\d@X}}\fi\fi\fi
7040 \fi\fi \next@}

The procedures for the special ⟨diag⟩onal cases are summarised in this table:

⟨diag⟩onal Direction cos(Direction), sin(Direction) sign(dX , dY ) Char Semi
dl  0  −\sqrt{\frac{1}{2}}, −\sqrt{\frac{1}{2}}  −, −  127 127
d  K  0, −1  +, −  15 31
dr  2K  \sqrt{\frac{1}{2}}, −\sqrt{\frac{1}{2}}  +, −  31 63
r  3K  1, 0  +, +  47 95
ur  4K  \sqrt{\frac{1}{2}}, \sqrt{\frac{1}{2}}  +, +  63 127
u  −3K  0, 1  +, +  79 31
ul  −2K  −\sqrt{\frac{1}{2}}, \sqrt{\frac{1}{2}}  −, +  95 63
l  −K  −1, 0  −, +  111 95

In each case the argument is used as the unit circle, i.e., non-zero of dX and dY , and <K \frac{dX}{dY} ,K \frac{dY}{dX} > := KK × <dX ,dY >…

7068 \xydef@\dlDirection@{\Direction=\z@
7069 \def\cosDirection{-.7071}\def\sinDirection{-.7071}\def\sd@X{-}\def\sd@Y{-}%
7070 \chardef\DirectionChar=127\relax\chardef\SemiDirectionChar=127\relax
7071 \K@dXdY=1\K@ \K@dYdX=1\K@ \fixedDirection@}
7073 \xydef@\dDirection@{\Direction=\K@
7074 \def\cosDirection{0}\def\sinDirection{-1}\def\sd@Y{-}%\def\sd@X{+}
7075 \edef\sd@X{\ifdim\X@c<\X@p-\else+\fi}%
7076 \chardef\DirectionChar=15\relax\chardef\SemiDirectionChar=31\relax
7077 \K@dXdY=\z@ \K@dYdX=\KK@\K@ \fixedDirection@}
7079 \xydef@\drDirection@{\dimen@ii=2\K@ \Direction=\dimen@ii
7080 \def\cosDirection{+.7071}\def\sinDirection{-.7071}\def\sd@X{+}\def\sd@Y{-}%
7081 \chardef\DirectionChar=31\relax\chardef\SemiDirectionChar=63\relax
7082 \K@dXdY=-1\K@ \K@dYdX=-1\K@ \fixedDirection@}
7084 \xydef@\rDirection@{\dimen@ii=3\K@ \Direction=\dimen@ii
7085 \def\cosDirection{+1}\def\sinDirection{0}\def\sd@X{+}%\def\sd@Y{+}%
7086 \edef\sd@Y{\ifdim\Y@c<\Y@p-\else+\fi}%
7087 \chardef\DirectionChar=47\relax\chardef\SemiDirectionChar=95\relax
7088 \K@dXdY=\KK@\K@ \K@dYdX=\z@ \fixedDirection@}
7090 \xydef@\urDirection@{\dimen@ii=4\K@ \Direction=\dimen@ii
7091 \def\cosDirection{+.7071}\def\sinDirection{+.7071}\def\sd@X{+}\def\sd@Y{+}%
7092 \chardef\DirectionChar=63\relax\chardef\SemiDirectionChar=127\relax
7093 \K@dXdY=1\K@ \K@dYdX=1\K@ \fixedDirection@}
7095 \xydef@\uDirection@{\dimen@ii=-3\K@ \Direction=\dimen@ii
7096 \def\cosDirection{0}\def\sinDirection{+1}\def\sd@Y{+}%\def\sd@X{+}
7097 \edef\sd@X{\ifdim\X@c<\X@p-\else+\fi}%
7098 \chardef\DirectionChar=79\relax\chardef\SemiDirectionChar=31\relax
7099 \K@dXdY=\z@ \K@dYdX=\KK@\K@ \fixedDirection@}

7101 \xydef@\ulDirection@{\dimen@ii=-2\K@ \Direction=\dimen@ii
7102 \def\cosDirection{-.7071}\def\sinDirection{+.7071}\def\sd@X{-}\def\sd@Y{+}%
7103 \chardef\DirectionChar=95\relax\chardef\SemiDirectionChar=63\relax
7104 \K@dXdY=-1\K@ \K@dYdX=-1\K@ \fixedDirection@}
7106 \xydef@\lDirection@{\Direction=-\K@
7107 \def\cosDirection{-1}\def\sinDirection{0}\def\sd@X{-}%\def\sd@Y{+}%
7108 \edef\sd@Y{\ifdim\Y@c<\Y@p-\else+\fi}%
7109 \chardef\DirectionChar=111\relax\chardef\SemiDirectionChar=95\relax
7110 \K@dXdY=\KK@\K@ \K@dYdX=\z@ \fixedDirection@}
7112 \xydef@\fixedDirection@#1{\dimen@ii=#1\relax
7113 \d@X=\cosDirection\dimen@ii \d@Y=\sinDirection\dimen@ii
7114 \resetupDirection@}

Here is the procedure for the generic code.

l.7171 Make sign variables and slopes: sdX := sign(dX ), sdY := sign(dY ), K \frac{dX}{dY} := sdX × sdY × ⌊|KK × dX | / |dY /KK |⌋, and K \frac{dY}{dX} := sdX × sdY × ⌊|KK × dY | / |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… Also takes care not to multiply too big dimensions with each other.

l.7188 If −K ≤ K \frac{dX}{dY} ≤ K then the direction is mostly up or down: if dY < 0 [down, l.7189]: Direction := −K \frac{dX}{dY} + 1K; else [up, l.7191]: Direction := −K \frac{dX}{dY} − 3K.

l.7194 If −K < K \frac{dY}{dX} < K then direction is mostly left or right: if dX < 0 [left, l.7195]: Direction := K \frac{dY}{dX} − K; else [right, l.7197]: Direction := K \frac{dY}{dX} + 3K.

l.7222 Compute character codes for direction and semidirection fonts. [l.7223]: DirectionChar := (8K + Direction + K/32) div (K/16) − 1; while DirectionChar > 127 : DirectionChar− := 128. [l.7226]: SemiDirectionChar := (8K + Direction + K/64) div (K/32) − 1; while SemiDirectionChar > 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…

l.7229 Build cosDirection and sinDirection from appropriate characters in the \xydashfont. [l.7229]: cosDirection := wd(\xydashfontSemiDirectionChar). [l.7231] C := SemiDirectionChar − 64, if C < 0: C := C + 128, sinDirection := wd(\xydashfontC).

l.7207 Register this dX ,dY for next time.

7170 \xydef@\setupDirection@ii{%
7171 \ifdim\d@X<\z@ \def\sd@X{-}\else \def\sd@X{+}\fi
7172 \ifdim\d@Y<\z@ \def\sd@Y{-}\else \def\sd@Y{+}\fi
7173 \K@dXdY=\sd@X\d@X \ifdim\K@dXdY<500pt \multiply\K@dXdY\KK@ \fi
7174 \dimen@=\sd@Y\d@Y
7175 % \advance\dimen@.5\KK@ \divide\dimen@\KK@
7176 \advance\dimen@\ifdim\dimen@<\z@-\fi.5\KK@ \divide\dimen@\KK@
7177 \ifdim\dimen@=\z@\else %\count@=\dimen@ \divide\count@\tw@
7178 \advance\K@dXdY by.5\dimen@\relax \divide\K@dXdY\dimen@
7179 \fi \K@dXdY=\sd@X\sd@Y\K@dXdY

7180 \K@dYdX=\sd@Y\d@Y \ifdim\K@dYdX<500pt \multiply\K@dYdX\KK@ \fi
7181 \dimen@=\sd@X\d@X
7182 % \advance\dimen@.5\KK@ \divide\dimen@\KK@
7183 \advance\dimen@\ifdim\dimen@<\z@-\fi.5\KK@ \divide\dimen@\KK@
7184 \ifdim\dimen@=\z@\else %\count@=\dimen@ \divide\count@\tw@
7185 \advance\K@dYdX by.5\dimen@\relax \divide\K@dYdX\dimen@
7186 \fi \K@dYdX=\sd@X\sd@Y\K@dYdX
7187 \Direction=\maxdimen
7188 \ifnum\K@dXdY<-\K@ \else \ifnum\K@<\K@dXdY \else
7189 \ifdim \d@Y<\z@
7190  \Direction=\K@ \advance\Direction-\K@dXdY
7191 \else
7192  \Direction=\K@ \multiply\Direction-\thr@@ \advance\Direction-\K@dXdY
7193 \fi\fi\fi
7194 \ifnum-\K@<\K@dYdX \ifnum\K@dYdX<\K@
7195 \ifdim \d@X<\z@
7196  \Direction=-\K@ \advance\Direction\K@dYdX
7197 \else
7198  \Direction=\K@ \multiply\Direction\thr@@ \advance\Direction\K@dYdX
7199 \fi\fi\fi
7200 \ifnum\Direction=\maxdimen
7201 \Direction=\K@dYdX \advance\Direction-\K@dXdY
7202 \advance\Direction\ifnum\Direction<\z@-\fi\@ne \divide\Direction\tw@
7203 \ifnum\K@dXdY<\z@ \advance\Direction\K@ \advance\Direction\K@
7204 \else \advance\Direction-\K@ \advance\Direction-\K@ \fi

7205 \fi

7206 \imposeDirection@i
7207 \resetupDirection@

7208 }

7210 \xydef@\imposeDirection@{\count@@=\Direction
7211 \loop@\ifnum\count@@>4096 \advance\count@@-8192 \repeat@
7212 \loop@\ifnum\count@@<-4096 \advance\count@@8192 \repeat@
7213 \def\sd@X{+}\ifnum\count@@<\K@ \relax
7214 \ifnum\count@@>-3072 \def\sd@X{-}\fi\fi
7215 \def\sd@Y{+}\ifnum\count@@<3072 \relax
7216 \ifnum\count@@>-\K@ \relax\def\sd@Y{-}\fi\fi
7217 \imposeDirection@i
7218 \d@X=\cosDirection\xydashl@ \d@Y=\sinDirection\xydashl@
7219 \resetupDirection@}
7221 \xydef@\imposeDirection@i{%
7222 \count@@=\K@ \multiply\count@@ by8 \advance\count@@\Direction
7223 \count@=\count@@ \advance\count@\KK@ \divide\count@64 \advance\count@\m@ne
7224 \loop@\ifnum127<\count@ \advance\count@-128 \repeat@
7225 \chardef\DirectionChar\count@
7226 \advance\count@@16 \divide\count@@\KK@ \advance\count@@\m@ne
7227 \loop@\ifnum127<\count@@ \advance\count@@-128 \repeat@
7228 \chardef\SemiDirectionChar\count@@
7229 \setbox8=\hbox{\xydashfont\SemiDirectionChar\/}%
7230 \quotient@@\cosDirection{\sd@X\wd8}\xydashl@

7231 \setbox8=\hbox{\xydashfont\count@=\SemiDirectionChar\advance\count@-64
7232 \ifnum\count@<\z@ \advance\count@128 \fi \char\count@\/}%
7233 \quotient@@\sinDirection{\sd@Y\wd8}\xydashl@}
7235 \xydef@\getxyDirection@#1{\xy@@\bgroup\xy@@ix@{#1}%
7236 \xy@@{\expandafter\POS\the\toks9\relax\setupDirection@
7237 \edef\next@{\egroup \Direction=\the\Direction}\next@ \imposeDirection@ }}

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), i.e.,

computes a new direction as the vector

<X − x × cos α × L − y × (− sin α) × L,Y − x × sin α × L − y × cos α × L>

where α is the previous direction angle.

7253 \xydef@\reverseDirection@{%
7254 \d@X=-\d@X \d@Y=-\d@Y
7255 \ifdim\d@X<\z@ \def\sd@X{-}\else \def\sd@X{+}\fi
7256 \ifdim\d@Y<\z@ \def\sd@Y{-}\else \def\sd@Y{+}\fi
7257 \dimen@=4\K@ \ifnum\Direction<\z@ \advance\Direction\dimen@
7258 \else \advance\Direction-\dimen@ \fi
7259 \count@=\DirectionChar \ifnum\count@<64 \advance\count@64 %
7260 \else \advance\count@-64 \fi \chardef\DirectionChar=\count@
7261 \edef\cosDirection{\if-\cosDirection\else-\cosDirection\fi}%
7262 \edef\sinDirection{\if-\sinDirection\else-\sinDirection\fi}%
7263 \resetupDirection@}
7265 \xydef@\aboveDirection@#1{%
7266 \dimen@=\d@X \d@X=-\d@Y \d@Y=\dimen@
7267 \dimen@=\K@dXdY \K@dXdY=-\K@dYdX \K@dYdX=-\dimen@
7268 \ifdim\d@X<\z@ \def\sd@X{-}\else \def\sd@X{+}\fi
7269 \ifdim\d@Y<\z@ \def\sd@Y{-}\else \def\sd@Y{+}\fi
7270 \dimen@=2\K@ \ifdim 1\Direction<\dimen@\else \dimen@=-6\K@ \fi
7271 \advance\Direction\dimen@
7272 \count@=\DirectionChar \ifnum\count@<96 \advance\count@32 %
7273 \else \advance\count@-96 \fi \chardef\DirectionChar=\count@
7274 \count@=\SemiDirectionChar \ifnum\count@<64 \advance\count@64 %
7275 \else \advance\count@-64 \fi \chardef\SemiDirectionChar=\count@
7276 \let\tmp@=\cosDirection
7277 \edef\cosDirection{\if-\sinDirection\else-\sinDirection\fi}%
7278 \let\sinDirection=\tmp@
7279 \dimen@=#1\relax \d@X=\cosDirection\dimen@ \d@Y=\sinDirection\dimen@
7280 \resetupDirection@}
7282 \xydef@\belowDirection@#1{%
7283 \dimen@=\d@X \d@X=\d@Y \d@Y=-\dimen@
7284 \dimen@=\K@dXdY \K@dXdY=-\K@dYdX \K@dYdX=-\dimen@
7285 \ifdim\d@X<\z@ \def\sd@X{-}\else \def\sd@X{+}\fi
7286 \ifdim\d@Y<\z@ \def\sd@Y{-}\else \def\sd@Y{+}\fi
7287 \dimen@=-2\K@\ifdim 1\Direction<\dimen@\dimen@=6\K@\fi
7288 \advance\Direction\dimen@
7289 \count@=\DirectionChar \ifnum\count@<32 \advance\count@96 %

7290 \else \advance\count@-32 \fi \chardef\DirectionChar=\count@
7291 \count@=\SemiDirectionChar \ifnum\count@<64 \advance\count@64 %
7292 \else \advance\count@-64 \fi \chardef\SemiDirectionChar=\count@
7293 \let\tmp@=\sinDirection
7294 \edef\sinDirection{\if-\cosDirection\else-\cosDirection\fi}%
7295 \let\cosDirection=\tmp@
7296 \dimen@=#1\relax \d@X=\cosDirection\dimen@ \d@Y=\sinDirection\dimen@
7297 \resetupDirection@}
7299 \xydef@\vDirection@(#1,#2)#3{\dimen@ii=#3\relax
7300 \dimen@=#1\dimen@ii \dimen@ii=#2\dimen@ii
7301 \d@X=\cosDirection\dimen@ \advance\d@X-\sinDirection\dimen@ii
7302 \d@Y=\sinDirection\dimen@ \advance\d@Y \cosDirection\dimen@ii
7303 \X@p=\X@c \advance\X@p-\d@X \Y@p=\Y@c \advance\Y@p-\d@Y
7304 \setupDirection@\ignorespaces}

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 p⃗c, \resetupDirerection when the entire direction state is changed in a consistent manner.

7314 \xydef@\resetDirection@{%
7315 \d@X=\X@c\advance\d@X-\X@p \d@Y=\Y@c\advance\d@Y-\Y@p
7316 \let\next@=\resetupDirection@
7317 \ifdim\sd@X\d@X<\z@ \let\next@=\setupDirection@i \fi
7318 \ifdim\sd@Y\d@Y<\z@ \let\next@=\setupDirection@i \fi
7319 \next@}
7321 \xydef@\resetupDirection@{%
7322 \edef\Directiontest@@##1##2{\noexpand\DN@{##2}%
7323 \noexpand\ifdim\noexpand\d@X=\the\d@X\relax
7324 \noexpand\ifdim\noexpand\d@Y=\the\d@Y\relax \noexpand\DN@{##1}%
7325 \noexpand\fi\noexpand\fi \noexpand\next@}}
7327 \xydef@\unsetupDirection@{\def\Directiontest@@##1##2{##2}}

Finally the initial direction: up!

7333 \uDirection@\xydashl@

1.8.2 Edges

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:

0 c is changed to be equal to the point on the edge intersecting with the line segment from p (for 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}!

1 Test whether the center of p, i.e., <X_{p},Y_{p}>, is ‘inside’ the c object (or on the edge). Sets the test \ifInside@ accordingly.

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).

3 c is changed to be equal to the point on the edge furthest in the direction towards p (for P ⟨corner⟩).

Note: This should not change any of A, B, or any component of the state except X_{c} and Y_{c}!

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).

5 Replace c with smallest rectangle that encloses the current object completely.

(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 :-)

7396 \message{edges,}
7398 \xynew@{if}\ifInside@

Points: The simplest shape is none at all – a point.

7406 \xydef@\zeroEdge#1{%
7407 \ifcase#1\relax \or \Inside@false \or \dimen@=\z@
7408 \or \else \Edge@c={\rectangleEdge}\fi}

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.

7420 \xydef@\circleEdge#1{\ifcase#1\expandafter\circleEdge@
7421 \or \expandafter\circleUnder@ \or \dimen@=\R@c
7422 \or \expandafter\circleProp@ \or \expandafter\circleInner@
7423 \else \expandafter\circleOuter@ \fi}
7425 \xydef@\circleEdge@{\DN@{\ellipseEdge@}%
7426 \ifdim\R@c=\L@c\relax \ifdim\U@c=\D@c\relax
7427 \ifdim\R@c=\U@c\DN@{\circlecentredEdge@}%
7428 \else\DN@{\ellipsecentredEdge@}\fi
7429 \fi\fi \next@}
7431 \xydef@\circleProp@{\DN@{\reverseDirection@\ellipseEdge@}%
7432 \ifdim\R@c=\L@c\relax \ifdim\U@c=\D@c\relax
7433 \ifdim\R@c=\U@c\DN@{\reverseDirection@\circlecentredEdge@}%
7434 \else\DN@{\reverseDirection@\ellipsecentredEdge@}\fi
7435 \fi\fi \next@}
7437 \xydef@\circleUnder@{\Inside@false
7438 \ifdim\X@p=\X@c \relax \ifdim\Y@p=\Y@c \Inside@true \fi \fi
7439 \ifInside@ \else \expandafter \circleCentre@ \fi}
7441 \xydef@\circleCentre@{{%
7442 \ifdim\L@c=\R@c \relax\else
7443 \dimen@=\R@c\advance\dimen@-\L@c \divide\dimen@\tw@

7444 \advance\X@c\dimen@ \advance\R@c-\dimen@ \fi
7445 \d@X=\X@c \advance\d@X-\X@p \d@X=\ifdim\d@X<\z@-\fi\d@X
7446 \ifdim\U@c=\D@c\relax \else
7447 \dimen@=\U@c\advance\dimen@-\D@c \divide\dimen@\tw@
7448 \advance\Y@c\dimen@ \advance\U@c-\dimen@ \fi
7449 \d@Y=\Y@c \advance\d@Y-\Y@p \d@Y=\ifdim\d@Y<\z@-\fi\d@Y
7450 \DN@{}\ifdim\d@X>\R@c \relax \else \ifdim\d@Y>\U@c \relax
7451 \else \ifdim\U@c=\R@c \DN@{\circlecentredUnder@}%
7452 \else \DN@{\ellipsecentredUnder@}\fi
7453 \fi\fi \next@}}
7455 \xydef@\circleInner@{\DN@{\ellipseInner@}%
7456 \ifdim\R@c=\L@c\relax \ifdim\U@c=\D@c\relax
7457 \ifdim\R@c=\U@c\DN@{\circlecentredInner@}%
7458 \else\DN@{\ellipsecentredInner@}\fi
7459 \fi\fi \next@}
7461 \xydef@\circleOuter@{\DN@{\ellipseOuter@}%
7462 \ifdim\R@c=\L@c\relax \ifdim\U@c=\D@c\relax
7463 \ifdim\R@c=\U@c\DN@{\circlecentredOuter@}%
7464 \else\DN@{\ellipsecentredOuter@}\fi
7465 \fi\fi \next@}

True circles, centered: Code 0 moves <X_{c},Y_{c}> to the point <X_{c} − R_{c} × cos α,Y_{c} − R_{c} × sin α> where α 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.

7477 \xydef@\circlecentredEdge@{%
7478 \dimen@=-\cosDirection\R@c \advance\X@c\dimen@
7479 \dimen@=-\sinDirection\R@c \advance\Y@c\dimen@}
7481 \xydef@\circlecentredUnder@{%
7482 \loop\ifdim\R@c>100\p@ \circlescale@ \repeat
7483 \edef\tmp@{\expandafter\removePT@\the\R@c}\dimen@=\tmp@\R@c
7484 \edef\tmp@{\expandafter\removePT@\the\d@X}\advance\dimen@-\tmp@\d@X
7485 \edef\tmp@{\expandafter\removePT@\the\d@Y}\advance\dimen@-\tmp@\d@Y
7486 \ifdim\dimen@>\z@ \aftergroup\Inside@true \fi}
7488 %%\xydef@\circlescale@{\divide\R@c\KK@ \divide\d@X\KK@ \divide\d@Y\KK@ }
7489 \xydef@\circlescale@{\divide\R@c\KK@ \divide\d@X\KK@ \divide\d@Y\KK@ }
7491 \xydef@\circlecentredInner@{%
7492 \L@c=\sd@X\cosDirection\R@c \D@c=\sd@Y\sinDirection\R@c
7493 \R@c=\L@c \U@c=\D@c \Edge@c={\rectangleEdge}}
7495 \xydef@\circlecentredOuter@{%
7496 \L@c=\R@c \D@c=\R@c \U@c=\D@c \Edge@c={\rectangleEdge}}

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.

7506 \xydef@\ellipsecentredEdge@{\bgroup \X@p=\X@c \Y@p=\Y@c

7507 \ifdim\U@c>\R@c
7508 \X@c=\cosDirection\U@c \Y@c=\sinDirection\U@c
7509 \quotient@\tmp@\U@c\R@c \X@c=\tmp@\X@c \R@c=\U@c
7510 \else
7511 \X@c=\cosDirection\R@c \Y@c=\sinDirection\R@c
7512 \quotient@\tmp@\R@c\U@c \Y@c=\tmp@\Y@c

7513 \fi

7514 \advance\X@c\X@p \advance\Y@c\Y@p
7515 \setupDirection@ \X@c=\X@p \Y@c=\Y@p \circlecentredEdge@
7516 \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p
7517 \ifdim\U@c>\L@c \quotient@\tmp@\L@c\U@c \d@X=\tmp@\d@X
7518 \else \quotient@\tmp@\U@c\R@c \d@Y =\tmp@\d@Y \fi
7519 \X@c=\X@p \advance\X@c\d@X \Y@c=\Y@p \advance\Y@c\d@Y
7520 \edef\next@{\egroup \X@c=\the\X@c \Y@c=\the\Y@c}\next@ }%
7522 \xydef@\ellipsecentredUnder@{%
7523 \ifdim\R@c>64\p@ \circlescale@ \divide\U@c\KK@
7524 \else \ifdim\U@c>64\p@ \circlescale@ \divide\U@c\KK@ \fi\fi
7525 \edef\tmp@{\expandafter\removePT@\the\R@c}\d@Y=\tmp@\d@Y
7526 \edef\tmp@{\expandafter\removePT@\the\U@c}\d@X=\tmp@\d@X
7527 \R@c=\tmp@\R@c \circlecentredUnder@ }

For elliptical objects the Outer-rectangle retains all the extents, so just change the edge-type.

7534 \xydef@\ellipsecentredOuter@{\Edge@c={\rectangleEdge}}

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.

7543 \xydef@\ellipsecentredInner@{%
7544 \bgroup \X@p=\X@c \Y@p=\Y@c \ellipsecentredEdge@
7545 % \advance\X@c-\X@p \L@c=\ifdim\X@c<\z@-\fi\L@c
7546 \advance\X@c-\X@p \L@c=\ifdim\X@c<\z@-\fi\X@c
7547 % \advance\Y@c-\Y@p \D@c=\ifdim\Y@c<\z@-\fi\D@c
7548 \advance\Y@c-\Y@p \D@c=\ifdim\Y@c<\z@-\fi\Y@c
7549 \edef\next@{\egroup \L@c=\the\L@c \D@c=\the\D@c}\next@
7550 \R@c=\L@c \U@c=\D@c \Edge@c={\rectangleEdge}}

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 \frac{x^{2}}{a^{2}} + \frac{y^{2}}{b^{2}} = 1. Now let (dx, dy) be the displacement from the centre to the reference point; then x = dx + s cos θ and y = dy + s sin θ where s is the distance to (x, y) in the required direction θ. We must find the value of s, presumed to satisfy s ≥ 0.

If a < b we search for a root of

f (\frac{s}{a})  = (d̃x + \frac{s}{a} cos θ)^{2} + (d̃y + \frac{s}{a} \frac{a}{b} sin θ)^{2}
f′ (\frac{s}{a}) = 2 (d̃x + \frac{s}{a} cos θ) cos θ + 2 (d̃y + \frac{s}{a} \frac{a}{b} sin θ) \frac{a}{b} sin θ

where d̃x = dx/a and d̃y = dy/b. By choosing a starting value s_{0} = 2a + 2b the Newton-iteration converges rapidly to the correct root, provided b > 0. If a > b then we solve a similar quadratic in \frac{s}{b}.

To Do: 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.

To Do: 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 …

                          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.

7603 \xydef@\ellipseEdge@{\bgroup
7604 \A@=\R@c \B@=\U@c
7605 \ifdim\R@c=\L@c \d@X=\z@
7606 \else \d@X=.5\R@c \advance\d@X-.5\L@c
7607 \advance\A@\L@c \divide\A@\tw@ \fi
7608 \ifdim\U@c=\D@c \d@Y=\z@
7609 \else \d@Y=.5\U@c \advance\d@Y-.5\D@c
7610 \advance\B@\D@c \divide\B@\tw@ \fi
7611 \bgroup
7612 \L@c=\A@ \U@c=\B@
7613 \R@p=\U@c \advance\R@p\L@c \multiply\R@p\tw@
7614 \ifdim\B@<\A@  \quotient@\tmp@\U@c\L@c \R@c=\tmp@\p@ \D@c=\p@
7615  \quotient@\tmp@\R@p\L@c \R@p=\tmp@\p@
7616 \else
7617 \ifdim\A@<\B@ \quotient@\tmp@\L@c\U@c \D@c=\tmp@\p@ \R@c=\p@
7618  \quotient@\tmp@\R@p\U@c \R@p=\tmp@\p@
7619 \else
7620 \R@c=\p@ \D@c=\p@ \quotient@\tmp@\R@p\U@c \R@p=\tmp@\p@
7621 \fi\fi
7622 \quotient@\sd@X\d@X\L@c \d@X=\sd@X\p@
7623 \quotient@\sd@Y\d@Y\U@c \d@Y=\sd@Y\p@
7624 \loop
7625 \bgroup \U@p=-\p@ \D@p=\z@
7626 \ifdim\R@c<\p@
7627  \edef\tmp@{\expandafter\removePT@\the\R@c}\dimen@=\tmp@\R@p
7628  \advance\d@X\cosDirection\dimen@
7629 \else \advance\d@X\cosDirection\R@p \fi
7630 \edef\sd@X{\expandafter\removePT@\the\d@X}%
7631 \advance\U@p\sd@X\d@X
7632 \ifdim\R@c<\p@
7633  \edef\tmp@{\expandafter\removePT@\the\R@c}\dimen@=\tmp@\d@X
7634  \advance\D@p\cosDirection\dimen@
7635 \else \advance\D@p\cosDirection\d@X \fi

7636 %

7637 \ifdim\D@c<\p@
7638  \edef\tmp@{\expandafter\removePT@\the\D@c}\dimen@=\tmp@\R@p
7639  \advance\d@Y\sinDirection\dimen@
7640 \else \advance\d@Y\sinDirection\R@p \fi
7641 \edef\sd@Y{\expandafter\removePT@\the\d@Y}%
7642 \advance\U@p\sd@Y\d@Y

7643 \ifdim\D@c<\p@
7644  \edef\tmp@{\expandafter\removePT@\the\D@c}\dimen@=\tmp@\d@Y
7645  \advance\D@p\sinDirection\dimen@
7646 \else \advance\D@p\sinDirection\d@Y \fi
7647 \multiply\D@p\tw@
7648 \dimen@=\ifdim\U@p<\z@-\fi\U@p
7649  \ifdim\dimen@<.01\p@ \U@p=\z@
7650  \else
7651  \quotient@\tmp@\U@p\D@p \U@p=\tmp@\p@
7652  \ifdim\U@p<\z@\xywarning@{poor convergence}\U@p=\z@
7653  \else \advance\R@p-\U@p \U@p=\ifdim\U@p<\z@-\fi\U@p
7654  \fi \fi
7655  \edef\next@{\egroup \R@p=\the\R@p \U@p=\the\U@p \D@p=\the\D@p}\next@
7656 \ifdim\U@p>\z@ \repeat
7657 \edef\next@{\egroup \dimen@=\the\R@p}\next@
7658 \edef\tmp@{\expandafter\removePT@\the\dimen@}%
7659 \ifdim\B@<\A@ \dimen@=\tmp@\B@ \else \dimen@=\tmp@\A@ \fi
7660 \dimen@=-\dimen@
7661 \advance\X@c\cosDirection\dimen@
7662 \advance\Y@c\sinDirection\dimen@
7663 \edef\next@{\egroup \X@c=\the\X@c \Y@c=\the\Y@c}\next@ }%

The ‘Under’ procedure is identical to the centered version.

7669 \xydef@\ellipseOuter@{\Edge@c={\rectangleEdge}}
7671 \xydef@\ellipseInner@{%
7672 \bgroup \X@p=\X@c \Y@p=\Y@c \ellipseEdge@
7673 \d@X=\X@c\advance\d@X-\X@p
7674 \ifdim\d@X>\z@ \R@p=\d@X \L@p=\R@p
7675 \ifdim\L@c=\R@c\else\advance\L@p\L@c \advance\L@p-\R@c \fi
7676 \else \L@p=-\d@X \R@p=\L@p
7677 \ifdim\L@c=\R@c \else\advance\R@p\R@c \advance\R@p-\L@c \fi

7678 \fi

7679 \d@Y=\Y@c\advance\d@Y-\Y@p
7680 \ifdim\d@Y>\z@ \U@p=\d@Y \D@p=\U@p
7681 \ifdim\D@c=\U@c\else\advance\D@p\D@c \advance\D@p-\U@c \fi
7682 %\else \D@p=-\d@X \R@p=\D@p
7683 \else \D@p=-\d@Y \U@p=\D@p                     % <<<<<<========
7684 \ifdim\D@c=\U@c\else\advance\U@p\U@c \advance\U@p-\D@c \fi

7685 \fi

7686 \edef\next@{\egroup
7687 \L@c=\the\L@p \D@c=\the\D@p \R@c=\the\R@p \U@c=\the\U@p}%
7688 \next@ \Edge@c={\rectangleEdge}}

Rectangles:

Rectangles intersection is slightly more complicated and handled separately for the horizontal and vertical case.

7697 \xydef@\rectangleEdge#1{\ifcase#1\expandafter\rectangleEdge@
7698 \or \expandafter\rectangleUnder@ \or \expandafter\rectangleDist@

7699 \or \expandafter\rectangleProp@ %%%\or \expandafter\rectangleInner@ BUG!
7700 \else \relax \fi}

Bug: no ‘Inner’ for rectangles!

7706 % \rectangleEdge@
7707 %       Sets <X,Y> to the intersection of a line from <X-dX,Y-dY> to <X,Y>
7708 %       and the rectangle from <X-L,Y-D> to <X+R,Y+U>:

7709 %

7710 %       %1a     dY<0, dX<0:     X := X + min{R, U*|dX/dY|},
7711 %                               Y := Y + min{U, R*|dY/dX|};
7712 %         b     dY<0, dX=0:     Y := Y + U;
7713 %         c     dY<0, dX>0:     X := X - min{L, U*|dX/dY|},
7714 %                               Y := Y + min{U, L*|dY/dX|};

7715 %

7716 %       %2a     dY=0, dX<0:     X := X + R;
7717 %         b     dY=0, dX=0:     ;
7718 %         c     dY=0, dX>0:     X := X - L;

7719 %

7720 %       %3a     dY>0, dX<0:     X := X + min{R, D*|dX/dY|},
7721 %                               Y := Y - min{D, R*|dY/dX|};
7722 %         b     dY>0, dX=0:     Y := Y - D;
7723 %         c     dY>0, dX>0:     X := X - min{L, D*|dX/dY|},
7724 %                               Y := Y - min{D, L*|dY/dX|};

7725 %

7726 %       %4 \resetupDirection@ to register that even though dX,dY changed all
7727 %          Direction parameters are is still valid!

7728 %

7729 %       NOTE: d=0 really means |d| < .05pt.

7730 %

7731 \xydef@\rectangleEdge@{%
7732 \ifdim\d@Y<-.05\p@ \rectangleEdge@i                                     %1
7733 \else\ifdim\d@Y<.05\p@ \rectangleEdge@ii                                %2
7734 \else \rectangleEdge@iii\fi\fi
7735 \resetupDirection@}
7737 \xydef@\rectangleEdge@i{%
7738 \ifdim\d@X<-.05\p@
7739 \settomin@\X@c+\R@c\U@c\d@X\d@Y \settomin@\Y@c+\U@c\R@c\d@Y\d@X%1a
7740 \else\ifdim\d@X<.05\p@ \advance\Y@c\U@c                                 %1b
7741 \else \settomin@\X@c-\L@c\U@c\d@X\d@Y \settomin@\Y@c+\U@c\L@c\d@Y\d@X   %1c
7742 \fi\fi}
7744 \xydef@\rectangleEdge@ii{%
7745 \ifdim\d@X<-.05\p@ \advance\X@c\R@c                                     %2a
7746 \else\ifdim\d@X<.05\p@                                                  %2b
7747 \else \advance\X@c-\L@c                                                 %2c
7748 \fi\fi}
7750 \xydef@\rectangleEdge@iii{%
7751 \ifdim\d@X<-.05\p@
7752 \settomin@\X@c+\R@c\D@c\d@X\d@Y \settomin@\Y@c-\D@c\R@c\d@Y\d@X%3a
7753 \else\ifdim\d@X<.05\p@ \advance\Y@c-\D@c                                %3b

7754 \else \settomin@\X@c-\L@c\D@c\d@X\d@Y \settomin@\Y@c-\D@c\L@c\d@Y\d@X   %3c
7755 \fi\fi}
7757 \xydef@\settomin@#1#2#3#4#5#6{%
7758 % Perform d := #2 min{#3, #4*|#5/#6|}; #1 := #1+d ...
7759 \edef\nextii@{\A@=\the\A@ \B@=\the\B@}\quotient@\next@{#5}{#6}\nextii@
7760 \dimen@=\sd@X\sd@Y\next@#4\relax
7761 \ifdim#3<\dimen@ \dimen@=#3\fi \advance#1#2\dimen@}

Checking that p is under is simpler: Normally it is not but if c = p or (−L_{c} < X_{p} − X_{c} < R_{c} and −D_{c} < Y_{p} − Y_{c} < U_{c}) then it is.

7769 \xydef@\rectangleUnder@{\Inside@false
7770 \ifdim\X@p=\X@c \ifdim\Y@p=\Y@c \Inside@true \fi\fi
7771 \ifInside@ \else
7772 \dimen@=\X@p \advance\dimen@-\X@c
7773 \ifdim \dimen@>-\L@c \relax \ifdim\dimen@<\R@c
7774 \dimen@=\Y@p \advance\dimen@-\Y@c
7775 \ifdim \dimen@>-\D@c \relax \ifdim\dimen@<\U@c
7776  \Inside@true
7777 \fi\fi\fi\fi\fi }

Calculating the width is like computing the edge point, just simpler: (l.7787) Set A to the horizontal and B to the vertical distance applicable; if either is zero (or close) use the other unmodified . (l.7796) If both nonzero use min(A/ cos α, B/ sin α) where α is the current angle.

7787 \xydef@\rectangleDist@{\let\next@=\rectangleDist@i
7788 \ifdim\d@X<-.05\p@ \dimen@=\R@c
7789 \else\ifdim\d@X<.05\p@ \dimen@=\z@ \DN@{\dimen@=\dimen@ii}%
7790 \else \dimen@=\L@c \fi\fi
7791 \ifdim\d@Y<-.05\p@ \dimen@ii=\U@c
7792 \else\ifdim\d@Y<.05\p@ \DN@{}%
7793 \else \dimen@ii=\D@c \fi\fi
7794 \next@}
7796 \xydef@\rectangleDist@i{
7797 \begingroup \quotient@\next\p@{\sd@X\cosDirection\p@}%
7798 \edef\next{\endgroup \dimen@=\next\dimen@}\next
7799 \begingroup \quotient@\next\p@{\sd@Y\sinDirection\p@}%
7800 \edef\next{\endgroup \dimen@ii=\the\dimen@ii}\next
7801 \ifdim\dimen@ii<\dimen@ \dimen@=\dimen@ii \fi}

Setting c to the ‘proportional edge point’ is straight out of v2.6’s \setlabel@@ macro…

7808 % First rotate to opposite direction.
7810 % Then compute Leftf,Upf [\next@,\nextii@]:
7811 %               0,(D-2K)/2K     for  2K < D <= 4K       [right]
7812 %       (2K-D)/2K,0             for   0 < D <= 2K       [down]
7813 %               1,-D/2K         for -2K < D <= 0        [left]
7814 %       (D+4K)/2K,1             for -4K < D <= -2K      [up]
7816 % Finally set <X,Y> to
7817 %       < X - L + Leftf*(R+L) , Y + U - Upf*(D+U) >
7819 \xydef@\rectangleProp@{%

7820 \enter@{\A@=\the\A@ \B@=\the\B@ \DirectionfromtheDirection@}%
7821 \reverseDirection@
7822 \dimen@=1\Direction \count@=\K@ \multiply\count@\tw@
7823 \ifnum \Direction>\count@
7824 \DN@{0}%
7825 \advance\dimen@-2\K@ \quotient@\nextii@{\dimen@}{2\K@}%
7826 \else\ifnum \Direction>\z@
7827 \dimen@=-\dimen@ \advance\dimen@2\K@ \quotient@\next@{\dimen@}{2\K@}%
7828 \DNii@{0}%
7829 \else\ifnum \Direction>-\count@
7830 \DN@{1}%
7831 \quotient@\nextii@{-\dimen@}{2\K@}%
7832 \else
7833 \advance\dimen@4\K@ \quotient@\next@{\dimen@}{2\K@}%
7834 \DNii@{1}%
7835 \fi\fi\fi
7836 \advance\X@c-\L@c \dimen@=\L@c \advance\dimen@\R@c
7837 \ifdim\dimen@=\z@ \advance\X@c 2\L@c \else \advance\X@c\next@\dimen@ \fi
7838 \advance\Y@c+\U@c \dimen@=\D@c \advance\dimen@\U@c
7839 \ifdim\dimen@=\z@ \advance\Y@c-2\U@c \advance\Y@c\Upness@\U@c
7840 \else \advance\Y@c-\nextii@\dimen@ \fi
7841 \leave@}

1.8.3 Connections

7851 \message{connections;}

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:

\Invisible@@, \Hidden@@, and \Drop@@: as for ⟨object⟩.

\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.

\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).

\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).

\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).

\Cintercept@@: Set c to a zerosized object at the point where the connection crosses the straight line from p to c (the !{… } ⟨place⟩ component).

\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:

1. \Connect@@ sets lastbreak := p and nextbreak := c

2. The commands \Cslidec@@, \Cslidep@@, and \Cintercept@@, set nextbreak logically to the position that is obtained by the manipulation.

3. \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).

4. The command \Clast@@ typesets from lastbreak and the remainder of the connection, and resets lastbreak := p and nextbreak := c.

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… are rather simple – in particular they just merge with zerosized objects at the locations cutoff locations (this was inherited from the broken arrow code ◯_{¨⌣}).

7925 \xydef@\Creset@@{}
7926 \xydef@\Cshavep@@{\noCshavep@@}
7927 \xydef@\Cshavec@@{\noCshavec@@}
7928 \xydef@\Cslidep@@{\noCslidep@@}
7929 \xydef@\Cslidec@@{\noCslidec@@}
7930 \xydef@\Calong@@{\noCalong@@}
7931 \xydef@\Cintercept@@{\noCintercept@@}
7932 \xydef@\Cbreak@@{\noCbreak@@}
7933 \xydef@\Clast@@{\noClast@@}
7935 \xylet@\lastbreak@@=\empty
7937 \xydef@\noCshavep@@{\setupDirection@
7938 \enter@{\cfromthec@ \DirectionfromtheDirection@}%
7939 \reverseDirection@ \cfromp@ \the\Edge@c\z@
7940 \pfromc@ \leave@ \resetDirection@}
7942 \xydef@\noCshavec@@{\setupDirection@ \the\Edge@c\z@ \resetDirection@}
7944 \xydef@\noCslidep@@#1{\dimen@=#1\relax
7945 \advance\X@p\cosDirection\dimen@ \advance\Y@p\sinDirection\dimen@
7946 \resetDirection@}
7948 \xydef@\noCslidec@@#1{\dimen@=#1\relax
7949 \advance\X@c\cosDirection\dimen@ \advance\Y@c\sinDirection\dimen@
7950 \resetDirection@}
7952 \xydef@\noCalong@@#1{%
7953 \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
7954 \resetupDirection@}

Next the intercept method that just uses \intersect@.

7960 \xydef@\noCintercept@@{\enter@{\pfromthep@}%
7961 \begingroup\Creset@@ \edef\tmp@{\endgroup
7962 \X@origin=\the\X@p \Y@origin=\the\Y@p \R@c=\the\d@X \U@c=\the\d@Y}\tmp@
7963 \loop@\dimen@=\ifdim\R@c<\z@-\fi\R@c \advance\dimen@\ifdim\U@c<\z@-\fi\U@c
7964 \ifdim\dimen@>10\p@ \advance\R@c \ifdim\R@c<\z@-\fi 16sp \divide\R@c\KK@
7965 \advance\U@c \ifdim\U@c<\z@-\fi 16sp \divide\U@c\KK@ \repeat@
7966 \intersect@ \leave@}

And finally the dummy ‘break’ method which of course does nothing except the required shifting.

7973 \xydef@\noCbreak@@{\edef\lastbreak@@{\cfromthec@}}
7974 \xydef@\noClast@@{\Creset@@ \edef\lastbreak@@{\cfromthep@}}

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:

7986 \xydef@\no@@{\setupDirection@ \edef\lastbreak@@{\cfromthep@}%
7987 \enter@{\cfromthec@\pfromthep@\DirectionfromtheDirection@}%
7988 \edef\Creset@@{\cfromthec@ \pfromthep@ \DirectionfromtheDirection@}%
7989 \edef\next@{{\sd@X}{\sd@Y}}\expandafter\straightcheckoverlap@\next@
7990 \setupDirection@ \the\Edge@c\z@
7991 \swap@\reverseDirection@\the\Edge@c\z@\swap@\reverseDirection@
7992 \resetDirection@
7993 \edef\Cshavep@@{\DirectionfromtheDirection@
7994 \pfromthep@\noexpand\resetDirection@}%
7995 \edef\Cshavec@@{\DirectionfromtheDirection@
7996 \cfromthec@\noexpand\resetDirection@}%
7997 \leave@
7998 \def\Cslidep@@{\noCslidep@@}\def\Cslidec@@{\noCslidec@@}%
7999 \def\Calong@@{\noCalong@@}\def\Cintercept@@{\noCintercept@@}%
8000 \def\Cbreak@@{\noCbreak@@}\def\Clast@@{\noClast@@}\noinsert@}
8002 \xydef@\noinsert@{\ifHidden@\else
8003 \ifdim\Y@c>\Y@max \Y@max=\Y@c \fi  \ifdim\Y@p>\Y@max \Y@max=\Y@p \fi
8004 \ifdim\Y@c<\Y@min \Y@min=\Y@c \fi  \ifdim\Y@p<\Y@min \Y@min=\Y@p \fi
8005 \ifdim\X@c>\X@max \X@max=\X@c \fi  \ifdim\X@p>\X@max \X@max=\X@p \fi
8006 \ifdim\X@c<\X@min \X@min=\X@c \fi  \ifdim\X@p<\X@min \X@min=\X@p \fi
8007 \fi}

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:

\lastobjectbox@: box to fill with; assumed to be ‘trimmed’ to have only the size needed for the filler; size is w × (h + d)).

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.

Procedure: [l.8046] setup direction parameters, clear the break state, and define the \Creset@@ macro to reestablish this initial state; [l.8049] build macro to discover if the edges of the objects overlap (it edges were removed); [??] move both p, c to the edges of the objects… and define the \Cshave*@@ macros accordingly; [l.8058] choose either to ignore the connection if requested or there is overlap between the objects of choose either vbox or hbox version (see below)…; and [l.8063] build \Calong@@, \Cbreak@@, and \Clast@@ macros, and reset pc.

Note: Assumes that the direction is not tampered with between Creset is defined and used…

8043 \xydef@\Spread@@{}
8044 \xydef@\checkoverlap@@{}
8046 \xydef@\straight@#1{\setupDirection@ \def\Spread@@{#1}%

8047 \edef\Creset@@{\cfromthec@ \pfromthep@  \DirectionfromtheDirection@}%
8048 \edef\lastbreak@@{\cfromthep@}%
8049 \edef\next@{{\sd@X}{\sd@Y}}\expandafter\straightcheckoverlap@\next@
8050 \setupDirection@ \the\Edge@c\z@
8051 \swap@\reverseDirection@\the\Edge@c\z@\swap@\reverseDirection@
8052 \resetDirection@
8053 \edef\Cshavep@@{\DirectionfromtheDirection@
8054 \pfromthep@\noexpand\resetDirection@}%
8055 \edef\Cshavec@@{\DirectionfromtheDirection@
8056 \cfromthec@\noexpand\resetDirection@}%
8057 \noinsert@
8058 \straight@typeset
8059 \def\Cbreak@@{\straightCbreak@}\def\Clast@@{\straightClast@}%
8060 % \DN@{\solidSpread@}\ifx\next@\Spread@@
8061 %  \checkXy@rules@\solidhrule@pre\solidvrule@pre\relax
8062 % \fi
8063 \def\Cslidep@@{\noCslidep@@}\def\Cslidec@@{\noCslidec@@}
8064 \def\Calong@@{\noCalong@@}\def\Cintercept@@{\noCintercept@@}%
8065 \Creset@@}
8067 \xydef@\straightcheckoverlap@#1#2{\def\checkoverlap@@{%
8068 \ifdim#1\X@p>#1\X@c \let\next@=\relax \fi
8069 \ifdim#2\Y@p>#2\Y@c \let\next@=\relax \fi}}
8071 \xydef@\straight@typeset{%
8072 \ifInvisible@ \let\next@=\relax
8073 \else\ifdim 1\Direction<-2\K@ \DN@{\straightv@}%
8074 \else\ifdim 1\Direction<\z@   \DN@{\straighth@}%
8075 \else\ifdim 1\Direction<2\K@  \DN@{\straightv@}%
8076 \else                         \DN@{\straighth@}%
8077 \fi\fi\fi\fi \checkoverlap@@ \next@}

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.

8091 \xylet@\nextbreak@@=\empty
8093 \xydef@\straightCbreak@{\connectRestore@
8094 \edef\nextbreak@@{\cfromthec@}%
8095 \Creset@@ \swap@ \the\Edge@c4\enter@{\cmergethec@}\lastbreak@@ \leave@
8096 \swap@ \the\Edge@c4\enter@{\cmergethec@}\nextbreak@@ \leave@
8097 \setupDirection@
8098 \the\Edge@c\z@
8099 \swap@ \reverseDirection@ \the\Edge@c\z@ \swap@ \reverseDirection@
8100 \resetDirection@ \noinsert@ \straight@typeset
8101 \Creset@@ \let\lastbreak@@=\nextbreak@@}
8103 \xydef@\straightClast@{\connectRestore@
8104 \Creset@@ \swap@ \the\Edge@c4\enter@{\cmergethec@}\lastbreak@@ \leave@

8105 \swap@
8106 \setupDirection@
8107 \the\Edge@c\z@
8108 \swap@\reverseDirection@ \the\Edge@c\z@ \swap@\reverseDirection@
8109 \resetDirection@ \noinsert@ \straight@typeset
8110 \Creset@@ \edef\lastbreak@@{\cfromthep@}}

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:

[??] start box; [l.8151] compute initial adjustment (X right and Y up) and A := w, B := h + d, N = ⌊(⌋ |dX | /A), and run user supplied Spread; [l.8155] adjust first filler position horizontally: if dX > 0 then X := X − w; [l.8156] adjust first filler vertically: Y := Y − sdX × L × (dY /dX ) × w where L = ifdX > 0then(1 − Leftness)elseLeftness; [l.8160] recompute the move dimensions (A right and B up): A := −sdX (|dX| − w)/(N − 1), B := sdY |sdX (w) × dY /dX − dY | /(N − 1), and set the filler box to have w := A; [l.8166] 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!

8149 \xydef@\straighth@{\setbox\z@=\hbox{%
8150 \setbox8=\copy\lastobjectbox@
8151 \A@=\wd8\relax \B@=\dp8\relax \advance\B@\ht8\relax
8152 \ifdim \A@=\z@ \count@@=\m@ne
8153 \else \dimen@=\sd@X\d@X \divide\dimen@\A@ \count@@=\dimen@ \fi
8154 \Spread@@
8155 \ifdim\d@X>\z@ \advance\X@c-\wd8\relax\fi
8156 \dimen@=-\sd@X\wd8\relax
8157 \multiply\dimen@\K@dYdX \divide\dimen@\K@
8158 \ifdim\d@X>\z@ \advance\Y@c\dimen@ \advance\Y@c-\Leftness@\dimen@
8159 \else \advance\Y@c\Leftness@\dimen@ \fi
8160 \dimen@=\wd8\relax \A@=\sd@X\d@X \advance\A@-\dimen@
8161 \B@=\sd@X\dimen@ \multiply\B@\K@dYdX \divide\B@\K@
8162 \advance\B@-\d@Y \B@=\sd@Y\B@
8163 \count@=\count@@ \advance\count@\m@ne
8164 \ifnum\z@<\count@ \divide\A@\count@ \divide\B@\count@ \fi
8165 \A@=-\sd@X\A@ \B@=\sd@Y\B@ \wd8=\A@
8166 \kern\X@c \count@=\z@
8167 \loop@\ifnum\count@<\count@@ \advance\count@\@ne
8168 \raise\Y@c\copy8\relax \advance\Y@c\B@ \repeat@}%
8169 \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}

The mosly vertical is analogous. Bug: \dimen@ holds the unadjusted h+d throughout – somehow it works anyway!

8176 \xydef@\straightv@{\setbox\z@=\vtop{%
8177 \setbox8=\copy\lastobjectbox@
8178 \A@=\wd8\relax \B@=\dp8\relax \advance\B@\ht8\relax
8179 \ifdim \B@=\z@ \count@@=\m@ne
8180 \else \dimen@=\sd@Y\d@Y \divide\dimen@\B@ \count@@=\dimen@ \fi

116 CHAPTER 1. KERNEL: XY.DOC

8181 \Spread@@
8182 \dimen@=\dp8\relax \advance\dimen@\ht8\relax
8183 \B@=\sd@Y\d@Y \advance\B@-\dimen@
8184 \A@=\sd@Y\dimen@ \multiply\A@\K@dXdY \divide\A@\K@ \advance\A@-\d@X
8185 \A@=\sd@X\A@ \count@=\count@@ \advance\count@\m@ne
8186 \ifnum\z@<\count@ \divide\B@\count@ \divide\A@\count@ \fi
8187 \B@=\sd@Y\B@ \A@=\sd@X\A@ \ht8=\B@ \dp8=\z@
8188 \ifdim\d@Y<\z@
8189 \advance\Y@c\dimen@ \advance\Y@c\Upness@\B@
8190 \else
8191 \advance\dimen@\Upness@\B@ \advance\Y@c-\dimen@ \advance\Y@c\B@

8192 \fi

8193 \advance\Y@c\B@
8194 \ifdim\d@X<\z@ \else \advance\X@c-\wd8\relax \fi
8195 \null \kern-\Y@c \count@=\z@
8196 \loop@\ifnum\count@<\count@@ \advance\count@\@ne
8197 \nointerlineskip \moveright\X@c\copy8\relax \advance\X@c\A@
8198 \repeat@}%
8199 \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}

End & log

XY-pic ends with a message saying so.

8211 \message{ Xy-pic loaded}\xyuncatcodes \endinput

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.

8219 % $Log: xy.doc,v $
8220 % Revision 3.7  1999/02/16 15:12:50  krisrose
8221 % Interim release (Y&Y fonts now free).

8222 %

8223 % Revision 3.6  1998/03/06 01:28:05  krisrose
8224 % Releasing (with Y&Y fonts).

8225 %

8226 % Revision 3.5  1997/05/28 13:05:01  krisrose
8227 % Fixed missing breaks bug.

8228 %

8229 % Revision 3.4  1997/05/18 01:14:25  krisrose
8230 % Essential bugfixes.

8231 %

8232 % Revision 3.3  1996/12/19 03:31:56  krisrose
8233 % Maintenance release

8234 %

8235 % Revision 3.2  1995/09/19  18:22:27  kris
8236 % Bug fix release.

8237 %

8238 % Revision 3.1  1995/09/05  20:31:32  kris
8239 % Releasing!

8241 % Revision 3.0  1995/07/07  20:14:21  kris
8242 % Major release w/new User's Guide!

8243 %

8244 % Revision 2.14  1995/07/05  22:20:09  kris
8245 % Buglets...

8246 %

8247 % Revision 2.13  1995/07/04  15:11:17  kris
8248 % Ready to release v3?

8249 %

8250 % Revision 2.12  1994/10/25  11:55:12  kris
8251 % Interim release just before v3 [works with AMS-LaTeX 1.2]...

8252 %

8253 % Revision 2.11  1994/07/05  10:37:32  kris
8254 % Third 3beta release [bug fixes].
8255 % Experimental graph feature included (for ECCT-94 presentation).

8256 %

8257 % Revision 2.10  1994/06/15  12:55:07  kris
8258 % Second 3beta release: bug fixes.

8259 %

8260 % Revision 2.9  1994/06/09  14:59:19  kris
8261 % Release 3beta.

8262 %

8263 % Revision 2.8  1994/04/11  09:31:09  kris
8264 % Second (bug fix) 3alpha release [corrected].

8265 %

8266 % Revision 2.7  1994/03/08  02:06:01  kris
8267 % Release 3alpha.

8268 %

8269 % Revision 2.6.9.1  1994/03/07  04:22:46  kris
8270 % Last internal 3alpha and pre-2.7 release.

8271 %

8272 % MAJOR REWRITE and REORGANISATION:
8273 % File xypic.doc split into separate files: xy.doc for `kernel' and other
8274 % files with the `extensions' and `features'.
8275 % Documented in special DOCMODE LaTeX-based format supported by xydoc.sty.

8276 %

8277 % Revision 2.6.1.1  1992/07/01  07:08:24        kris
8278 % Send to EuroTeX '92...

8279 %

8280 % Revision 2.6  1992/06/24  01:23:34  kris
8281 % Added hooks using font xyqc10.
8282 % Added new POSitions: * and !.
8283 % Added triple lines \Ssolid and \Ddashed.

8284 %

8285 % Revision 2.5  1992/02/24  03:30:54  kris
8286 % Fixed bugs in \Direction calculation logic...
8287 % Added (FACTOR) to \rotate to allow arbitrary rotation.
8288 % ` intermediate points now accept an optional /RADIUS argument.
8289 % Added \Tip with wide tip.

8290 % [See ChangeLog for further details].

8291 %

8292 % Revision 2.4  1992/01/22  02:15:10  kris
8293 % Fixed bugs [with thanks]:
8294 % No spurious arrow heads with LaTeX: \pit now undefined [Werner Struckmann]
8295 % \Solid works: sets \Density [Dave Bowen]
8296 % Short diagonal lines work...major rewrite of \connectv@ [Eric Domenjoud]

8297 %

8298 % Revision 2.3  1992/01/13  23:28:12  kris
8299 % Swapped definitions of \ddtoX and \uutoX [found by Nico Verwer].
8300 % Diagonal lines were wrong [Eric Domenjoud].

8301 %

8302 % Revision 2.2  1992/01/09  04:05:40  kris
8303 % Still problems with rules in frames and horizontal/vertical \solids. Grrr.

8304 %

8305 % Revision 2.1  1992/01/02  14:54:07  kris
8306 % Release version.

8307 %

8308 % Revision 1.40  1991/12/17 04:53:23 kris
8309 % Version distributed as `final draft' on Usenet.

Extensions

This chapter describes the options that provide extensions to the kernel, i.e., support facilities that are not obtainably using the kernel. Most such features are only approximated, relying on a driver for the implementation.

2.1 Curve and Spline extension

Vers. 3.7 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This option provides XY-pic with the ability to typeset spline curves by constructing curved connections using arbitrary directional objects and by encircling objects similarly. Warning: Using curves can be quite a strain on TEX’s memory; you should therefore limit the length and number of curves used on a single page. Memory use is less when combined with a backend capable of producing its own curves; e.g., the PostScript backend).

Header:

1 %% $Id: xycurve.doc,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %%
3 %% Xy-pic ``Curves and Splines'' extension.
4 %% Copyright (c) 1993-1997 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997 Kristoffer H. Rose  <krisrose@ens-lyon.fr>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,

22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{curve}{Curve and Spline extension}{\stripRCS$Revision: 3.7 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

2.1.1 Curved connections

49 \message{curve,}

Simple ways to specify curves in XY-pic are as follows:

**\crv{⟨poslist⟩} curved connection
**\crvs{⟨dir⟩} get ⟨poslist⟩ from the stack
\curve{⟨poslist⟩} as a ⟨decor⟩ation

in which ⟨poslist⟩ is a list of valid ⟨pos⟩itions. The decoration form \curve is just an abbreviation for \connect\crv. As usual, the current p and c are used as the start and finish of the connection, respectively. Within ⟨poslist⟩ the ⟨pos⟩itions are separated by &. A full description of the syntax for \crv is given in figure 2.1.

[figure: A; B; 0; 1; 2; 4]

We need a counter to track the number of control points, (i.e. the number of ⟨pos⟩s in ⟨poslist⟩) and provide a macro to read it. Also a token list which will store the vital information for later use, to allow curved connections to work properly.

84 \xynew@{count}\crv@cnt@
85 \xydef@\xynumctrlpts@{\the\crv@cnt@}
86 \xynew@{toks}\crvpts@

If ⟨poslist⟩ is empty a straight connection is computed. When the length of ⟨poslist⟩ is one or two then the curve is uniquely determined as a single-segment Bézier quadratic or cubic spline. The tangents at p and c are along the lines connecting with the adjacent control point. With three or more ⟨pos⟩itions a cubic B-spline construction is used. Bézier cubic segments are calculated from the given control points.

102 \xydef@\setcurve@{%
103 \edef\xysplineparams@{%
104  \expandafter\noexpand\csname params@\endcsname}%
105 \edef\xysplineedges@{%

106  \expandafter\noexpand\csname edges@\endcsname}%
107 \edef\xycrvcnt@{%
108  \expandafter\noexpand\csname crvcnt@\endcsname}%
109 \expandafter\edef\xycrvcnt@{\number\crv@cnt@}%
110 \ifcase\crv@cnt@
111 \expandafter\xycvxhull@\or
112 \expandafter\xyquadbezier@\or
113 \expandafter\xycubicbezier@\or
114 \expandafter\xybspline@iii\or
115 \expandafter\xybspline@iv\else
116 \expandafter\xybspline@
117 \fi}

The previous picture was typeset using:

\xy (0,20)*+{A};(60,0)*+{B}
**\crv{}
**\crv{(30,30)}
**\crv{(20,40)&(40,40)}
**\crv{(10,20)&(30,20)&(50,-20)&(60,-10)}
\endxy

except for the labels, which denote the number of entries in the ⟨poslist⟩. (Extending this code to include the labels is set below as an exercise).

The ?-operator of §1.3 (note 1.3h) is used to find arbitrary ⟨place⟩s along a curve in the usual way.

Exercise 2.1: Extend the code given for the curves in the previous picture so as to add the labels giving the number of control points.

Using ? will set the current direction to be tangential at that ⟨place⟩, and one can ⟨slide⟩ specified distances along the curve from a found ⟨place⟩ using the ?… /⟨dimen⟩/ notation:

[figure: A; B; ⊕; x; ⊕; x′; ⊗; Q; P]

Exercise 2.2: Suggest code to produce something like the above picture; the spline curve is the same as in the previous picture. Hints: The line is 140pt long and touches 0.28 of the way from A to B and the x is 0.65 of the way from A to B.

The positions in ⟨poslist⟩ specify control points which determine the initial and final directions of the curve—leaving p and arriving at c—and how the curve behaves in between, using standard spline constructions. In general, control points need not lie upon the actual curve.

A natural spline parameter varies in the interval [0, 1] monotonically along the curve from p to c. This is used to specify ⟨place⟩s along the curve, however there is no easy relation to arc-length. Generally the parameter varies more rapidly where the curvature is greatest. The following diagram illustrates this effect for a cubic spline of two segments (3 control points).

[figure: A; B; (<); (>); .1; .9; .2; .8; .3; .7; .4; .6; .5]

Exercise 2.3: Write code to produce a picture such as the one above. (Hint: Save the locations of places along the curve for later use with straight connections.)

To have the same ⟨pos⟩ occuring as a multiple control point simply use a delimiter, which leaves the ⟨pos⟩ unchanged. Thus \curve{⟨pos⟩&} uses a cubic spline, whereas \curve{⟨pos⟩} is quadratic.

Repeating the same control point three times in succession results in straight segments to that control point. Using the default styles this is an expensive way to get straight lines, but it allows for extra effects with other styles.

Curve Objects: At present the syntax is supported for using a \curve object only as a decoration, constructed from a \crv object used as a connection.

256 \xydef@\curve{\connect\crv}

The more general \crv object currently works as a connection. In future this object-type will be extended to allow closed curves as the boundaries of objects.

264 \xydef@\crv#1#{\hbox \bgroup \crvresetbreaks@ \initshape@
265 \def\pure@crv{\crv@saveStyles@}\crv@{#1}}
267 \xydef@\crv@#1#2{%
268 \DN@{#1}\ifx\empty\next@
269 \DN@{\def\afterCURVEaction@{}\parsecurve@\xycurve@@}%
270 \else\DN@{\parseCURVE@#1\parsecurve@\curveSTYLE@}\fi
271 \next@ #2\@endcurve\endcrv@ }
273 \xydef@\curveSTYLE@{\xycurve@@}%  default style
274 \xydef@\afterCURVEaction@{}%  default after-curve action
275 \xydef@\@endcurve{}%
276 \xydef@\endcrv@@{\endcrv@\POS}%
277 \xydef@\pure@crv{\relax}

The \@endcurve inserted here ensures that subsequent parsing with \checkendcurve@ (see below) will terminate cleanly.

The \crvs object has restricted functionality with choice of styles and is always used for curves only. It has a single braced argument which can be used to set curve styles. Its main use is for retypesetting different portions of the same curve, for example the subsegments of a curved arrow/path segment.

This is done by first examinining \bstartPLACE@. If \relax or undefined, then the curve is set using \@crv@ to decide the style. If \bstartPLACE@ is \empty then the curve is fully processed as a connection but nothing is actually typeset; this is used by curved arrows where the curve is first set as “invisible” before breaks and labels are processed. When \bstartPLACE@ contains a number, normally within the range 0 to 1, this is interpreted as a ⟨place⟩ along a curved connection that has already been established. No typesetting may occur before this ⟨place⟩.

In this case the control point information is discarded since the curve can be recovered using \splinereset@. The current p and c are no longer the endpoints of the curve but are ⟨pos⟩itions along the curve between which the typesetting should occur. The value of \bstartPLACE@ is typically a ⟨place⟩ along the curve which is within the ⟨pos⟩ at p. It is used to help locate the edge of this ⟨pos⟩ where typesetting should commence. Similarly \bendPLACE@ is typically a ⟨place⟩ along the curve which is within the ⟨pos⟩ at c.

314 \xywarnifdefined\crv@normaltemplate
315 \xywarnifdefined\crv@othertemplate
316 \xywarnifdefined\crv@specialtemplate@@
317 {\xyuncatcodes \catcode`\@=11 \catcode`\#=6
318 \gdef\crv@normaltemplate#1{{}{~**#1\xy@@crvaddstack@}}
319 \gdef\crv@othertemplate#1{{}{~*=<2\jot>{}~**#1\xy@@crvaddstack@}}
320 \gdef\crv@specialtemplate@@#1{{}{~**\dir{#1}\xy@@crvaddstack@}}

321 }

323 \xydef@\crvs#1#{\hbox \bgroup \def\pure@crv{\relax}\crvs@{#1}}%
324 \xydef@\crvi#1#{\hbox \bgroup \def\pure@crv{\relax}\invisbreaks@ \crvs@{#1}}%
326 \xydef@\crvs@#1{\DN@{\initshape@ \@crv@{#1}}%
327 \def\crv@defaultshape{-}%
328 \ifx\bstartPLACE@\relax \else
329 \ifx\bstartPLACE@\empty \Invisible@true \else
330 \splinetrace@{bstartPLACE@=\bstartPLACE@, bendPLACE@=\bendPLACE@}%
331 \DN@{\let\xy@@crvaddstack@=\xy@@samecurve@
332  \let\saveshape@=\savesame@
333  \let\savectrlptsnum@=\relax
334  \let\startxycurve@=\recovercurve@
335  \crv@cnt@=\xycrvptsnum@\relax \@crv@{#1}}%
336 \fi \fi \next@ }
340 \xydef@\xy@@samecurve@{\xyFN@\checkendcurve@}
341 \xydef@\savesame@{\egroup }
342 \xydef@\recovercurve@{%
343 \crv@cnt@=\xycrvptsnum@ \splinereset@ \recovercv@end
344 \ifx\bendPLACE@\relax \def\bendPLACE@{1}\fi
345 \ifdim\zz@\R@c \ifdim\zz@\L@c \ifdim\zz@\D@c \ifdim\zz@\U@c
346  \Edge@c={\zeroEdge}\fi\fi\fi\fi
347 \edef\cv@end{\cfromthec@}\edef\cv@start{\cfromthep@}}
349 \xydef@\recovercv@end{\count@=\ptsnum@\relax\advance\count@\@ne
350 \edef\tmp@{\the\count@}\csname cv@\tmp@\endcsname}%
352 \xydef@\crvSTYLE@@{}
353 \expandafter\xydef@\expandafter\crv@defaultshape\expandafter{\addDASH@{}}
354 \xydef@\crv@noobject{\Invisible@true}
356 \xydef@\@crv@#1#2{\DN@{#1#2}%
357 \ifx\next@\empty \edef\next@{\crv@defaultshape}%
358 \ifx\bstartPLACE@\empty \xdef\crvSTYLE@@{{\crv@defaultshape}}\fi
359 \else
360 \ifx\bstartPLACE@\empty \gdef\crvSTYLE@@{#1{#2}}\fi
361 \fi

362 \ifx\next@\empty \crv@noobject \DN@{\crv@{}{\xy@@crvaddstack@}}%
363 \else\def\tmp@{-}\ifx\next@\tmp@ \DN@{\crv@{}{\xy@@crvaddstack@}}%
364 \else\def\tmp@{=}\ifx\next@\tmp@
365 \DN@{\expandafter\crv@\crv@normaltemplate{\dir{=}}}%
366 \else\def\tmp@{2-}\ifx\next@\tmp@
367 \DN@{\expandafter\crv@\crv@normaltemplate{\dir{2.}}}%
368 \else\def\tmp@{3-}\ifx\next@\tmp@
369 \DN@{\expandafter\crv@\crv@normaltemplate{\dir{3.}}}%
370 \else\def\tmp@{--}\ifx\next@\tmp@
371 \DN@{\expandafter\crv@\crv@specialtemplate@{--}}%
372 \else\def\tmp@{==}\ifx\next@\tmp@
373 \DN@{\expandafter\crv@\crv@normaltemplate{\dir2{--}}}%
374 \else\def\tmp@{2--}\ifx\next@\tmp@
375 \DN@{\expandafter\crv@\crv@normaltemplate{\dir2{--}}}%
376 \else\def\tmp@{3--}\ifx\next@\tmp@
377 \DN@{\expandafter\crv@\crv@normaltemplate{\dir3{--}}}%
378 \else\def\tmp@{.}\ifx\next@\tmp@
379 \DN@{\expandafter\crv@\crv@specialtemplate@{.}}%
380 \else\def\tmp@{:}\ifx\next@\tmp@
381 \DN@{\expandafter\crv@\crv@normaltemplate{\dir{:}}}%
382 \else\def\tmp@{2.}\ifx\next@\tmp@
383 \DN@{\expandafter\crv@\crv@normaltemplate{\dir{:}}}%
384 \else\def\tmp@{..}\ifx\next@\tmp@
385 \DN@{\expandafter\crv@\crv@specialtemplate@{.}}%
386 \else
387 \DN@{\expandafter\crv@\crv@othertemplate{\dir#1{#2}}}%
388 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
390 \xylet@\crv@specialtemplate@=\crv@specialtemplate@@
391 \xydef@\crv@special#1{}

Bug: this should use a \Step@@ method to get the spacing for dotting; this will eliminate the need for templates…

Parsing: Two separate parsers are required: one for \curve..., the other for the contents of {...}.

Set \curveSTYLE@ to be the default of \xycurve@@ then examine the following tokens to see if this must be changed.

Set \curveSTYLE@ to be the default of \xycurve@@ then examine the following tokens to see if this must be changed.

Procedure: If the first token of #1 (from \crv@) is ~ then a letter should follow, determining how to set the style. If instead it is an active control sequence then issue a warning message, but let it do its thing anyway. However \parsecurve@ is a normal thing to encounter, so no warning is required. Currently a single letter without the ~ will be recognised, but two-letter combinations definitely need the ~.

498 \xydef@\parseCURVE@{\def\curveSTYLE@{\xycurve@@}\def\afterCURVEaction@{}%
499 \xyFN@\parseCURVE@@}
500 \xydef@\parseCURVE@@{%
501 \ifx\space@\next\expandafter\DN@\space{\xyFN@\parseCURVE@@}% gobble spaces
502 \else\ifx ~\next \DN@ ~{\xy@~{}\xyFN@\setcurveSTYLE@@}%
503 \else\ifx\parsecurve@\next\DN@{}%

Syntax  Action
\curve⟨modifier⟩{⟨curve-object⟩⟨poslist⟩}  construct curved connection
⟨modifier⟩  ⟶ ⟨empty⟩  zero or more modifiers possible; default is ~C
| ~⟨curve-option⟩ ⟨modifier⟩  set ⟨curve-option⟩

⟨curve-option⟩

⟶

                  p | P | l | L | c | C

show only2.1d control points (p=points), joined by lines (l=lines), or curve only (c=curve)

| pc | pC | Pc | PC  show control points2.1f and curve2.1e
| lc | lC | Lc | LC  show lines joining2.1g control points and curve2.1e

|

                  cC

plot curve twice, with and without specified formatting

⟨curve-object⟩ ⟶ ⟨empty⟩  use the appropriate default style
| ~*⟨object⟩ ⟨curve-object⟩  specify the “drop” object2.1a and maybe more2.1c
| ~**⟨object⟩ ⟨curve-object⟩  specify “connect” object2.1b and maybe more2.1c
⟨poslist⟩  ⟶ ⟨empty⟩ | ⟨pos⟩ ⟨delim⟩ ⟨poslist⟩ list of positions for control points
| ~@ | ~@ ⟨delim⟩ ⟨poslist⟩  add the current stack2.1h to the control points
⟨delim⟩  ⟶ &  allowable delimiter

Figure 2.1: Syntax for curves.

504 \else\ifcat\active\noexpand\next\DN@{\xyactive@Warning}%
505 \else\ifcat a\noexpand\next\DN@##1{\xytilde@Warning\setcurveSTYLE@{##1}%
506 \xyFN@\parseCURVE@@}%
507 \else\DN@{}\fi\fi\fi\fi\fi \next@ }%

Options are normally specified using ~. Sometimes this can be safely omitted; if such a case is encountered then a warning message is issued advising to use ~. This nicety may be removed in future versions.

516 \xydef@\xyactive@Warning{\xywarning@{expandable control sequences should
517 not be here, results are unpredictable in diagrams.}}%     (2)
518 \xydef@\xytilde@Warning{Please use ~ to set curve style.}%  (3a)

Examine the next token to see if it determines a curve style. Currently only p, l and c are recognised, along with the uppercase variants P, L and C. When one of these letters is encountered,

set \curveSTYLE@ and keep examining tokens with \setafterCURVEaction@.

528 \xydef@\setcurveSTYLE@#1{\xyFN@\setcurveSTYLE@@#1}
529 \xydef@\setcurveSTYLE@@{%
530 \ifx\next p\def\curveSTYLE@{\xyc@trlpts@@}%
531  \DN@ p{\xyFN@\setafterCURVEaction@}%
532 \else\ifx\next P\def\curveSTYLE@{\xyc@trlpts@}%
533  \DN@ P{\xyFN@\setafterCURVEaction@}%
534 \else\ifx\next l\def\curveSTYLE@{\xyc@vxhull@@}%
535  \DN@ l{\xyFN@\setafterCURVEaction@}%
536 \else\ifx\next L\def\curveSTYLE@{\xyc@vxhull@}%
537  \DN@ L{\xyFN@\setafterCURVEaction@}%
538 \else\ifx\next c\def\curveSTYLE@{\xycurve@@}%

539  \DN@ c{\xyFN@\setafterCURVEaction@}%
540 \else\ifx\next C\def\curveSTYLE@{\xycurve@@}%
541  \DN@ C{\xyFN@\setafterCURVEaction@}%
542 \else \DN@##1{\xywarning@{unknown curve style ##1}\xyFN@\parseCURVE@@}%
543 \fi\fi\fi\fi\fi\fi \next@ }

\setafterCURVEaction@ examines tokens to see if a 2-letter combination is being specified; e.g. pc, lC, etc. Alternatively another ~ can set a new specification.

551 \xydef@\setafterCURVEaction@{%
552 \ifx\next~\DN@~{\xyFN@\setcurveSTYLE@@}%
553 \else\ifcat a\noexpand\next\DN@{\setafterCURVEaction@@}%
554 \else\DN@{\xyFN@\parseCURVE@@}%
555 \fi\fi \next@}

Currently the only 2-letter specifications have either c or C as the 2nd letter.

562 \xydef@\setafterCURVEaction@@{%
563 \ifx\next c\DN@ c{%
564 \def\afterCURVEaction@{\noexpand\endcurve\noexpand\xy@curve@}%
565  \xyFN@\parseCURVE@@ }%
566 \else\ifx\next C\DN@ C{%
567 \def\afterCURVEaction@{\noexpand\endcurve\noexpand\xy@curve@@}%
568  \xyFN@\parseCURVE@@ }%
569 \else \DN@##1{\xywarning@{unknown after-curve action ##1}%
570 \xyFN@\parseCURVE@@ }%
571 \fi\fi \next@ }

When \parsecurve@ is encountered, this signifies the end of this part of the parsing. The only active control sequence that should be encountered legitimately here is \@endcurve, which signifies that the ⟨poslist⟩ is empty and default styles are required. Otherwise assume we the subsequent tokens are from #2 of \crv@. Control passes to \xycurve@@ to prepare for reading the ⟨crv-object⟩s and ⟨poslist⟩.

586 \xydef@\parsecurve@{\xyFN@\parsecurve@@}
587 \xydef@\parsecurve@@{%
588 \ifx\space@\next\expandafter\DN@\space{\xyFN@\parsecurve@@}%
589 \else\ifx\next\@endcurve\DN@\@endcurve{\checkafterCURVE@}%
590 \else\ifcat\active\noexpand\next\DN@{\relax}%
591 \else\DN@{\xycurve@@}\fi\fi\fi\next@}%
595 \xydef@\xycurve@{\begingroup\afterCURVE{\setcurve@\endgroup}\crvobjects@
596 \startxycurve@\xycrvmods@}
597 \xydef@\xycurve@@{\afterCURVE{\setcurve@}\crvobjects@\startxycurve@
598 \xycrvmods@}
599 \xydef@\xy@curve@{\xy@curve@@@{\splinedefaulttol@\crvobjects@}}
600 \xydef@\xy@curve@@{\xy@curve@@@{\resetcrvobjects@}}
601 \xydef@\xy@curve@@@#1{\ifx\cv@start\relax
602 \DN@{\xywarning@{There is no curve to plot}}.
603 \else\DN@{\begingroup\afterCURVE{\setcurve@\endgroup}#1\cv@end}%
604 \fi \next@ }
605 \xydef@\crvobjects@{\def\xycrvdrop@{}\def\xycrvconn@{}}
606 \xydef@\resetcrvobjects@{\crvobjects@}

These were originally provided for sophisticated-user access. They are otherwise undocumented and may be removed.

613 \xylet@\savecurve=\xycurve@@
614 \xylet@\samecurve=\xy@curve@

\xy@crvmods@ handles reading the ⟨curve-object⟩s, i.e. the “drop” object and the “connect” object.

Procedure:l.635 Get next token.l.639 Is it a ~? l.640 If not, exit. l.645 If so, is it followed by a *? l.647 If not, issue a message and go back to l.635. Otherwise, l.652 is there a second *? l.653 If not then read and store the “drop” object, l.661 else, read and store the “connect” object. When finished, in either case, l.659 look for further specifications. l.657 An empty “drop” object is not allowed, so this actually gives the default of \zerodot.

635 \xydef@\xycrvmods@{\xyFN@\xy@crvmods@}
637 \xydef@\xy@crvmods@{%
638 \ifx\space@\next\expandafter\DN@\space{\xyFN@\xy@crvmods@}%gobble spaces
639 \else\ifx\next ~\DN@ ~{\xyFN@\xy@crvmods@@}
640 \else\DN@{\xy@crvmods@@@@}\fi\fi \next@}
641 \xydef@\xy@crvmods@@@@{\xyFN@\checkendcurve@}%
643 \xydef@\xy@crvmods@@{%
644 \ifx\space@\next\expandafter\DN@\space{\xyFN@\xy@crvmods@@}%gobble spaces
645 \else\ifx\next *\DN@ *{\xyFN@\xy@@crvmods@}
646 \else\addAT@\ifx\next\addAT@\DN@{\xyFN@\xy@@crvaddstack}%
647 \else\DN@{\xywarning@{badly-formed curve option}\xyFN@\xy@crvmods@}
648 \fi\fi\fi \next@}%
650 \xydef@\xy@@crvmods@{%
651 \ifx\space@\next\expandafter\DN@\space{\xyFN@\xy@@crvmods@}%gobble spaces
652 \else\ifx\next *\DN@ *{\xyFN@\xy@@crvmods@@}
653 \else\DN@{\xy@crv@mods@@}\fi\fi \next@}
655 \xydef@\xy@crv@mods@@#1#{\DN@##1{\xy@crvmods@@@{#1}{##1}}\next@}%
656 \xydef@\xy@crvmods@@@#1#2{%
657 \DN@{#1#2}\ifx\next@\empty \def\xycrvdrop@{ #1{\zerodot}}
658 \else \def\xycrvdrop@{ #1{#2}}\fi
659 \xyFN@\xy@crvmods@ }
661 \xydef@\xy@@crvmods@@#1#{\DN@##1{\xy@@crvmods@@@{#1}{##1}}\next@}
662 \xydef@\xy@@crvmods@@@#1#2{\def\xycrvconn@{ #1{#2}}\xyFN@\xy@crvmods@ }%

Parsing of the ⟨poslist⟩ is quite simple, recognising few special tokens:

• \endcurve and \endxy terminate reading of control points.

• &, \\ and \relax delimit ⟨pos⟩itions

• anything else is treated as a ⟨pos⟩, being handled by the \POS@ parser.

680 \xydef@\checkendcurve@{%
681 \ifx\space@\next\expandafter\DN@\space{\xyFN@\checkendcurve@}%gobble spaces
682 \else\ifx\next\endcurve\DN@\endcurve{\clearsearchflag@\endxycurve@}%
683 \else\ifx\next\@endcurve\DN@\@endcurve{\checkafterCURVE@}%
684 \else\ifx\next\xy@@crvaddstack@\DN@{}%
685 \else\ifx\next\endxy\DN@{\clearsearchflag@\sloppyendcrv@}%

686 % \else\addAND@\ifx\next\addAND@\DN@{\clearsearchflag@\searchnextpt@}%
687 \else\testAND@\iffalse \DN@##1{\clearsearchflag@\searchnextpt@}%
688 \else\ifx ~\next\DN@ ~{\xyFN@\checkcrvtilde@}%
689 \else\ifx\next\relax\DN@\relax{\clearsearchflag@\searchnextpt@}%
690 \else\ifx\next\\\DN@\\{\clearsearchflag@\searchnextpt@}%
691 \else\ifx\searchflag@\relax
692  \DN@{\setsearchflag@\searchnextpt@}%
693  \else\DN@##1{\flagwarn@{##1}}\fi
694 \fi\fi\fi\fi\fi\fi\fi\fi\fi \next@ }
695 \xydef@\searchnextpt@{\afterPOS{\xy@@\addtocrv@ \xyFN@\checkendcurve@}}

There could be a problem in that an invalid token would cause an infinite loop, passing back and forth between \checkendcurve@ and \POS@. This is avoided by setting a flag \setsearchflag@ when the \POS@ parser is called, not following a valid delimiter. Encountering a valid delimiter clears the flag. If \checkendcurve@ is called with the flag set, a warning message is issued and the token is skipped; the flag remains set. Processing continues, but it is possible that the wrong number of positions will be read; presumably there is some kind of error that needs to be fixed anyway.

710 \xydef@\checkafterCURVE@{%
711 \edef\tmp@{\noexpand\xyFN@\noexpand\checkendcurve@ %
712 \afterCURVEaction@\noexpand\endcurve}\tmp@ }
714 \xylet@\searchflag@=\relax
715 \xydef@\setsearchflag@{\let\searchflag@=@}
716 \xydef@\clearsearchflag@{\let\searchflag@=\relax}
717 \xydef@\flagwarn@#1{%
718 \ifx\next\@endcurve\DN@{\xyFN@\checkendcurve@\endcurve}%
719 \else\setsearchflag@\DN@{\xyFN@\checkendcurve@}%
720 \xywarning@{skipping invalid token \string#1\space in curve}%
721 \fi \next@ }

It is possible for the final \endcurve to be omitted, but only when the next token is \endxy. A warning message is written to the log file, protesting against this sloppy TEX-ing.◯_{¨⌣}

729 \xydef@\sloppyendcrv@{%
730 \xywarning@{Please use \string\endcurve\space to end the curve.}\endxycurve@}

Creation of the \crv is completed when \endcrv@ is encountered. At this point the usual methods \Drop@@ and \Connect@@ are defined. Extra information is retained, using \saveshape@ and \savecrvparams@ for the benefit of methods which treat the curve as a connection.

742 \xydef@\endcrv@{\saveshape@ %\def\Upness@{0}%
743 \Edge@c={\splineEdge}\Invisible@false\Hidden@false
744 \edef\Drop@@{\noexpand\ifInvisible@ \setbox\z@=\copy\voidb@x
745 \noexpand\else
746 \noexpand\wdz@=\z@
747 \noexpand\ht\z@=\z@ \noexpand\dp\z@=\z@
748 \noexpand\splineDrop@
749 \noexpand\fi }%

750 %

751 \edef\Connect@@{%
752 \noexpand\setbox\z@=\noexpand\box\lastobjectbox@
753 \noexpand\wdz@=\z@
754 \noexpand\ht\z@=\z@ \noexpand\dp\z@=\z@

755 \expandafter\noexpand\pure@crv
756 \noexpand\ifInvisible@ \noexpand\crv@saveStyles@ \noexpand\else
757 \noexpand\crv@getStyles@\noexpand\styledboxz@ \noexpand\fi

758 %

759 \noexpand\ifHidden@\noexpand\else
760 \noexpand\ifx\noexpand\COORD@\noexpand\xymatrixCOORD@ \noexpand\else
761  \noexpand\X@min=\the\X@min \noexpand\X@max=\the\X@max
762  \noexpand\Y@min=\the\Y@min \noexpand\Y@max=\the\Y@max
763 \noexpand\fi \noexpand\fi
764 \savecrvparams@ \noexpand\crvconnect@ %\noexpand\initbreaks@

765 }%

766 \wdz@=\z@
767 \ht\z@=\z@ \dp\z@=\z@ }

The control names \crvXY@pre@ and \crvXY@post@ are used to transfer style information passed with \preconnect@ to subsegments.

774 \xydef@\crvXY@pre@{}
775 \xydef@\crvXY@post@{}
777 \xydef@\crv@saveStyles@{\def\xy@style@{}%
778 \expandafter\def\expandafter\crvXY@pre@\expandafter{\preXY@style@}%
779 \expandafter\def\expandafter\crvXY@post@\expandafter{\postXY@style@}}
781 \xydef@\crv@getStyles@{\def\xy@style@{}%
782 \gdef\preXY@style@{\crvXY@pre@}\gdef\postXY@style@{\crvXY@post@}}

The values of \X@min, \X@max, etc. are used to compute the extents \L@c, \R@c, etc. of the object. This information must be maintained after the group is closed, unless the “hidden” attribute is required or we are inside a matrix construction.

In calculating the size of the box containing the curve \X@min, \X@max, etc. are initialised to describe the minimum rectangle enclosing p and c. At the same time we save the current scope.

795 \xydef@\initshape@{\savescope@
796 \ifdim\X@c>\X@p \X@min=\X@p \X@max=\X@c \else \X@max=\X@p \X@min=\X@c \fi
797 \ifdim\Y@c>\Y@p \Y@min=\Y@p \Y@max=\Y@c \else \Y@max=\Y@p \Y@min=\Y@c \fi }

\saveshape is used to pass necessary information up one level of grouping.

804 \xydef@\saveshape@{\savectrlptsnum@
805 \R@c=\X@max \advance\R@c-\X@c \L@c=\X@c \advance\L@c-\X@min
806 \U@c=\Y@max \advance\U@c-\Y@c \D@c=\Y@c \advance\D@c-\Y@min
807 \edef\tmp@{\egroup \U@c=\the\U@c \D@c=\the\D@c \L@c=\the\L@c \R@c=\the\R@c
808 \noexpand\ifdim\noexpand\X@min>\the\X@min\noexpand\X@min=\the\X@min\noexpand\fi
809 \noexpand\ifdim\noexpand\Y@min>\the\Y@min\noexpand\Y@min=\the\Y@min\noexpand\fi
810 \noexpand\ifdim\noexpand\X@max<\the\X@max\noexpand\X@max=\the\X@max\noexpand\fi
811 \noexpand\ifdim\noexpand\Y@max<\the\Y@max\noexpand\Y@max=\the\Y@max\noexpand\fi
812 \savecrvparams@ \def\noexpand\pure@crv{\expandafter\noexpand\pure@crv}}%
813 \tmp@ }
815 \xydef@\savecrvparams@{\crvpts@={\the\crvpts@}%
816 \noexpand\def\noexpand\crvconnect@{\expandafter\noexpand\crvconnect@}}%
822 \xydef@\splineEdge{\rectangleEdge}

To Do: This can be improved. For example, trace along the spline until an appropriate point is found. There may be more than one such point, so extra criteria may be required.

Notes

2.1a. The “drop” object is set once, then “dropped” many times at appropriately spaced places along the curve. If directional, the direction from p to c is used. Default behaviour is to have tiny dots spaced sufficiently closely as to give the appearance of a smooth curve. Specifying a larger size for the “drop” object is a way of getting a dotted curve (see the example in the next note).

2.1b. The “connect” object is also dropped at each place along the curve. However, if non-empty, this object uses the tangent direction at each place. This allows a directional object to be specified, whose orientation will always match the tangent. To adjust the spacing of such objects, use an empty “drop” object of non-zero size as shown here:

[figure: A; B; ^{.. ..............}.... . . . . . ...............]

\xy (0,0)*+{A}; (50,-10)*+{B}
**\crv{~*=<4pt>{.} (10,10)&(20,0)&(40,15)}
**\crv{~*=<8pt>{}~**!/-5pt/\dir{>}(10,-20)
 &(40,-15)} \endxy

When there is no “connect” object then the tangent calculations are not carried out, resulting in a saving of time and memory; this is the default behaviour.

2.1c. The “drop” and “connect” objects can be specified as many times as desired. Only the last specification of each type will actually have any effect. (This makes it easy to experiment with different styles.)

2.1d. Complicated diagrams having several spline curves can take quite a long time to process and may use a lot of TEX’s memory. A convenient device, especially while developing a picture, is to show only the location of the control points or to join the control points with lines, as a stylized approximation to the spline curve. The ⟨curve-option⟩s ~p and ~l are provided for this purpose. Uppercase versions ~P and ~L do the same thing but use any ⟨curve-object⟩s that may be specified, whereas the lowercase versions use plain defaults: small cross for ~p, straight line for ~l. Similarly ~C and ~c set the spline curve using any specified ⟨curve-option⟩s or as a (default) plain curve.

2.1e. Use of ~p, ~l, etc. is extended to enable both the curve and the control points to be easily shown in the same picture. Mixing upper- and lower-case specifies whether the ⟨curve-option⟩s are to be applied to the spline curve or the (lines joining) control points. See the examples accompanying the next two notes.

2.1f. By default the control points are marked with a small cross, specified by *\dir{x}. The “connect” object is ignored completely.

A  B [figure: ............................; .......................................]

was typeset by …

   \xy (0,0)*+{A};(50,-10)*+{B}
   **\crv~pC{~*=<\jot>{.}(10,-10)&(20,15)
    &(40,15)} \endxy

2.1g. With lines connecting control points the default “drop” object is empty, while the “connect” object is \dir{-} for simple straight lines. If non-empty, the “drop” object is placed at each control point. The “connect” object may be used to specify a fancy line style.

A  B [figure: ⊕; ⊕]

was typeset by …

   \xy (0,0)*+{A};(50,-10)*+{B}
   **\crv~Lc{~**\dir{--}~*{\oplus}
    (20,20)&(35,15)} \endxy

2.1h. When a stack of ⟨pos⟩itions has been established using the @i and @+ commands, these positions can be used and are appended to the ⟨poslist⟩.

940 \xydef@\xy@@crvaddstack{%
941 \ifx\next ~\xywarning@{there should be a poslist here, \string~@ ignored}%
942 \DN@{\xy@crvmods@}%
943 \else\DN@{\xy@@crvaddstack@}\fi \next@}
945 \xydef@\xy@@crvaddstack@{\smapxy@@\addtocrv@ \xyFN@\checkendcurve@}
947 \xydef@\checkcrvtilde@{%
948 \addAT@\ifx\next\addAT@\DN@{\xy@@crvaddstack@}%
949 \else\xywarning@{invalid token after ~, ignored}%
950 \DN@##1{\xyFN@\checkendcurve@}%
951 \fi \next@ }

Spline Methods Each \curve has to set the sliding abilities. This is done by a call to \crvconnect@@ which gives values to the methods \Creset@@, \Cshavep@, etc. These values depend on the style of the curve itself.

968 \xydef@\crvconnect@@{%
969 \def\Creset@@{\crvreset@}%
970 \def\Cshavep@@{\crvshavep@}%

971 \def\Cshavec@@{\crvshavec@}%
972 \def\Cslidep@@{\crvslidep@}%
973 \def\Cslidec@@{\crvslidec@}%
974 \def\Calong@@{\crvalong@}%
975 \def\Cintercept@@{\crvintercept@}%
976 \def\Cbreak@@{\crvbreak@}%
977 \def\Clast@@{\crvlast@}%

978 }

When straight lines are required …

984 \xydef@\straitconnect@{\crvconnect@@
985 \let\crvreset@=\straitreset@
986 \let\crvshavep@=\straitshavep@
987 \let\crvshavec@=\straitshavec@
988 \let\crvslidep@=\straitslidep@
989 \let\crvslidec@=\straitslidec@
990 \let\crvalong@=\straitalong@
991 \let\crvintercept@=\straitintercept@
992 \let\crvbreak@=\straitbreak@
993 \let\crvlast@=\straitlast@

994 }

These are the actual methods used for a sequence of straight segments.

1000 \xydef@\straitreset@{\the\crvpts@
1001 \edef\xycrvptsnum@{\csname ptsnum@\endcsname}%
1002 \def\segmentnum@{0}}
1003 \xydef@\straitslidep@{\setupDirection@ii \noCslidep@@ }
1004 \xydef@\straitslidec@{\setupDirection@ii \noCslidec@@ }
1006 \xydef@\straitshavep@{%
1007 \expandafter\ifnum\xycrvptsnum@>\z@
1008 \def\segmentnum@{0}%
1009 \csname cv@1\endcsname
1010 \resetDirection@ \setupDirection@ii
1011 \fi \noCshavep@@ }
1013 \xydef@\straitshavec@{%
1014 \expandafter\ifnum\xycrvptsnum@>\z@
1015 \expandafter\count@@\xycrvptsnum@\relax
1016 \bgroup \csname cv@\number\count@@\endcsname
1017 \edef\tmp@{\egroup \X@p=\the\X@c \Y@p=\the\Y@c}\tmp@
1018 \edef\segmentnum@{\xycrvptsnum@}%
1019 \resetDirection@ \setupDirection@ii
1020 \fi \noCshavec@@ }
1022 \xydef@\straitalong@#1{%
1023 \ifdim#1\p@<\z@
1024 \xywarning@{parameter value #1 is negative, using 0}%
1025 \cfromp@ \def\PLACEf@{{0}}%
1026 \else
1027 \dimen@=#1\p@ \count@=\dimen@ \divide\count@\p@
1028 \expandafter\count@@\xycrvptsnum@\relax \advance\count@@\@ne

2.1. CURVE AND SPLINE EXTENSION 133

1029 \advance\dimen@\segmentnum@\p@
1030 \advance\count@\segmentnum@\relax
1031 \def\segmentnum@{0}%
1032 \ifnum\count@@<\count@
1033 \xywarning@{parameter value #1 too large, using \the\count@@}%
1034 \count@=\count@@ \advance\count@\m@ne \edef\PLACEf@{{1}}%
1035 \else
1036 \advance\dimen@-\count@\p@
1037 \ifdim\zz@\dimen@\ifnum\count@>\z@
1038  \advance\count@\m@ne \advance\dimen@\p@ \fi\fi
1039 \edef\PLACEf@{{\expandafter\removePT@\the\dimen@}}%

1040 \fi

1041 \ifnum\count@=\z@\else \bgroup
1042 \csname cv@\number\count@\endcsname
1043 \edef\tmp@{\egroup \X@p=\the\X@c \Y@p=\the\Y@c}\tmp@

1044 \fi

1045 \advance\count@\@ne
1046 \ifnum\count@<\count@@
1047 \splinetrace@{find place \the\dimen@\space along straight segment
1048 \the\count@}%
1049 \csname cv@\number\count@\endcsname

1050 \fi

1051 \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p
1052 \fi \expandafter\noCalong@@\PLACEf@ \czeroEdge@ }
1056 \xydef@\straitintercept@{\noCintercept@@}
1057 \xydef@\straitbreak@{\straightCbreak@@}
1058 \xydef@\straitlast@{\straightClast@@}

When curved segments are required …

1064 \xydef@\splineconnect@{%
1065 \let\crvreset@=\splinereset@
1066 \let\crvshavep@=\splineshavep@
1067 \let\crvshavec@=\splineshavec@
1068 \let\crvslidep@=\splineslidep@
1069 \let\crvslidec@=\splineslidec@
1070 \let\crvalong@=\splinealong@
1071 \let\crvintercept@=\splineintercept@
1072 \let\crvbreak@=\splinebreak@
1073 \let\crvlast@=\splinelast@

1074 }

These are the actual methods.

Reset the spline parameters: \xycrvptsnum@: expands to a control sequence, whose name incorporates the correct scoping level,

giving the number of control points. \the\crvpts@: reads the control point locations and other information from a token list. \xysplineparams@: set to a control sequence name, incorporating the correct scoping level, which

will allow access to the Beźier control points for each spline segment, when required.

\xysplineedges@: set to a control sequence name, incorporating the correct scoping level, which gives the spline parameters of the edges of objects at p and c;

\segmentnum@: reset to 0.
\splinecorrect@p and \splinecorrect@c: reset to 0 until changed by a \Cshavep@ or \Cshavec@.

\splinelength@: reset to 0 until changed by a \Cshavep@, \Cshavec@ or \Calong@; this is needed by \Cshavep@ and \Cshavec@ to quickly locate where to slide from, especially when it is necessary to slide across more than a single spline segment.

\splineplace@: reset to .5.

1110 \xydef@\splinereset@{\the\crvpts@
1111 \edef\xycrvptsnum@{\csname ptsnum@\endcsname}%
1112 \edef\xysplineparams@{%
1113 \expandafter\noexpand\csname params@\endcsname}%
1114 \edef\xysplineedges@{%
1115 \expandafter\noexpand\csname edges@\endcsname}%
1116 \def\segmentnum@{1}\def\splinecorrect@p{0}\def\splinecorrect@c{0}%
1117 \splinelength@=\z@ \def\splineplace@f{.5}%

1118 }

Shaving to the appropriate edge. This is simply a matter of reading the stored edge information and storing the appropriate value in \splinecorrect@p or \splinecorrect@c. The difficult part is to construct the correct control sequence name and then to extract the correct part of the text in its expansion.

1129 \xydef@\splineshavep@{\begingroup
1130 \edef\xysplineedges@{%
1131 \expandafter\noexpand\csname edges@\endcsname}%
1132 \expandafter\expandafter\expandafter\getsplineedges@safe\xysplineedges@ @@%
1133 \edef\tmp@{\noexpand\removePT@\the\dimen5}%
1134 \edef\tmp@{\endgroup
1135 \noexpand\def\noexpand\splinecorrect@p{\tmp@}}\tmp@
1136 \setupDirection@ii }
1138 \xydef@\splineshavec@{\begingroup
1139 \edef\xysplineedges@{%
1140 \expandafter\noexpand\csname edges@\endcsname}%
1141 \expandafter\expandafter\expandafter\getsplineedges@safe\xysplineedges@ @@%
1142 \dimen@=-\dimen7\relax \advance\dimen@\p@
1143 %% \getcrvsegsnum@ \advance\dimen@\count@\p@
1144 \edef\tmp@{\noexpand\removePT@\the\dimen@}%\W@{**shave**<\tmp@>***}%
1145 \edef\tmp@{\endgroup
1146 \noexpand\def\noexpand\splinecorrect@c{\tmp@}}\tmp@
1147 \setupDirection@ii }
1149 \xydef@\splineslidep@#1{\enter@{\pfromthep@}%
1150 \begingroup \splinealong@@{0}{#1}+\splineslidep@@@
1151 \setupDirection@ii \leave@ }%
1153 \xydef@\splineslidep@@@{%
1154 \d@X=\dimen5 \d@Y=\dimen7 \edef\tmp@{\postfind@}\tmp@ \dimen@=\splineval@

1155 \expandafter\count@\xycrvptsnum@\relax
1156 \ifnum\count@>\tw@ \advance\count@\m@ne
1157 \advance\dimen@\segmentnum@\p@ \advance\dimen@-\p@

1158 \fi

1159 \edef\tmp@{\endgroup \endgroup
1160 \noexpand\def\noexpand\xysplineval@{\the\splineval@}%
1161 \noexpand\def\noexpand\splinecorrect@p{\expandafter\removePT@\the\dimen@}%
1162 \splinetrace@{slide = \the\splinelength@}%
1163 \X@c=\dimen@i \Y@c=\dimen3  % something may be wrong here!!
1164 \d@X=\the\d@X \d@Y=\the\d@Y %
1165 \noexpand\def\noexpand\segmentnum@{\segmentnum@}}\tmp@ }
1167 \xydef@\splineslidec@#1{\enter@{\pfromthep@}%
1168 \begingroup
1169 \expandafter\splinealong@@\PLACEf@{#1}+\splineslidec@@@
1170 \setupDirection@ii \leave@ }
1172 \xydef@\splineslidec@@@{%
1173 \d@X=\dimen5 \d@Y=\dimen7 \edef\tmp@{\postfind@}\tmp@ \dimen@=\splineval@
1174 \expandafter\count@\xycrvptsnum@\relax
1175 \ifnum\count@>\tw@ \advance\count@\m@ne
1176 \advance\dimen@\segmentnum@\p@ \advance\dimen@-\p@
1177 \dimen@=-\dimen@ \advance\dimen@\count@\p@
1178 \else \dimen@=-\dimen@ \advance\dimen@\p@ \fi %\W@{**slide**<\the\dimen@>***}%
1179 %%  splinecorrect@c  is probably wrong here!!
1180 \edef\tmp@{\endgroup \endgroup
1181 \noexpand\def\noexpand\xysplineval@{\the\splineval@}%
1182 \noexpand\def\noexpand\splinecorrect@c{\expandafter\removePT@\the\dimen@}%
1183 \splinetrace@{slide = \the\splinelength@; correct@c=\noexpand\splinecorrect@c}%
1184 \X@c=\dimen@i \Y@c=\dimen3  %
1185 \d@X=\the\d@X \d@Y=\the\d@Y %
1186 \noexpand\def\noexpand\segmentnum@{\segmentnum@}}\tmp@ }
1188 \xydef@\checkslidemore@#1{%
1189 \dimen@ii=-#1\relax\ifdim\dimen@ii<\z@\multiply\dimen@ii\m@ne\fi
1190 \dimen@=-\splinelength@ \advance\dimen@\dimen@ii\relax
1191 \ifdim\dimen@<\z@\dimen@ii=-\dimen@\else\dimen@ii=\dimen@\fi
1192 \ifdim\dimen@ii<.2\p@\DN@{\splineslidec@@ \leave@}%%%% ?
1193 \else \splinetrace@{not found yet, \the\dimen@ii\space still to go}%
1194 \dimen@ii=#1\relax\ifdim\dimen@ii<\z@\multiply\dimen@\m@ne\fi
1195 \DN@{\expandafter\splineslidemore@\expandafter{\the\dimen@}}\fi
1196 \next@}%
1198 \xydef@\splineslidemore@#1{%
1199 \expandafter\count@\segmentnum@\relax
1200 \ifdim#1<\z@\advance\count@\m@ne\dimen@=\p@
1201 \else\advance\count@\@ne\dimen@=\z@\fi
1202 \ifnum\count@<\@ne
1203 \expandafter\splinesegment@\expandafter{\segmentnum@}%
1204 \DN@{\xywarning@{cannot slide beyond start of curve}%
1205 \spline@find{\z@}{\z@}{}\splineslidec@@ \leave@ }%%%% ?
1206 \else \expandafter\count@@\xycrvptsnum@\relax\advance\count@@\m@ne

1207 \expandafter\ifnum\count@@<\count@\relax
1208 \expandafter\splinesegment@\expandafter{\segmentnum@}%
1209 \DN@{\xywarning@{cannot slide beyond end of curve}%
1210 \spline@find{\p@}{\z@}{}\splineslidec@@ \leave@ }%%%%% ?
1211 \else
1212 \edef\segmentnum@{\the\count@}%
1213 \expandafter\splinesegment@\expandafter{\segmentnum@}%
1214 \splinetrace@{sliding onto segment \segmentnum@}%
1215 \expandafter\spline@find\expandafter{\the\dimen@}{#1}{}%
1216 \DN@{\checkslidemore@{#1}}%
1217 \fi\fi  \next@ }
1219 \xydef@\splineslidec@@{%
1220 \dimen@=\splineval@ \advance\dimen@\segmentnum@\p@\advance\dimen@-\p@
1221 \edef\tmp@{\endgroup
1222 \noexpand\def\noexpand\xysplineval@{\the\dimen@}%
1223 \splinetrace@{slide = \the\splinelength@}%
1224 \X@c=\the\dimen@i \Y@c=\the\dimen3 \d@X=\the\dimen5 \d@Y=\the\dimen7 \postfind@
1225 \noexpand\def\noexpand\segmentnum@{\segmentnum@}}\tmp@
1226 \setupDirection@ii}

The method \splinealong@#1 finds places along the curve, when #1 is given as a factor, normally between 0 and 1. The location of the edges of the objects at p and c are stored in \splinecorrect@p and \splinecorrect@c. These are the places found if the factor is either 0 or 1. If an edge is non-zero then it is actually possible to move to points inside that edge by specifying a factor less than 0 or greater than 1.

1238 \xydef@\splinealong@#1{\def\postfind@{}\splinealong@@{#1}\z@+%
1239 \splineslidec@@
1240 \dimen@=\xysplineval@\relax
1241 \count@=\xycrvptsnum@\relax \ifnum\count@>\@ne \advance\count@\m@ne\fi
1242 \ifnum\count@>\@ne \dimen@nth\count@\dimen@
1243 \fi \edef\bthisPLACE@{\expandafter\removePT@\the\dimen@}%
1244 \splinetrace@{bthisPLACE@=\bthisPLACE@}}%

The parameter #2 in \splinealong@@#1#2#3 allows for a subsequent slide through a given ⟨dimen⟩ along the curve, from the place specifed by the factor in #1.

The information supplied in #1 must be converted to the segment number and parameter value of the specified point. These will be calculated and stored temporarily in \count@ and dimen@ before the values are passed respectively to \splinesegment@ which chooses the segment, and \spline@find to locate the point on this segment.

To do the calculation, first we correct for the parameter values of the edges of the objects at the end-points, which are stored in \splinecorrect@p and \splinecorrect@c. If the resulting number x is not an integer then \count@ is set to 1 + ⌊x⌋ while \dimen@ becomes (x − ⌊x⌋)\p@. If x is an

integer: x = 0 gives \count@=1 and \dimen@=\z@, otherwise \count@ = x and \dimen@=\p@.

1265 \xydef@\splinealong@@#1#2#3{%
1266 \edef\tmp@{#1}\relax \dimen@ii\tmp@\p@
1267 %% \getcrvsegsnum@
1268 %% \dimen@=-\count@\p@
1269 \dimen@=-\p@
1270 \expandafter\advance\expandafter\dimen@\splinecorrect@p\p@
1271 \expandafter\advance\expandafter\dimen@\splinecorrect@c\p@

1272 \edef\tmp@{#1}\relax \dimen@=-\tmp@\dimen@ \relax
1273 \expandafter\advance\expandafter\dimen@\splinecorrect@p\p@
1274 \getcrvsegsnum@ \multiply \dimen@ by\count@\relax
1275 \splinetrace@{actual:\the\dimen@; f:\the\dimen@ii; p:\splinecorrect@p, c:\splinecorrect@c}%
1276 \count@=\dimen@ \divide\count@\p@ \DN@{\relax}%
1277 \def\tmp@{\relax}\ifx\next@\tmp@
1278 \expandafter\ifnum\xycrvptsnum@<\count@
1279 \xywarning@{parameter value #1 too large}%
1280 \DNii@{\relax}\DN@{\begingroup}%
1281 \else
1282 \edef\xysplineval@{\the\dimen@}%
1283 \advance\dimen@-\count@\p@
1284 \ifdim\dimen@=\z@
1285 \splinetrace@{find knot point \the\count@}%
1286  \ifnum\count@=\z@ \count@=\@ne \else \dimen@=\p@ \fi
1287 \else \advance\count@\@ne
1288 \splinetrace@{find point \the\dimen@\space on spline segment \the\count@}%

1289 \fi

1290 \edef\segmentnum@{\the\count@}%
1291 \edef\next@{\begingroup\noexpand\splinesegment@{\the\count@}}%
1292 \edef\nextii@{%
1293 \noexpand\spline@find{\the\dimen@}{#2}{}\noexpand\checksplinefind@{#2}}%
1294 \ifx>#3\relax
1295 \edef\nextii@{%
1296 \noexpand\spline@find{\the\dimen@}{#2}#3\noexpand\checksplinefind@{#2}}%
1297 \else\ifx-#3\relax \ifdim\dimen@>\z@\relax \ifdim\dimen@<\p@
1298 \dimen@=-\dimen@ \advance\dimen@\p@
1299 \edef\nextii@{\noexpand\splinereverse@
1300 \noexpand\spline@find{\the\dimen@}{#2}{}\noexpand\checksplinefind@{#2}}%
1301 \fi\fi
1302 \else\ifx<#3\relax \ifdim\dimen@>\z@\relax \ifdim\dimen@<\p@
1303 \dimen@=-\dimen@ \advance\dimen@\p@
1304 \edef\nextii@{\noexpand\splinereverse@
1305 \noexpand\spline@find{\the\dimen@}{#2}#3\noexpand\checksplinefind@{#2}}%
1306 \fi\fi
1307 \fi\fi\fi
1308 \fi\fi  \expandafter\next@\nextii@ }

This macro checks whether the required sliding has been carried out, or whether it is necessary to continue sliding along the next segment.

1315 \xydef@\checksplinefind@#1{%
1316 \dimen@ii=#1\relax \dimen@=\splinelength@
1317 \ifdim\dimen@ii=\z@\DN@{}%
1318 \else
1319 \ifdim\dimen@ii<\z@\advance\dimen@\dimen@ii
1320 \else\advance\dimen@-\dimen@ii\fi
1321 \ifdim\dimen@<\z@\multiply\dimen@\m@ne\fi
1322 \ifdim\dimen@<.2\p@\DN@{}%
1323 \else
1324 \count@=\segmentnum@\relax

1325 \ifdim\dimen@ii<\z@\advance\dimen@ii\splinelength@
1326  \ifnum\count@>\@ne\advance\count@\m@ne
1327  \edef\next@{\noexpand\splinesegment@{\the\count@}%
1328  \noexpand\spline@find\p@{\the\dimen@ii}{}%
1329  \noexpand\checksplinefind@{\the\dimen@ii}}%
1330  \else
1331  \xywarning@{cannot slide \the\dimen@ii\space before start}%
1332  \DN@{\splinesegment@\@ne \spline@find\z@\z@{}}\fi
1333 \else\advance\dimen@ii-\splinelength@
1334  \count@@=\numcontrolpts
1335  \ifnum\count@<\count@@ \advance\count@\@ne
1336  \edef\next@{\noexpand\splinesegment@{\the\count@}%
1337  \noexpand\spline@find\z@{\the\dimen@ii}{}%
1338  \noexpand\checksplinefind@{\the\dimen@ii}}%
1339  \else
1340  \xywarning@{cannot slide \the\dimen@ii\space beyond end}%
1341  \DN@{\splinesegment@{\the\count@@}\spline@find\p@\z@{}}\fi

1342 \fi

1343 \fi\fi \next@ }

Breaks Typesetting breaks in curves is quite involved. The \bstartPLACE@ and \bendPLACE@ are used to hold parameter values for the positions of the beginning and end of a segment, respectively, when known. The default values of \relax indicate that these values need to be found, usually from the start- and end-edges of the curve. The value of \empty for \bstartPLACE@ is used initially with a new curved connection, to set up all its parameters — no typesetting takes place. This is used by curved arrows to set up the connection before places can be found for any breaks.

1361 \xydef@\resetbreaks@{%
1362 \let\bstartPLACE@=\relax \let\bthisPLACE@=\empty
1363 \let\bendPLACE@=\relax \let\bprevPLACE@=\relax}
1365 \xydef@\invisbreaks@{\resetbreaks@ \let\bstartPLACE@=\empty}
1366 \xydef@\crvresetbreaks@{\resetbreaks@ \let\bstartPLACE@=\relax }
1368 \xydef@\initbreaks@{\xy@@{\ifx\bstartPLACE@\relax
1369 \def\bstartPLACE@{0}\def\bendPLACE@{1}\else
1370 \ifx\bstartPLACE@\empty\def\bstartPLACE@{0}\def\bendPLACE@{1}%
1371 \fi\fi}}
1373 \xydef@\lastbreaks@{\ifx\bprevPLACE@\relax \def\bstartPLACE@{0}%
1374 \else \expandafter \bprevPLACE@ \fi
1375 \let\bprevPLACE@\relax \let\bendPLACE@\relax}
1377 \xylet@\bstartPLACE@\relax
1378 \xylet@\bendPLACE@\relax
1379 \xylet@\bprevPLACE@\relax
1380 \xydef@\bthisPLACE@{1}

These are called in the actual setting of curved sub-segments.

1386 \xydef@\splinebreak@{%
1387 \splinetrace@{***new break*** this:\bthisPLACE@ }%
1388 \ifx\bthisPLACE@\empty\def\bendPLACE@{1}%

1389 \else\edef\bendPLACE@{\bthisPLACE@}\let\bthisPLACE@\empty\fi
1390 %\xystatus@{BR1}%
1391 \ifx\bprevPLACE@\relax\def\bstartPLACE@{0}\else\expandafter\bprevPLACE@\fi
1392 \edef\bprevPLACE@{\def\noexpand\bstartPLACE@{\bendPLACE@}\pfromthec@}%
1393 \splinetrace@{splineBREAK: \bstartPLACE@ <> \bendPLACE@}%
1394 %\xystatus@{BR}%
1395 \edef\cv@brend{\cfromthec@}%
1396 \edef\cv@brstart{\cfromthep@}%
1397 \expandafter\connect\expandafter\crvs\crvSTYLE@@{}% ? optimise
1398 \let\cv@brend=\relax
1399 \let\cv@brstart=\relax
1400 \splinetrace@{**break done**}%

1401 }

1403 \xydef@\splinelast@{\splinereset@ \lastbreaks@ %\splinetracing
1404 \splinetrace@{splineLAST}%
1405 %\xystatus@{LA}%
1406 \edef\cv@brend{\cfromthec@}%
1407 \edef\cv@brstart{\cfromthep@}%
1408 \expandafter\connect\expandafter\crvs\crvSTYLE@@{}% ? optimise
1409 \let\cv@brend=\relax
1410 \let\cv@brstart=\relax
1411 \splinetrace@{**last done**}%
1412 \resetbreaks@}

Intersection with a curved connection Just as the intersection of two lines (1.3j) can be found, so can the intersection of a straight line with a curved connection, or the intersection of a curve with a straight connection.

[figure: A; B; C; D; ⊕; A; B; C; D; ⊕]

\xy*+{A}="A";p+/r5pc/+(0,15)*+{B}="B"
 ,p+<1pc,3pc>*+{C}="C"
 ,"A"+<4pc,-1pc>*+{D}="D",{\ar@/_/"C"}
 ,?!{"A";"B"**@{-}}*++{\oplus}
\endxy \quad \xy
 *+{A}="A";p+/r5pc/+(0,15)*+{B}="B",
 ,p+<1pc,3pc>*+{C}="C"
 ,"A"+<4pc,-1pc>*+{D}="D","A";"B"**@{-}
 ,?!{"D",{\ar@/_/"C"}}*++{\oplus}
\endxy

When the line separates the end-points of a curve an intersection can always be found. If there is more than one then that occurring earliest along the curve is the one found.

Presume the end-points of the spline segment are at (X_{p}, Y_{p}) and (X_{c}, Y_{c}) with (L_{p}, U_{p}) and (R_{p}, D_{p}) as two points on the line. Then the macro \xysidesofinterval@ returns 3 pieces of information.

• \next expands to 2 characters, each from {+, −, 0} indicating which side of, or on, the line lies either end-point;

• \this@ expands to either + or − indicating which end is closer to the line, returning + if equi-distant;

• \howclose@ contains a non-negative ⟨num⟩ indicating the distance to the nearest end-point.

1456 \xydef@\splineNointercept@{\enter@{\pfromthep@}%
1457 \begingroup \splinereset@ \csname cv@0\endcsname \swap@
1458 \count@=\ptsnum@ \advance\count@\@ne \csname cv@\the\count@\endcsname
1459 \edef\tmp@{\endgroup \X@origin=\the\X@p \Y@origin=\the\Y@p
1460 \R@c=\the\d@X \U@c=\the\d@Y}\tmp@
1461 \loop@
1462 \dimen@=\ifdim\R@c<\z@-\fi\R@c
1463 \advance\dimen@ \ifdim\U@c<\z@-\fi\U@c
1464 \ifdim\dimen@>10\p@
1465 \advance\R@c \ifdim\R@c<\z@-\fi 16sp \divide\R@c\KK@
1466 \advance\U@c \ifdim\U@c<\z@-\fi 16sp \divide\U@c\KK@
1467 \repeat@
1468 \intersect@ \leave@}
1470 \xydef@\splineintercept@{\Hidden@true\Invisible@true\splineintercept@i}
1472 \xydef@\splineintercept@i{\enter@{\pfromthep@}\begingroup
1473 \R@p=\X@c \L@p=\X@p \d@X=\R@p \advance\d@X-\L@p
1474 \D@p=\Y@c \U@p=\Y@p \d@Y=\D@p \advance\d@Y-\U@p
1475 \dimen@nth\KK@\d@X \edef\sd@X{\expandafter\removePT@\the\d@X}%
1476 \dimen@nth\KK@\d@Y \edef\sd@Y{\expandafter\removePT@\the\d@Y}%
1477 \dimen@=\sd@Y\L@p \advance\dimen@-\sd@X\U@p
1478 \edef\sideOffset@{\the\dimen@}\def\closestseg@{1}%
1479 \let\crvconnect@@=\relax \crvconnect@
1480 \let\spline@end=\splinef@end
1481 \def\spline@start{\bgroup \def\prevnext@{+-}%
1482 \def\splinerec@{\let\splinerec@=\splineIrec@ \splineinterceptTest@}%
1483 \def\splinedecast@{\let\splinedecast@=\splinedecast@@
1484 \def\splineadvance@{\splineIadvance@@}\splinedecast@@}%
1485 \def\splineadvance@{\intercepthull@}%
1486 %  \def\splinepoint@{\splineIpt@@}%
1487 \global\let\splinepoint=\splineIpt@@
1488 \global\let\splinegoal@=\splinef@pt
1489 \global\let\splinefinish@=\splinefinish@@}%
1490 \begingroup \splineIsegment@
1491 \splinesetparams@ \splined@@ \def\postfind@{}\splineIplace@
1492 \setupDirection@ii \leave@ }
1495 \xydef@\splineIplace@{%
1496 \d@X=\dimen5 \d@Y=\dimen7 \dimen@=\splineval@
1497 \expandafter\count@\xycrvptsnum@\relax
1498 \ifnum\count@>\tw@ \advance\count@\m@ne %\advance\count@\m@ne
1499 \advance\dimen@\segmentnum@\p@ \advance\dimen@-\p@
1500 \dimen@nth\count@\dimen@  %  \divide\dimen@\count@

1501 \fi \edef\tmp@{\endgroup \endgroup
1502 \def\noexpand\PLACEf@{{\expandafter\removePT@\the\dimen@}}%
1503 \X@c=\dimen@i \Y@c=\dimen3 %
1504 \d@X=\the\d@X \d@Y=\the\d@Y }\tmp@
1505 \splinetrace@{PLACE = \PLACEf@:(\the\X@c, \the\Y@c)}%
1506 \expandafter\edef\expandafter\bthisPLACE@\PLACEf@

1507 }

1509 \xydef@\splineIrec@{\splineinterceptTest@ }
1511 \xydef@\squineIpt@{\edef\tmp@{\endgroup
1512 \def\noexpand\prevnext@{\next}\begingroup}\tmp@ }
1513 \xydef@\squineIadvance@{\edef\tmp@{\endgroup
1514 \def\noexpand\prevnext@{\next}\def\noexpand\howclose@{\howclose@}}%
1515 \tmp@ \splineadvance@@\begingroup}
1517 \xydef@\cubicIpt@{\edef\tmp@{\endgroup
1518 \def\noexpand\prevnext@{\next}\begingroup}\tmp@ }
1519 \xydef@\cubicIadvance@{\edef\tmp@{\egroup
1520 \def\noexpand\prevnext@{\next}\def\noexpand\howclose@{\howclose@}}%
1521 \tmp@ \splineadvance@@\bgroup}
1523 \xydef@\splineIsegment@{\DN@{\splinesegment@\@ne}%
1524 \ifx\splinesegment@\squinesegment@\else
1525 \ifx\splinesegment@\cubicsegment@\else\DN@{\findIsegment@}%
1526 \fi\fi\next@}
1528 \xydef@\findIsegment@{\expandafter\count@\xycrvptsnum@ \count@@\z@
1529 \loop@ \advance\count@@\@ne \bgroup
1530 \expandafter\splinesegment@\expandafter{\the\count@@}%
1531 \xysidesofinterval@
1532 \findIsegment@i \repeat@
1533 \expandafter\dimen@\prevhowclose@ \relax
1534 \ifdim\dimen@=\z@ \edef\closestseg@{\the\count@@}\fi
1535 \expandafter\splinesegment@\expandafter{\closestseg@}}
1537 \xydef@\findIsegment@i{%
1538 \expandafter\ifx\next \expandafter\findIsegment@ii
1539 \else\expandafter\findIsegment@x\fi \next@ }
1541 \xydef@\findIsegment@ii{\expandafter\count@\xycrvptsnum@ \relax
1542 \advance\count@\m@ne \ifnum\count@>\segmentnum@\relax
1543 \expandafter\findIsegment@y\else\expandafter\findIsegment@x\fi}
1545 \xydef@\findIsegment@x{%
1546 \edef\next@{\egroup\def\noexpand\next{\next}%
1547 \def\noexpand\prevhowclose@{\prevhowclose@}%
1548 \def\noexpand\closestseg@{\closestseg@}\noexpand\iffalse}}
1550 \xydef@\findIsegment@y{%
1551 \edef\next@{\egroup\def\noexpand\next{\next}%
1552 \def\noexpand\prevhowclose@{\prevhowclose@}%
1553 \def\noexpand\closestseg@{\closestseg@}\noexpand\iftrue}}
1555 \xydef@\xysidesofinterval@{\bgroup
1556 \L@p=\sd@X\Y@p \advance\L@p-\sd@Y\X@p \advance\L@p\sideOffset@

1557 \U@p=\sd@X\Y@c \advance\U@p-\sd@Y\X@c \advance\U@p\sideOffset@
1558 \def\this@{}\ifdim\L@p>\almostz@ \ifdim\U@p>\almostz@ \def\next{++}\else
1559 \ifdim\U@p<-\almostz@ \def\next{+-}\else\def\next{+0}\def\this@{-}\fi\fi
1560 \else\ifdim\L@p<-\almostz@ \ifdim\U@p>\almostz@ \def\next{-+}\else
1561 \ifdim\U@p<-\almostz@ \def\next{--}\else\def\next{-0}\def\this@{+}\fi\fi
1562 \else \ifdim\U@p>\almostz@ \def\next{0+}\else
1563 \ifdim\U@p<-\almostz@ \def\next{0-}\else\def\next{00}\def\this@{+}\fi\fi
1564 \fi\fi
1565 \ifx\this@\empty
1566 \L@p=\ifdim\L@p<\z@-\fi\L@p \U@p=\ifdim\U@p<\z@-\fi\U@p
1567 \ifdim\L@p<\U@p \edef\howclose@{\the\L@p}\def\this@{-}%
1568 \else \edef\howclose@{\the\U@p}\def\this@{+}\fi
1569 \else\def\howclose@{0.0pt}\fi
1570 \splinetrace@{\next:\this@:\howclose@;\the\splineval@:%
1571 (\the\X@p,\the\Y@p);(\the\X@c,\the\Y@c)}%
1572 \ifdim\howclose@<\prevhowclose@\relax
1573 \edef\tmp@{\egroup\def\noexpand\this@{\this@}\def\noexpand\next{\next}%
1574 \def\noexpand\howclose@{\howclose@}\def\noexpand\prevhowclose@{\howclose@}%
1575 \def\noexpand\closestseg@{\segmentnum@}}%
1576 \splinetrace@{closest yet: \howclose@, in segment \segmentnum@}%
1577 \else
1578 \edef\tmp@{\egroup\def\noexpand\this@{\this@}\def\noexpand\next{\next}%
1579 \def\noexpand\howclose@{\howclose@}}%
1580 \fi \tmp@ }
1582 \xydef@\splineinterceptTest@{%
1583 \xysidesofinterval@ \DN@{\splineadvance@}%
1584 \DNii@{0.0pt}\ifx\howclose@\nextii@ \DN@{\splineclosest@}%
1585 \else\expandafter\ifx\next \expandafter\ifx\prevnext@
1586 \ifx\next\prevnext@\else\DN@{\X@c=\X@p \Y@c=\Y@p
1587 \splinefinishf@}\fi\fi
1588 \else \DN@{\splinedecast@}\fi\fi
1589 {\splinefar@false \splinenear@\X@p\X@c\Y@p\Y@c
1590 \ifsplinefar@ \aftergroup\next@
1591 \else\aftergroup\splineclosest@
1592 \splinetrace@{too close: (\the\X@p,\the\Y@p)::(\the\X@c,\the\Y@c)}%
1593 \fi}}
1595 \xydef@\splineclosest@{%\global\advance\splineval@-.5\splinedepth@
1596 \expandafter\ifx\this@-\relax
1597 \X@c=\X@p \Y@c=\Y@p \global\advance\splineval@-\splinedepth@
1598 \fi \splinefinishf@ }%

When the line misses the convex hull of the curve’s control points it is still possible to get the point of closest approach.

1605 \xydef@\squinetestcvxhull@{\begingroup
1606 \splinetrace@{hull: closest in segment \closestseg@}%
1607 \expandafter\splinesegment@\ifx\undefined\closestseg@\@ne\else\closestseg@\fi
1608 \X@c=\L@c \Y@c=\U@c \xysidesofinterval@
1609 \expandafter\ifx\next \expandafter\splineoutsidehull@@
1610 \else \expandafter\splineinsidehull@\fi}

1612 \xydef@\cubictestcvxhull@{\begingroup
1613 \expandafter\splinesegment@\ifx\undefined\closestseg@\@ne\else\closestseg@\fi
1614 \X@c=\L@c \Y@c=\U@c \xysidesofinterval@
1615 \expandafter\ifx\next \expandafter\cubictestcvxhull@i
1616 \else \expandafter\splineinsidehull@\fi}
1618 \xydef@\cubictestcvxhull@i{%\begingroup
1619 \X@c=\R@c \Y@c=\D@c \xysidesofinterval@
1620 \expandafter\ifx\next \expandafter\splineoutsidehull@@
1621 \else \expandafter\splineinsidehull@\fi}
1624 \xydef@\xysidesofhull@{\bgroup
1625 \L@p=\sd@X\Y@p \advance\L@p-\sd@Y\X@p \advance\L@p\sideOffset@
1626 \U@p=\sd@X\Y@c \advance\U@p-\sd@Y\X@c \advance\U@p\sideOffset@
1627 \L@p=\ifdim\L@p<\z@-\fi\L@p \U@p=\ifdim\U@p<\z@-\fi\U@p
1628 \ifdim\L@p<\U@p \edef\howclose@{\the\L@p}\def\this@{-}%
1629 \else \edef\howclose@{\the\U@p}\def\this@{+}\fi
1630 \ifx\splinedecast@\squinedecast@ \D@c=\U@c \R@c=\L@c \fi
1631 \L@p=\sd@X\U@c \advance\L@p-\sd@Y\L@c \advance\L@p\sideOffset@
1632 \L@p=\ifdim\L@p<\z@-\fi\L@p
1633 \expandafter\if\this@-%
1634 \ifdim\L@p<\prevhowclose@ \def\next{-+}\else \def\next{--}\fi
1635 \else
1636 \ifdim\L@p<\howclose@ \def\next{-+}\else
1637 \U@p=\sd@X\D@c \advance\U@p-\sd@Y\R@c \advance\U@p\sideOffset@
1638 \U@p=\ifdim\U@p<\z@-\fi\U@p
1639 \ifdim\U@p<\howclose@ \def\next{+-}\else \def\next{++}\fi
1640 \fi\fi
1641 \edef\tmp@{\egroup\def\noexpand\this@{\this@}\def\noexpand\next{\next}%
1642 \def\noexpand\howclose@{\howclose@}}\tmp@ }

This is for straight connections intercepting with a curve. It requires a redefinition of \PLACE@intercept@ to recognise that the intercept is with a curved connection.

1650 \def\PLACE@intercept@#1{%
1651 \xy@@{\enter@{\pfromthep@\basefromthebase@}\begingroup}%
1652 \xy@@ix@{#1}\xy@@{\plainxy@ \def\Creset@@{}%
1653 \expandafter\POS\the\toks9\relax
1654 \DNii@{\crvreset@}\ifx\nextii@\Creset@@ \edef\next@{\endgroup
1655 \def\noexpand\xyinterceptpts@{\the\crvpts@}%
1656 \X@c =\the\X@c \Y@c=\the\Y@c \X@p=\the\X@p \Y@p=\the\Y@p
1657 \noexpand\CCintercept@@ }%
1658 \else \edef\next@{\endgroup
1659 \X@c =\the\X@c \Y@c=\the\Y@c \X@p=\the\X@p \Y@p=\the\Y@p
1660 \noexpand\Cintercept@@ }%
1661 \fi \next@ \leave@}%
1662 \PLACE@@}
1664 \xydef@\CCintercept@@{\splineSintercept@}
1665 \xydef@\splineSintercept@{\enter@{\pfromthep@}\begingroup
1666 \Creset@@ \edef\connect@pts{\cfromthec@ \pfromthep@}%
1667 \xyinterceptpts@ \splinereset@ \connect@pts \splineintercept@

1668 \edef\next@{\endgroup \cfromthec@ \DirectionfromtheDirection@ }%
1669 \next@ \let\xyinterceptpts@=\empty \leave@}

To Do: If both connections are curves, only the line joining the end-points of the first connection is used. Find a way to do better than this.

If the line does not separate the end-points then there may be no intersection with the curve. If there is one then either the line is tangential or necessarily there will also be at least one other intersection. A message

                       perhaps no curve intersection, or many.

is written to the log-file, but a search for an intersection will still be performed and a “sensible” place found on the curve. In the usual case of a single quadratic or cubic segment, the place nearest the line is found and the tangent direction is established.

The following examples show this, and show how to get the place on the line nearest to the curve.

[figure: A; B; C; D; ⊗; A; B; C; D; ⊗]

\xy *+{A}="A";p+/r5pc/+(0,15)*+{B}="B",
 ,p-<.5pc,2pc>*+{C}="C","A"+<6pc,-.5pc>
 ,*+{D}="D","A",{\ar@/_25pt/"B"}
 ,?!{"C";"D"**@{-}}*\dir{x}="E"
 ,+/_2pc/="F";"E"**@{-},?!{"C";"D"}
 ,*{\otimes}\endxy\qquad\xy
 *+{A}="A";p+/r5pc/+(0,15)*+{B}="B",
 ,p-<.5pc,2pc>*+{C}="C"
 ,"A"+<7pc,.5pc>*+{D}="D","A"
 ,{\ar@/_40pt/"B"},?!{"C";"D"**@{-}}
 ,*{\otimes}\endxy

The warning message, that no intersection may exist, always occurs inside a grouping so it can safely switch itself off for deeper levels.

1712 \xydef@\nointerceptwarning@{\let\nointerceptwarning@=\relax
1713 \xywarning@{perhaps no curve intersection, or many. }}
1715 \xydef@\intercepthull@{\nointerceptwarning@
1716 \expandafter\def\expandafter\prevnext@\expandafter{\next}%
1717 \splinetestcvxhull@}

When the line meets the convex hull of the current control points, then a closer point exists inside the current portion of the curve. We must “decast” to find it, after storing the closest value known

so far, within \prevhowclose@.

1726 \xydef@\splinetestcvxhull@{\begingroup
1727 \X@c=\L@c \Y@c=\U@c \splinetrace@{hull:}\xysidesofinterval@
1728 \expandafter\ifx\next \expandafter\splineoutsidehull@@
1729 \else \expandafter\splineinsidehull@\fi}
1731 \xydef@\splineinsidehull@{\edef\tmp@{\endgroup

1732 \def\noexpand\howcvxclose@{\howclose@}%
1733 \noexpand\interceptinsidehull@}\tmp@ }
1735 \xydef@\interceptinsidehull@{\edef\prevhowclose@{\howclose@}%
1736 \splinedecast@@ }

If the line does not cross into the convex hull, then we use the distance from the control points to determine whether or not there can be a closer point. The value of \prevhowclose@ indicates the best so far, while \howcvxclose@ temporarily holds the distance to the closest control point. When this is nearer then there will be a closer point on the curve.

1747 {\xdef\next{\the\maxdimen}}
1748 \xylet@\prevhowclose@=\next
1750 \xydef@\splineoutsidehull@{\edef\tmp@{\endgroup
1751 \def\noexpand\howcvxclose@{\howclose@}%
1752 \noexpand\interceptoutsidehull@}\tmp@}
1753 \xylet@\splineoutsidehull@@=\splineoutsidehull@
1755 %\xydef@\interceptoutsidehull@{\dimen@=\howcvxclose@ \relax
1756 % \ifdim\dimen@<\howclose@ \relax
1757 %  \ifdim\howclose@<\prevhowclose@\relax \edef\prevhowclose@{\howclose@}\fi
1758 %   \DN@{\begingroup\splinedecast@@ \endgroup}%
1759 % \else\ifdim\howclose@>\prevhowclose@ \relax \DN@{\splineHadvance@}%
1760 % \else \DN@{\splineHadvance@ }\fi\fi \next@ }
1761 \xydef@\interceptoutsidehull@{\dimen@=\howcvxclose@ \relax
1762 % \global\splineval@=\z@
1763 \splinetrace@{OUTSIDE HULL: \the\dimen@ : (\howclose@)(\prevhowclose@)}%
1764 \let\splinedecast@=\splinedecast@@
1765 \let\splinerec@\splineHnear@test
1766 \let\splineadvance@\splineIadvance@@
1767 \splinedecast@@ }
1769 \xydef@\splineHnear@test{%
1770 \xysidesofhull@ \DN@{\splinedecast@}%
1771 \ifdim\howclose@<\prevhowclose@\edef\howclose@{\prevhowclose@}\fi
1772 \expandafter\if\this@-%
1773 \expandafter\ifx\next\DN@{\splineclosest@}\fi
1774 \else
1775 \expandafter\ifx\next\DN@{\splineadvance@}\fi

1776 \fi

1777 {\splinefar@false \splinenear@\X@p\X@c\Y@p\Y@c
1778 \ifsplinefar@ \aftergroup\next@
1779 \else\aftergroup\splineclosest@
1780 \splinetrace@{too close: (\the\X@p,\the\Y@p)::(\the\X@c,\the\Y@c)}%
1781 \fi}}

For cubic segments it is necessary to look at both control-points off the curve and compare their distances; hence the use of \prevhowcvxclose@, initially set to \maxdimen.

1789 \xydef@\cubicoutsidehull@{\edef\tmp@{\endgroup
1790 \def\noexpand\howcvxclose@{\howclose@}}\tmp@
1791 \edef\prevhowcvxclose@{\howcvxclose@}\begingroup
1792 \X@p=\R@c \Y@p=\D@c \splinetrace@{hullii:}\xysidesofinterval@
1793 \expandafter\ifx\next \expandafter\cubicoutsidehull@i

1794 \else \expandafter\cubicinsidehull@\fi}
1796 \xydef@\cubicinsidehull@{\edef\tmp@{\endgroup
1797 \def\noexpand\howclose@{\howclose@}}\tmp@
1798 \cubicoutsidehull@ii }
1800 \xydef@\cubicoutsidehull@i{\edef\tmp@{\endgroup
1801 \def\noexpand\howcvxclose@{\howclose@}}\tmp@
1802 \dimen@=\prevhowcvxclose@\relax
1803 \ifdim\dimen@<\howcvxclose@ \relax
1804 \edef\howcvxclose@{\the\dimen@}\expandafter\interceptoutsidehull@
1805 \else \expandafter\cubicoutsidehull@ii\fi }
1807 \xydef@\cubicoutsidehull@ii{%
1808 \def\splineadvance@{\splineadvance@@}%
1809 \def\splinepoint\endgroup{\endgroup
1810 %  \global\let\splinepoint=\splinepoint@
1811 \global\let\splinepoint=\relax
1812 \def\splineadvance@{\intercepthull@}}%
1813 \splinedecast@@ }%

This macro \splineHadvance@ is used at the end of a \splinedecast@ in order to pass information from out of a subsegment, to help decide whether there is any point in further searching.

1821 \xydef@\splineHadvance@{\futurelet\next@\splineHadvance@i}
1822 \xydef@\splineHadvance@i{\ifx\next@\endgroup
1823 \expandafter\splineHadvance@x\else\expandafter\splineclosest@\fi}
1825 \xydef@\splineHadvance@x{\edef\tmp@{\endgroup
1826 \def\noexpand\prevhowclose@{\prevhowclose@}%
1827 \def\noexpand\prevnext@{\next}\def\noexpand\howcvxclose@{\howclose@}}%
1828 \tmp@ \dimen@=\prevhowclose@ \relax
1829 \ifdim\dimen@<\howclose@ \relax \DN@{\splineclosest@\begingroup}%
1830 \else\ifdim\howcvxclose@=\dimen@\DN@{\splineclosest@\begingroup}%
1831 \else\DN@{\splineadvance@@\begingroup}\fi\fi \next@ }

Miscellaneous features The command \clearcurve was originally provided to discard the curve information, and return to the graphics state before the curve was read, if this is ever found to be necessary. This will probably be removed.

1843 \xydef@\xyclearcrv@{\cv@end\cv@restore\loop@
1844 \expandafter\let\csname cv@\number\crv@cnt@\endcsname\relax
1845 \ifnum\crv@cnt@>0\advance\crv@cnt@\m@ne\repeat@
1846 \let\cv@start=\relax \let\cv@end=\relax \let\cv@restore=\relax \POS}
1847 \xylet@\clearcurve=\xyclearcrv@

To Do: Define an \extendcurve as a ⟨postcurve⟩ which allows the curve to be continued smoothly past the endpoint c.

A macro can be used within the modifier, to provide different labels at each control point. For example…

A 1  2  3  4 B

\newcount\cptlabel\global\cptlabel=0
\def\nextcptlabel{\global\advance\cptlabel 1 %
 \number\cptlabel}
\xy (0,0)*+{A}; (50,-10)*+{B}
**\crv~Pc{~*{\nextcptlabel}(10,-10)
 &(20,15)&(30,-15)&(40,15)} \endxy

Two control sequences are provided to access the control points. Firstly \numcontrolpts returns the number of them, while \xycontrolpt⟨num⟩ sets c to be the particular control point. Here ⟨num⟩ must be a single digit, grouped integer e.g. {-15} or count register containing a numerical value. If larger than \numcontrolpts then c becomes the end-point of the curve, while if zero it becomes the starting point. A negative value sets both p and c to be the starting point, whereas other values leave p unchanged.

1881 \xylet@\numcontrolpts=\xynumctrlpts@
1883 \xydef@\xycontrolpt@#1{{%
1884 \ifnum#1<\z@\aftergroup\cv@restore\aftergroup\cv@start
1885 \else
1886 \expandafter\count@\xycrvptsnum@\relax \advance\count@\@ne
1887 \ifnum#1>\count@ \ifx\cv@end\relax
1888 \expandafter\aftergroup\csname cv@\number#1\endcsname
1889 \else\aftergroup\cv@end\fi
1890 \else
1891 \expandafter\ifx\csname cv@\number#1\endcsname\relax
1892  \ifnum#1=\z@\aftergroup\cv@start\else\aftergroup\cv@end\fi
1893 \else\expandafter\aftergroup\csname cv@\number#1\endcsname
1894 \fi\fi\fi}}%
1895 \xylet@\xycontrolpt=\xycontrolpt@

Storing control point locations: Upon starting to read the control points for a curve, first set the counter \crv@cnt@ to be zero. Store the position of p and c and the current base in control sequences \cv@start, \cv@end and \cv@restore for later retrieval and to reinstate the current graphics state. \cv@start is a little more complicated in order to retain the existing value of p.

1910 \xydef@\startxycurve@@{\crv@cnt@=\z@
1911 \edef\cv@start{\cfromthep@}%
1912 \ifdim\zz@\R@c \ifdim\zz@\L@c \ifdim\zz@\D@c \ifdim\zz@\U@c
1913  \Edge@c={\zeroEdge}\fi\fi\fi\fi
1914 \edef\cv@end{\cfromthec@}%
1915 \edef\cv@restore{\pfromthep@\basefromthebase@}}
1916 \xylet@\startxycurve@=\startxycurve@@
1918 \xylet@\cv@start=\relax

1919 \xylet@\cv@end=\relax
1920 \xylet@\cv@restore=\relax
1921 \xydef@\readxycurve@{\startxycurve@\xycrvmods@}
1922 \xylet@\readxycurve=\readxycurve@

The position of each control point is stored as the expansion of a control sequence whose name encodes its place within the ⟨poslist⟩. Expanding this control sequence sets c to be the appropriate position.

1931 \xydef@\addtocrv@{\advance\crv@cnt@\@ne
1932 \edef\tmp@{%
1933 \expandafter\noexpand\csname cv@\number\crv@cnt@\endcsname}%
1934 \expandafter\edef\tmp@{\cfromthec@}%
1935 \edef\tmp@{\noexpand\addtocrvpts@{\noexpand\def
1936 \expandafter\noexpand\tmp@{\X@c=\the\X@c \Y@c=\the\Y@c }}}\tmp@
1937 \edef\xycrvptsnum@{\the\crv@cnt@}%

1938 }

1947 \xydef@\xycrvdrop@{ {\zerodot}}
1948 \xydef@\xycrvconn@{}
1950 \xydef@\xyc@trlpts@{\def\xycrvdrop@{ \dir{x}}\def\xycrvconn@{}%
1951 \afterCURVE{\savecrvobjects@\xyctrlpts@}\readxycurve@}
1952 \xydef@\xyc@trlpts@@{%
1953 \afterCURVE{\savecrvobjects@\def\xycrvdrop@{ \dir{x}}%
1954 \def\xycrvconn@{}\xyctrlpts@}\readxycurve@}
1955 \xydef@\xyc@vxhull@{\def\xycrvdrop@{ {}}%
1956 \edef\xycrvconn@{ \noexpand\dir{\addDASH@{}}}%
1957 \afterCURVE{\savecrvobjects@\xycvxhull@}\readxycurve@}
1958 \xydef@\xyc@vxhull@@{%
1959 \afterCURVE{\savecrvobjects@\def\xycrvdrop@{ {}}%
1960 \edef\xycrvconn@{ \noexpand\dir{\addDASH@{}}}\xycvxhull@}\readxycurve@}
1961 \xylet@\controlpts=\xyc@trlpts@
1962 \xylet@\convexhull=\xyc@vxhull@
1963 \xydef@\savecrvobjects@{\bgroup
1964 \expandafter\toks@\expandafter{\xycrvdrop@}%
1965 \expandafter\toks@ii\expandafter{\xycrvconn@}%
1966 \edef\tmp@{\egroup\noexpand\def\noexpand\resetcrvobjects@{%
1967 \noexpand\def\noexpand\xycrvdrop@{\the\toks@}%
1968 \noexpand\def\noexpand\xycrvconn@{\the\toks@ii}%
1969 }}\tmp@}

Alternate curve styles: There is the potential to do many other things here, by using \afterCURVE, once the list of control points has been read.

1978 \xydef@\afterCURVE#1{\def\afterCURVE@{#1}}
1979 \xydef@\endxycurve@{\cv@end\savectrlptsnum@
1980 \expandafter\def\csname params@\endcsname{\the\crvpts@}%
1981 \cv@restore\afterCURVE@\POS}
1982 \xylet@\endcurve=\endxycurve@

In fact this is essentially how \controlpts and \convexhull were interfaced before extensions were added to change styles.

\def\controlpts{\afterCURVE{\xyctrlpts}%
 \readxycurve}
\def\convexhull{\afterCURVE{\xycvxhull}%
 \readxycurve}

The real work is done by \xyctrlpts and \xycvxhull. At the point when these macros are expanded the graphics state has the restored p and c to their original values, i.e. the end-points of the curve.

\controlpts: This macro visits in order each of the control points dropping the requisite object. The connection style is not used and the direction does not change. For a loop-counter we use \count@@@.

2011 \xydef@\xyctrlpts@{\cv@end \cv@restore
2012 \def\crvconnect@{\straitconnect@}%
2013 \ifnum\crv@cnt@>\z@
2014 \count@@@=\@ne \DN@{\loop@\xycontrolpt@{\count@@@}\relax
2015 \expandafter\xycvxhulldrop@\xycrvdrop@
2016 \ifnum\crv@cnt@>\count@@@\advance\count@@@\@ne\repeat@
2017 \cv@end \cv@restore }%
2018 \else\DN@{\relax}\fi \next@ }
2019 \xylet@\xyctrlpts=\xyctrlpts@

The token list \crvpts@ stores the following information: current scope , location of p and c, number of control points \crv@cnt@ and their locations. It does this by storing \defs for control sequence names, depending on the scope, which expand to this information. Thus by executing \the\crvpts@ at the right level, the information is conveniently recovered via control sequences which do not conflict with anything else, and whose names can be reconstructed.

2032 \xydef@\addtocrvpts@#1{\crvpts@=\expandafter{\the\crvpts@#1}}
2036 \xydef@\savescope@{\crvpts@={}%
2037 \edef\tmp@{\expandafter\noexpand\csname cv@0\endcsname}%
2038 \edef\tmp@{\noexpand\addtocrvpts@{\noexpand\def
2039 \expandafter\noexpand\tmp@{\X@c=\the\X@p \Y@c=\the\Y@p}}}%
2040 \tmp@ }
2042 \xydef@\savectrlptsnum@{%
2043 \advance\crv@cnt@\@ne \edef\tmp@{%
2044 \expandafter\noexpand\csname cv@\number\crv@cnt@\endcsname}%
2045 \edef\tmp@{\noexpand\addtocrvpts@{\noexpand\def
2046 \expandafter\noexpand\tmp@{\X@c=\the\X@c \Y@c=\the\Y@c}}}\tmp@
2047 \advance\crv@cnt@\m@ne
2048 \edef\tmp@{\expandafter\noexpand\csname ptsnum@\endcsname}%
2049 \edef\tmp@{\noexpand\addtocrvpts@{%
2050 \noexpand\def\expandafter\noexpand\tmp@{\number\crv@cnt@}}}%
2051 \tmp@ }

Convex Hull: This macro visits in order each of the control points dropping the requisite object. With the previous as p and the current one as c, a connection is set in the requisite style. For a loop-counter we use \count@@@.

Use a group {\expandafter\POS\xycrvconn@} else the \loop@ gets upset. This does not affect the size of the XY-picture, since the dropped objects are not similarly shrouded.

Also used for the trivial case where there are no control points, hence a straight line between p and c is what is requested.

2070 \xydef@\xycvxhull@{\cv@end \cv@restore
2071 \addtocrvpts@{\def\crvconnect@{\straitconnect@}}%
2072 \def\crvconnect@{\straitconnect@}%
2073 \ifnum\crv@cnt@>\z@
2074 \count@@@=\@ne\relax \DN@{\loop@\xycontrolpt@{\count@@@}\relax
2075 \expandafter\xycvxhulldrop@\xycrvdrop@
2076 {\expandafter\connect\xycrvconn@{}}\pfromc@
2077 \ifnum\crv@cnt@>\count@@@\relax \advance\count@@@\@ne\repeat@
2078 \cv@end }%
2079 \else
2080 \ifx\empty\xycrvconn@
2081 \edef\xycrvconn@{\noexpand!C\noexpand\dir{\addDASH@{}}}\fi
2082 \DN@{\relax}\fi \next@
2083 {{\expandafter\connect\xycrvconn@{}}}%
2084 \cv@end \cv@restore }
2085 \xylet@\xycvxhull=\xycvxhull@
2087 \xydef@\xycvxhulldrop@#1#{\drop@{#1}}

Spline constructions The control sequence \xysplineparams@ provides a way to access a control sequence name that is unique to the current XY-pic scope. This control sequence will be used to store the parameters which determine the spline curve. Similarly \xysplineedges@ will be used to store the parameter values and lengths (along the squine) to the locations where the spline crosses the edge of the objects at the ends p and c.

2106 \xydef@\savespline@{%
2107 \splinetrace@{savespline@:}%
2108 % \edef\endspline@{\endgroup
2109 \edef\endspline@{\endgroup
2110 \savesplineparams@ \savesplinerefs@
2111 \X@min=\the\X@min\relax \X@max=\the\X@max\relax
2112 \Y@min=\the\Y@min\relax \Y@max=\the\Y@max\relax
2113 \ifInvisible@\noexpand\Invisible@true
2114 \else\noexpand\Invisible@false\fi
2115 }\endspline@
2116 \edef\tmp@{\noexpand\addtocrvpts@{\savesplineparams@}}\tmp@
2117 \xycontrolpt@\z@ \cv@end }
2119 \xydef@\savesplineparams@{%
2120 \noexpand\def\expandafter\noexpand\xysplineedges@{\xysplineedges@}}
2122 \xydef@\savesplinerefs@{%
2123 \noexpand\def\noexpand\xysplineparams@{%
2124 \expandafter\noexpand\xysplineparams@}%
2125 \noexpand\def\noexpand\xysplineedges@{%
2126 \expandafter\noexpand\xysplineedges@}%

2127 }

One new box register is required, for the object used to actually set the curve, …

2136 \xynew@{box}\splinebox@

… and 4 dimen registers ...

2142 \xynew@{dimen}\splineval@

… which is for tracking the natural spline parametrization;

2147 \xynew@{dimen}\splinedepth@

… which is for tracking he depth of the recursive algorithms;

2152 \xynew@{dimen}\splinetol@

… which contains the tolerance for the spline, (this can probably be shifted to an ordinary macro);

2158 \xynew@{dimen}\splinelength@

… which accumulates a measure of the length along a spline curve. (Currently this is not being used, as most things can be done satisfactorily using the spline parametrization only.)

Some new conditionals are also required. These are for testing whether successive places on the squine are sufficiently close together, and whether the objects should be placed or not.

2170 \xynew@{if}\ifsplinefar@
2171 \xynew@{if}\ifsplineplot@ % to plot points or not

Provide some tracing ability, for debugging.

2177 \xydef@\splinetracing{\let\splinetrace@=\W@}
2178 \xydef@\splineignore@#1{}
2179 \xylet@\splinetrace@=\splineignore@

The parameters for the current section of the spline are stored indirectly in \xysplineparams@, while information concerning the places where the spline crosses the edges of objects at p and c is stored indirectly in \xysplineedges. A control sequence \readsplineparams@ is used to extract this information. Each spline type must provide a \getsplineparams@ which puts the information into easily usable form.

2193 \xydef@\readsplineparams@{%
2194 \expandafter\expandafter\expandafter\getsplineparams@\xysplineparams@
2195 \expandafter\expandafter\expandafter\getsplineedges@safe\xysplineedges@ @@}
2197 \xydef@\getsplineedges@safe#1@@{\DN@{#1}%
2198 \ifx\next@\empty \DN@{\getsplineedges@.0pt;0.0pt,0.0pt;0.0pt,}%
2199 \else \DN@{\getsplineedges@safe@#1@@}\fi \next@}
2201 \xydef@\getsplineedges@safe@#1;#2,#3@@{\DN@{#3}%
2202 \splinetrace@{getsplineedges@safe}%
2203 \ifx\next@\empty \DN@{\getsplineedges@#1;#2,0.0pt;0.0pt,}%
2204 \else \DN@{\getsplineedges@#1;#2,#3}\fi \next@}

The edge locations are stored as x.y where x + 1 = spline-segment number and y or 1 − y = parameter value of the start, resp. finish, in the segment x + 1.

2213 \xydef@\getsplineedges@#1;#2,#3;#4,{%
2214 \global\dimen@i=#1\global\dimen5=#2\relax
2215 \dimen@=#3\multiply\dimen@\m@ne \advance\dimen@\splinelength@
2216 \global\dimen3=\dimen@
2217 \dimen@=#4\relax
2218 \ifdim\dimen@>\p@ \xywarning@{edge out-of-range: \the\dimen@}%
2219 \count@=\dimen@ \divide\count@\p@

2220 \advance\dimen@-\count@\p@ \multiply\dimen@\m@ne
2221 \advance\dimen@ \count@\p@ \advance\dimen@\p@
2222 \splinetrace@{\the\dimen@}%
2223 \else
2224 \multiply\dimen@\m@ne \advance\dimen@\p@

2225 \fi

2226 \global\dimen7=\dimen@ }

Sometimes TEX will run short of memory when many curves are used without a backend with special support for curves. In that case the following commands, that obey normal TEX groupings, may be helpful:

                              \SloppyCurves
                              \splinetolerance{⟨dimen⟩}

allow adjustment of the tolerance used to typeset curves. The first sets tolerance to .8pt, after which \splinetolerance{0pt} resets to the original default of fine curves.

Some useful methods for accurate division by integers.

2251 \xydef@\dimen@half{%
2252 \advance\dimen@ \ifdim\dimen@<\z@-\fi 1sp \divide\dimen@\tw@}
2254 \xydef@\halve@dimen#1{\dimen@=#1\relax \dimen@half #1=\dimen@}
2256 \xydef@\dimen@nth#1#2{\dimen@=#2\relax \dimen@ii=#1sp %
2257 \advance\dimen@ \ifdim\dimen@<\z@-\fi.5\dimen@ii
2258 \divide\dimen@ by#1\relax #2=\dimen@}

Before constructing the curve we first examine the “drop” object, setting it in an \xybox. The size of this object determines the spacing of objects placed along the curve, via the tolerance of the spline. This determines the maximum separation of places at which objects will be dropped; i.e. when two adjacent places would be separated by more than this amount, the spline algorithm constructs another place on the curve intermediate between these two. Note: Alter the spline tolerance by adjusting the size of the “drop” object. In particular, a dotted line can be achieved by setting an empty object with non-zero size. If the size is zero then the default tolerance is used. Initially this is .4pt; it may be altered using \splinetolerance⟨dimen⟩, where ⟨dimen⟩ must be greater than zero, else the initial tolerance is reset.

2279 \xydef@\splinetolerance@#1{\dimen@=#1\relax
2280 \ifdim\dimen@>\z@ \splinetol@=\dimen@
2281 \else\splinetol@=.4\p@\fi}
2283 \xylet@\splinedefaulttol@=\relax
2285 \xydef@\splinetolerance#1{\splinetolerance@{#1}%
2286 \edef\splinedefaulttol@{\splinetol@=\the\splinetol@}}
2288 \splinetolerance\z@
2290 \xydef@\SloppyCurves{\splinetolerance{.8\p@}}
2292 \xydef@\xylowtolerance@{\splinedefaulttol@
2293 \ifdim\splinetol@<\p@ \divide\splinetol@\tw@ \fi}

Similarly examine the “connect” object. If none has been specified then there is no need to calculate the tangent direction at each place along the curve. This saves on both time and memory requirement.

   Procedure: (1) If \xycrvdrop@ is empty, define \splinedrop@ to expand to \copy\zerodotbox@,

thus creating a curve constructed from small dots. Otherwise (2a) set the \splinebox@ with the specified object and (2b) use \copy\splinebox@ as the expansion of \splinedrop@. (3) Set \splinetol@ to be \sqrt{2}× maximum of width and height+depth of the box.

If \xycrvconn@ is empty (4) then \splineconn@ is set to \relax. (5) Otherwise it is necessary to reset the direction at each place along the curve before dropping the object specified by \xycrvconn@.

2316 \xywarnifdefined\splinedrop@
2317 \xydef@\setstdsplinedrop@{%
2318 \setbox\splinebox@=\hbox\bgroup
2319 \setboxz@h{\expandafter\object\xycrvdrop@{}}%
2320 \splinedefaulttol@ \dimen@=\wd\z@ \dimen@ii=\ht\z@ \advance\dimen@ii\dp\z@
2321 \ifdim\dimen@ii>\dimen@ \dimen@=\dimen@ii \fi \dimen@=1.4142\dimen@
2322 \ifdim\dimen@>\splinetol@ \splinetol@=\dimen@\else\dimen@=\splinetol@\fi
2323 \dimen@=.5\wd\z@
2324 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \kern-\dimen@ \Drop@@ \kern\dimen@
2325 \edef\tmp@{\egroup \splinetol@=\the\splinetol@
2326 \ifInvisible@\noexpand\Invisible@true
2327 \else\noexpand\Invisible@false\fi}\tmp@
2328 \edef\splinedefaulttol@{\splinetol@=\the\splinetol@}%
2329 \def\splinedrop@{\copy\splinebox@\splineextra@@}}
2331 \xywarnifdefined\splineconn@
2332 \xydef@\stdsplineconn@{{\setsplinedir@ %  %(5)
2333 \setboxz@h\bgroup\expandafter\object\xycrvconn@{}%
2334 \edef\tmp@{\egroup\L@c=\the\L@c \R@c=\the\R@c \D@c=\the\D@c \U@c=\the\U@c
2335  \noexpand\def\noexpand\Drop@@}\expandafter\tmp@\expandafter{\Drop@@}%
2336 \setboxz@h{\kern-\L@c \boxz@}%
2337 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \Drop@@}}
2339 \xydef@\setcrvobjects@{\setstdsplinedrop@ \def\splineconn@{\stdsplineconn@}}
2340 \xylet@\splineextra@@=\relax
2344 \xydef@\splinenear@#1#2#3#4{{\d@X=#1\advance\d@X-#2%
2345 \ifdim\d@X<\z@ \d@X=-\d@X\fi
2346 \ifdim\splinetol@<\d@X \aftergroup\splinefar@true
2347 \else \d@Y=#3\advance\d@Y-#4\ifdim\d@Y<\z@ \d@Y=-\d@Y\fi
2348 \ifdim\splinetol@<\d@Y\aftergroup\splinefar@true
2349 \else \xydist@\d@X\d@Y
2350 \ifdim\splinetol@<\dimen@ \aftergroup\splinefar@true
2351 \else
2352  \ifdim\dimen@<.1\splinetol@\aftergroup\splinetooclose@\fi
2353 \fi\fi\fi}}
2355 \xydef@\splineadvance@@{\global\advance\splineval@\splinedepth@}

This stops objects being placed too close together along the spline. It is necessary at the beginning of a segment with a non-zero edge. Otherwise, with a large \splinetolerance@, the accuracy of the place-finding mechanism results in being so deep in the tree that objects placed at every level on the way up would be much too close.

2365 \xydef@\splinetooclose@{\aftergroup\aftergroup\aftergroup\splinetooclose@@}
2366 \xydef@\splinetooclose@@{\def\splineplotpt@{\relax}}

Each place along the curve is tested according to a \splinetest@. Normally this is for visibility according to the extent of the objects at the end-points of the curve. When an edge is crossed then the \splinecontinue routine is called to decide how the behaviour may change e.g. whether the recursion should continue or exit to the top of the existing tree.

2377 \xydef@\splinepoint@@{%
2378 \splinetrace@{P@:(\the\X@c,\the\Y@c)::\the\splineval@;\the\splinedepth@}%
2379 {\splinetest@\ifsplineplot@\relax\else\aftergroup\splinecontinue\fi}}
2381 \xydef@\splinepoint@{%
2382 {\splinetest@\ifsplineplot@\aftergroup\splinecontinue\fi}}
2383 \xylet@\splinepoint=\splinepoint@
2385 \xydef@\splinecontinue@{%
2386 \global\let\splinepoint=\splinepoint@@
2387 \global\let\splinecontinue=\splinecontinue@@}
2388 \xydef@\splinecontinue@@{%
2389 \global\let\splinepoint=\splinepoint@
2390 \global\let\splinecontinue=\relax}
2391 \xylet@\splinecontinue=\splinecontinue@

Points where segments join lie at the top of the recursive tree. They are tested directly against the objects at the endpoints, in order to decide whether or not they are visible.

2400 \xydef@\splineknotpoint@{{\X@p=\X@c \Y@p=\Y@c \cv@start
2401 \the\Edge@c\@ne \ifInside@\else\aftergroup\splineknotpoint@@\fi}}%
2402 \xydef@\splineknotpoint@@{{\X@p=\X@c \Y@p=\Y@c \cv@end
2403 \the\Edge@c\@ne \ifInside@\else \aftergroup\splinepoint\fi}}%
2405 \xylet@\firstsplinepoint@=\splineknotpoint@
2406 \xylet@\lastsplinepoint@= \splineknotpoint@

This routine is used to find where the spline crosses the edges of the objects at p and c. First (1) we set up the tests which will determine when the edge has been crossed. Then commence the scan. (2)

2417 \xydef@\splined@@@{%
2418 \splinetrace@{finding end types}%
2419 \splinetrace@{bstartPLACE@:\bstartPLACE@; bendPLACE@:\bendPLACE@}%
2420 \DN@{\splinescan@}\ifx\bstartPLACE@\empty
2421 \ifx\bendPLACE@\relax\def\bendPLACE@{1}\fi
2422 \else\ifx\bstartPLACE@\relax
2423 \else\ifx\bstartPLACE@\undefined
2424 \else
2425 \DN@{\splinescanbreak@}\ifx\bendPLACE@\relax\def\bendPLACE@{1}\fi
2426 \DNii@{0}\ifx\bstartPLACE@\nextii@
2427  \DNii@{1}\ifx\bendPLACE@\nextii@\DN@{}%
2428 %    \else\DNii@{0.0}\ifx\bendPLACE@\nextii@\DN@{}\fi
2429 \fi\fi  % use the saved values
2430 \fi\fi\fi \next@ }%  %(2)
2432 \xydef@\splineStarttest@{{\X@p=\X@c \Y@p=\Y@c \cv@start \the\Edge@c\@ne
2433 \ifInside@\aftergroup\splineplot@false\else\aftergroup\splineplot@true\fi}}%
2434 \xydef@\splineEndtest@{{\X@p=\X@c \Y@p=\Y@c \cv@end \the\Edge@c\@ne
2435 \ifInside@\aftergroup\splineplot@false\else\aftergroup\splineplot@true\fi}}%
2437 \xydef@\splineBreakStarttest@{{\X@p=\X@c \Y@p=\Y@c \cv@brstart \the\Edge@c\@ne

2438 \ifInside@\aftergroup\splineplot@false\else\aftergroup\splineplot@true\fi}}%
2440 \xydef@\splineBreakEndtest@{{\X@p=\X@c \Y@p=\Y@c \cv@brend \the\Edge@c\@ne
2441 \ifInside@\aftergroup\splineplot@false\else\aftergroup\splineplot@true\fi}}%
2442 %  \ifInside@\aftergroup\splineplot@true\else\aftergroup\splineplot@false\fi}}%
2444 \xylet@\splineStarttest=\splineStarttest@
2445 \xylet@\splineEndtest=\splineEndtest@
2447 \xydef@\splineSlowStarttest{{\X@p=\X@c \Y@p=\Y@c \cv@start \the\Edge@c\@ne
2448 \ifInside@\aftergroup\splineplot@maybe@@\else\aftergroup\splineplot@true\fi}}%
2449 \xydef@\splineSlowEndtest{{\X@p=\X@c \Y@p=\Y@c \cv@end \the\Edge@c\@ne
2450 \ifInside@\aftergroup\splineplot@maybe@@\else\aftergroup\splineplot@true\fi}}%
2451 \xydef@\splineplot@maybe{\splineplot@false}%
2452 \xylet@\splineplot@maybe@@=\splineplot@maybe

(3) Start a new group and bind some macros appropriate to finding the starting edge. (4) start the spline algorithm, using a small tolerance. (5) Close the group, thus removing the bindings of (3).

(6) Record the information, which has been stored globally. (7) Do the same for the ending edge.

(8) Clear the global information. After this, set the curve as usual. (9)

2465 \xydef@\splinescan@{\bgroup%
2466 \expandafter\def\xysplineedges@{\z@;\z@,\z@;\z@,}%
2467 \bgroup \cv@start
2468 \expandafter\DN@\expandafter{\the\Edge@c}\DNii@{\zeroEdge}%
2469 \ifx\next@\nextii@ \gdef\splineedges@{\z@;\z@,}%
2470 \else\aftergroup\splinestartScan@\fi
2471 \egroup \relax
2472 \bgroup \cv@end
2473 \expandafter\DN@\expandafter{\the\Edge@c}\DNii@{\zeroEdge}%
2474 \ifx\next@\nextii@
2475 \getcrvsegsnum@ \edef\segmentnum@{\the\count@}%
2476 \splineval@=\z@ \splineRecordEndValue@
2477 \else\aftergroup\splineendScan@\fi
2478 \egroup \egroup
2479 \expandafter\testsplineedges@\splineedges@;,@@%
2480 \expandafter\edef\xysplineedges@{\splineedges@}%  %(6)
2481 \global\let\splineedges@=\relax %  %(8)
2482 \splinetrace@{edge params: \xysplineedges@}}%
2484 \xydef@\testsplineedges@#1;#2,#3;#4,#5@@{%
2485 \DN@{#5}\ifx\next@\empty
2486 \DNii@{#4}\ifx\nextii@\empty
2487 \xynoedgespline@{end}\def\splineedges@{#1;#2,\z@;\z@,}\fi
2488 \DNii@{#2}\ifx\nextii@\empty
2489 \xynoedgespline@{start}\def\splineedges@{\z@;\z@,\z@;\z@,}\fi
2490 \fi }
2491 \xydef@\xynoedgespline@#1{\xywarning@{#1 edge of spline not found}}%
2493 \xydef@\splinestartScan@{\bgroup % %(3)
2494 \splinetrace@{scan for start}%
2495 \global\let\splineadvance@=\splineadvance@@  %(3)
2496 \let\spline@start=\splinefindStart@   %(3)
2497 \let\spline@end=\spline@end@@   %(3)

2498 \let\splinefinish@=\splinefinish@@
2499 \let\splinewhich=\relax
2500 \global\splinelength@=\z@
2501 % \let\splinerec@=\splineSrec@
2502 \def\splinerec@{\let\splinerec@=\splineSrec@ \splinedecast@@}%
2503 \edef\splineedges@{}%
2504 \expandafter\let\xysplineedges@\relax
2505 % \bgroup
2506 \xylowtolerance@ \splined@@
2507 \ifx\splineedges@\empty\expandafter\splineslowScan@\fi
2508 \ifx\splineedges@\relax\expandafter\splinenostart@\fi
2509 \egroup }%  %(4)
2511 \xydef@\splineslowScan@{%
2512 \let\splineStarttest=\splineSlowStarttest
2513 \let\splinescanStarttest=\relax
2514 \def\splinerec@{\let\splinerec@=\splineSrec@ \splinedecast@@}%
2515 \splined@@ }
2517 \xydef@\splineslowEnd@{%
2518 \global\let\splineEndtest=\splineSlowEndtest
2519 \let\splinescanEndtest=\relax
2520 \def\splinerec@{\let\splinerec@=\splineErec@ \splinedecast@@}%
2521 \splined@@ }
2523 \xydef@\splinenostart@{%
2524 \def\segmentnum@{1}\splinelength@=\z@ \splineval@=\z@
2525 \xynoedgespline@{start}\splineRecordValue@ }
2527 \xydef@\splineendScan@{\bgroup % %(3)<-----------
2528 \bgroup %  %(7)
2529 \splinetrace@{scan for end}%
2530 \global\let\splineadvance@=\splineadvance@@
2531 \let\spline@start=\splinefindEnd@
2532 \let\spline@end=\spline@end@@
2533 \let\splinefinish@=\splinefinish@@
2534 \let\splinewhich=\relax
2535 \global\splinelength@=\z@
2536 % \let\splinerec@=\splineErec@
2537 \global\let\splineEndtest=\splineEndtest@
2538 \def\splinerec@{\let\splinerec@=\splineErec@ \splinedecast@@}%
2539 \expandafter\def\expandafter\prevedges@\expandafter{\splineedges@}%
2540 \xylowtolerance@ \splined@@
2541 \ifx\splineedges@\prevedges@\expandafter\splineslowScan@\fi
2542 \egroup \egroup}
2544 \xydef@\splinescanbreak@{%
2545 \splinetrace@{SCANBREAK}%
2546 \gdef\breakedges@{}%
2547 \DN@{0}\ifx\next@\bstartPLACE@
2548 \DN@{\bgroup \def\tmp@####1;####2,####3;####4,{%
2549  \global\splineval@=####2\relax}%
2550 \expandafter\expandafter\expandafter\tmp@\xysplineedges@

2551 \def\segmentnum@{1}\splineRecordBreakValue@ \egroup}%
2552 \else
2553 \bgroup \cv@start
2554 \expandafter\DN@\expandafter{\the\Edge@c}\DNii@{\zeroEdge}%
2555 \ifx\next@\nextii@ \aftergroup\splinezerostart
2556 \else\aftergroup\splinewidestart\fi
2557 \egroup
2558 \fi \next@
2559 \DN@{1}\ifx\next@\bendPLACE@
2560 \DN@{\bgroup \def\tmp@####1;####2,####3;####4,{%
2561  \global\splineval@=####4\relax}%
2562 \expandafter\expandafter\expandafter\tmp@\xysplineedges@
2563 %%   \multiply\splineval@\m@ne \advance\splineval@\p@
2564 %%   \def\segmentnum@{1}
2565 \getcrvsegsnum@ \edef\segmentnum@{\the\count@}%
2566 \global\multiply\splineval@\count@
2567 \splineRecordEndBreakValue@ \egroup}%
2568 \else
2569 \bgroup \cv@end
2570 \expandafter\DN@\expandafter{\the\Edge@c}\DNii@{\zeroEdge}%
2571 \ifx\next@\nextii@ \aftergroup\splinezeroend
2572 \else\aftergroup\splinewideend\fi
2573 \egroup
2574 \fi \next@
2575 \expandafter\def\expandafter
2576 \xybreakedges@\expandafter{\breakedges@}%  %(6)
2577 \global\let\breakedges@=\relax %  %(8)
2578 \splinetrace@{break params: \xybreakedges@::\bstartPLACE@--\bendPLACE@}%
2579 \expandafter\let\xysplineedges@\xybreakedges@ }
2581 \xydef@\getcrvsegsnum@{% sets \count@
2582 \count@=\ptsnum@\relax \ifnum\count@>\@ne\advance\count@\m@ne\fi}
2584 \xydef@\splinezerostart{\DN@{\bgroup
2585 \splinetrace@{splinezerostart:}%
2586 \dimen@=\bstartPLACE@\p@
2587 \global\splineval@=\dimen@
2588 \splineRecordBreakValue@ \egroup }}
2590 \xydef@\splinezeroend{\DN@{\bgroup
2591 \splinetrace@{splinezeroend:}%
2592 \dimen@=\bendPLACE@\p@
2593 \multiply\dimen@\m@ne \advance\dimen@\p@
2594 \def\segmentnum@{0}\global\splineval@=\dimen@
2595 \splineRecordEndBreakValue@ \egroup }}
2597 \xydef@\splinewidestart{\DN@{\bgroup
2598 \splinetrace@{scan for start}%
2599 \let\splinefbcontinue@=\breakstartcontinue@
2600 \let\splinef@pt=\splinef@breakpt
2601 \let\splinef@end=\break@start
2602 \edef\tmp@{{\bstartPLACE@}}%

2603 \expandafter\splinealong@@\tmp@\z@>\endgroup\egroup }}
2605 \xydef@\splinewideend{\DN@{\bgroup
2606 \splinetrace@{scan for wide end}%
2607 \let\splinefbcontinue@=\breakendcontinue@
2608 \let\splinef@pt=\splinef@breakpt
2609 \let\splinef@end=\break@end
2610 \edef\tmp@{{\bendPLACE@}}%
2611 \expandafter\splinealong@@\tmp@\z@<\endgroup\egroup }}
2614 \xydef@\splineSrec@{{%
2615 \splinetrace@{v=\the\splineval@ + d=\the\splinedepth@ :
2616 (\the\X@p,\the\Y@p);(\the\X@c,\the\Y@c):Srec }%
2617 \splineStarttest
2618 \ifsplineplot@
2619 \ifdim\splinedepth@<.0001\p@ \aftergroup\splinefinish@
2620 \global\advance\splineval@ .5\splinedepth@
2621 \else\aftergroup\splinedecast@@ \fi
2622 \else \aftergroup\splineadvance@ \fi}}
2624 \xydef@\splinefindStart@@{\bgroup \bgroup
2625 \expandafter\expandafter\expandafter\getsplineparams@\xysplineparams@
2626 \global\let\splineadvance@=\splineadvance@@
2627 \global\let\splinepoint=\relax
2628 \let\splinegoal@=\splineRecordValue@ \global\dimen5=\z@
2629 {\X@c=\X@p \Y@c=\Y@p \splinescanStarttest }%% first test initial point.

2630 }

2632 \xydef@\splinefindStart@{%
2633 \expandafter\crv@cnt@\xycrvptsnum@\relax
2634 \ifnum\crv@cnt@>\tw@
2635 \crv@cnt@=\@ne \splineplot@false \splinesegment@{\crv@cnt@}%
2636 {\splineStarttest %% test end of segment.
2637 \ifsplineplot@\aftergroup\splineplot@true\fi}%
2638 \ifsplineplot@ \else \searchforStartsegment@ \fi
2639 \splinesegment@{\crv@cnt@}%
2640 \splinetrace@{start is in segment \segmentnum@}%
2641 \else \splinesegment@\@ne \fi
2642 \splineplot@false  \splinefindStart@@

2643 }

This finds the first spline segment whose endpoint is beyond the edge of the object.

2650 \xydef@\searchforStartsegment@{\splineplot@true\loop@
2651 \advance\crv@cnt@\@ne
2652 \expandafter\count@\xycrvptsnum@\relax
2653 \ifnum\count@=\crv@cnt@\expandafter\splineplot@false
2654 \else
2655  \splinesegment@{\crv@cnt@}{\splineStarttest
2656  \ifsplineplot@\aftergroup\splineplot@false
2657  \else\aftergroup\splineplot@true\fi }%
2658 \fi \ifsplineplot@\repeat@

2.1. CURVE AND SPLINE EXTENSION 159

Finding the end is similar, but the spline is searched in reverse order.

2665 \xydef@\splinefindEnd@@{\bgroup \bgroup
2666 \expandafter\expandafter\expandafter\getsplineparams@\xysplineparams@
2667 \splinetrace@{params:\xysplineparams@}%
2668 \splinereverse@@
2669 \splinetrace@{params:\xysplineparams@}%
2670 \global\let\splineadvance@=\splineadvance@@
2671 \global\let\splinepoint=\splinescanEndtest
2672 \let\splinegoal@=\splineRecordEndValue@ \global\dimen5=\z@
2673 {\X@c=\X@p \Y@c=\Y@p \splinescanEndtest }%% first test initial point.

2674 }

2676 \xydef@\splinereverse@@{\splinereverse@@@}
2677 \xydef@\splinereverse@@@{%
2678 \def\postspline@{\d@X=-\d@X \d@Y=-\d@Y}%
2679 \dimen@ii=\X@c \X@c=\X@p \X@p=\dimen@ii
2680 \dimen@ii=\Y@c \Y@c=\Y@p \Y@p=\dimen@ii
2681 \global\dimen5=-\dimen5\relax
2682 \global\advance\dimen5\splinelength@ }
2683 \xydef@\postspline@{}
2685 \xydef@\splineErec@{{%
2686 \dimen@=\splineval@ \advance\dimen@\splinedepth@ %
2687 \splinetrace@{ER (\the\X@p,\the\Y@p);(\the\X@c,\the\Y@c);;;
2688 \the\dimen@,\the\splinedepth@}%
2689 \splineEndtest
2690 \ifsplineplot@
2691 \ifdim\splinedepth@<.0001\p@ \aftergroup\splinefinish@
2692 %   \global\advance\splineval@ .5\splinedepth@
2693 \else\aftergroup\splinedecast@@ \fi
2694 \else \aftergroup\splineadvance@ \fi}}
2696 \xydef@\splinefindEnd@{%
2697 \expandafter\crv@cnt@\xycrvptsnum@\relax
2698 \ifnum\crv@cnt@>\tw@
2699 \advance\crv@cnt@\m@ne
2700 \splineplot@false \splinesegment@{\crv@cnt@}%
2701 {\X@c=\X@p \Y@c=\Y@p \splineEndtest %% test end of segment.
2702 \ifsplineplot@\aftergroup\splineplot@true\fi }%
2703 \ifsplineplot@
2704 \else \searchforEndsegment@ \fi
2705 \splinesegment@{\crv@cnt@}%
2706 \splinetrace@{end is in segment: \segmentnum@ }%
2707 \else \splinesegment@\@ne \fi
2708 \splineplot@false\splinefindEnd@@

2709 }

2710 \xydef@\searchforEndsegment@{\splineplot@true\loop@
2711 \advance\crv@cnt@\m@ne
2712 \ifnum\crv@cnt@=\z@\expandafter\splineplot@false
2713 \else
2714  \splinesegment@{\crv@cnt@}{\X@c=\X@p \Y@c=\Y@p \splineEndtest

2715  \ifsplineplot@\aftergroup\splineplot@false
2716  \else\aftergroup\splineplot@true\fi}%
2717 \fi \ifsplineplot@\repeat@

2718 }

These are the tests, to determine when the edge-point has been found.

2724 \xydef@\splinescanStarttest{%
2725 \splinetrace@{SST (\the\X@c,\the\Y@c); \the\splinelength@, \the\splineval@}%
2726 {\splineplot@false\splineStarttest
2727 \ifsplineplot@\expandafter\splinefinish@\fi}}
2729 \xydef@\splinescanEndtest{%
2730 \splinetrace@{SET (\the\X@c,\the\Y@c); \the\splinelength@, \the\splineval@}%
2731 {\splineplot@false\splineEndtest
2732 \ifsplineplot@\expandafter\splinefinish@\fi}}
2736 \xydef@\splineBrec@{{%
2737 \dimen@=\splineval@ \advance\dimen@\splinedepth@ %
2738 \splinetrace@{BR (\the\X@p,\the\Y@p);(\the\X@c,\the\Y@c);;;
2739 \the\dimen@,\the\splinedepth@}%
2740 \splineEndtest
2741 \ifsplineplot@ \aftergroup\splineadvance@ \else
2742 \ifdim\splinedepth@<.0001\p@ \aftergroup\splinefinish@
2743 %   \global\advance\splineval@ .5\splinedepth@
2744 \else\aftergroup\splinedecast@@ \fi \fi}}
2746 \xydef@\splineBSrec@{{%
2747 \splinetrace@{SR (\the\X@p,\the\Y@p);(\the\X@c,\the\Y@c);;;
2748 \the\dimen@,\the\splinedepth@:SR}%
2749 \splineStarttest
2750 \ifsplineplot@
2751 \ifdim\splinedepth@<.0001\p@ \aftergroup\splinefinish@
2752 \global\advance\splineval@ .5\splinedepth@
2753 \else \advance\splineval@\splinedepth@
2754 \splinetest@ \advance\splineval@-\splinedepth@
2755 \ifsplineplot@\aftergroup\splineadvance@
2756 \else\aftergroup\splinedecast@@\fi

2757 \fi

2758 \else
2759 \global\advance\splineval@\splinedepth@
2760 \aftergroup\splinefinish@ \fi }}
2762 \xydef@\splineBErec@{{%
2763 \dimen@=\splineval@ \advance\dimen@\splinedepth@ %
2764 \splinetrace@{BE (\the\X@p,\the\Y@p);(\the\X@c,\the\Y@c);;;
2765 \the\dimen@,\the\splinedepth@}%
2766 \splineEndtest
2767 \ifsplineplot@
2768 \ifdim\splinedepth@<.0001\p@ \aftergroup\splinefinish@
2769 \global\advance\splineval@ .5\splinedepth@
2770 \else \advance\splineval@\splinedepth@
2771 \splinetest@ \advance\splineval@-\splinedepth@

2772 \ifsplineplot@\aftergroup\splineadvance@
2773 \else\aftergroup\splinedecast@@\fi

2774 \fi

2775 \else
2776 \ifdim\splinedepth@<\p@ \global\advance\splineval@\splinedepth@ \fi
2777 \aftergroup\splinefinish@ \fi }}
2779 \xydef@\splinef@breakpt#1{% gobbles |\splinecancel|
2780 \ifdim\splineval@>\z@
2781 \splinetrace@{found: val=\the\splineval@;(\the\X@c,\the\Y@c)}%
2782 \else
2783 \splinetrace@{found: val=\the\splineval@;(\the\X@p,\the\Y@p)}%
2784 \fi  \splinefbcontinue@ }
2786 \xydef@\splinef@pt@@{%
2787 \ifdim\splineval@>\z@
2788 \splinetrace@{found: val=\the\splineval@;c:(\the\X@c,\the\Y@c)}%
2789 \global\dimen@i=\X@c \global\dimen3=\Y@c
2790 \else
2791 \splinetrace@{found: val=\the\splineval@;p:(\the\X@p,\the\Y@p)}%

2792 \fi

2793 \setsplinedir@ \global\dimen5=\d@X \global\dimen7=\d@Y
2794 \global\splineval@=\splineval@
2795 \aftergroup\splinefocus@ }
2797 \xydef@\findbreakwarning@#1{%
2798 \xywarning@{#1 of break not found: bSTART=\bstartPLACE@, bEND=\bendPLACE@}%
2799 \DN@{#1}\def\DNii@{start}\ifx\next@\nextii@\splineRecordBreakValue@
2800 \else\splineRecordEndBreakValue@\fi\egroup}%
2802 \xydef@\breakstartcontinue@{\bgroup \cv@start
2803 %\xystatus@{SS}%
2804 \expandafter\DN@\expandafter{\the\Edge@c}\DNii@{\zeroEdge}%
2805 \ifx\next@\nextii@ \aftergroup\breakstartfound@
2806 \else \aftergroup\breakstartcontinue@i\fi \egroup }%
2808 \xydef@\breakstartcontinue@i{%
2809 \splinetrace@{move to start edge, from (\the\X@c,\the\Y@c): val=\the\splineval@ }%
2810 % \global\let\splinetest@=\splineStarttest
2811 \global\let\splineEndtest=\splineBreakStarttest@
2812 \global\let\splinetest@=\splineBreakStarttest@
2813 % \global\let\splinerec@=\splineSrec@
2814 \gdef\splinerec@{\global\let\splinerec@=\splineSrec@ \splinedecast@@}%
2815 \global\let\splinepoint=\relax
2816 \global\let\spline@end=\checkfoundSbreak@
2817 % \global\let\splinegoal@=\splineRecordBreakValue@
2818 \global\let\splinegoal@=\splineRecordSBreakValue@
2819 \global\let\splinefinish@=\splinefinish@@  }
2821 \xydef@\breakstartfound@{%
2822 \splinetrace@{found start edge, at (\the\X@c,\the\Y@c): val=\the\splineval@ }%
2823 \global\let\splinetest@=\splineStarttest
2824 \gdef\splinerec@{\splinegoal@ \global\let\splinerec@=\splinefinish@ }%

2825 \global\let\splinepoint=\relax
2826 \global\let\spline@end=\relax %\checkfoundSbreak@
2827 \global\let\splinegoal@=\splineRecordBreakValue@
2828 \global\let\splinefinish@=\splinefinish@@

2829 }

2831 \xydef@\checkfoundSbreak@{%
2832 \ifnum\xycrvptsnum@<\thr@@\DN@{\findbreakwarning@{start}}%
2833 \else\DN@{\searchBreakSsegment@}\fi \next@ }%
2835 \xydef@\searchBreakSsegment@{%
2836 \crv@cnt@=\segmentnum@ \DN@{}\count@=\crv@cnt@
2837 \DNii@{}\ifnum\splineval@=\z@ \ifnum\crv@cnt@=\@ne
2838 \ifnum\xycrvptsnum@=\@ne\count@=\z@\DNii@{\egroup}\fi
2839 \else \DN@{\egroup}\fi
2840 \else \ifnum\splineval@=\m@ne
2841 \else \advance\crv@cnt@\@ne \fi \fi
2842 \ifnum\crv@cnt@=\xycrvptsnum@\relax
2843 \ifnum\xycrvptsnum@>\tw@ \DNii@{\egroup}\fi
2844 \DN@{\expandafter\splineRecordBreakValue@\nextii@}%
2845 \else
2846 \DN@{\splinesegment@{\crv@cnt@}\splinesetparams@
2847 \splined@@ \egroup}%
2848 \fi \next@ }
2850 \xydef@\checkfoundEbreak@{%
2851 \ifnum\xycrvptsnum@<\thr@@\DN@{\findbreakwarning@{end}}%
2852 \else\DN@{\searchBreakEsegment@}\fi \next@ }%
2854 \xydef@\searchBreakEsegment@{%
2855 \crv@cnt@=\segmentnum@ \DN@{}\count@=\crv@cnt@
2856 \DNii@{}\ifnum\splineval@=\z@ \ifnum\crv@cnt@=\@ne
2857 \ifnum\xycrvptsnum@=\@ne\count@=\z@\DNii@{\egroup}\fi
2858 \else\DN@{\egroup}\fi
2859 \else \advance\crv@cnt@\m@ne \fi
2860 \ifnum\count@=\z@
2861 % \ifnum\crv@cnt@=\z@
2862 \ifnum\xycrvptsnum@>\tw@ \splineval@=\m@ne\p@
2863 \DNii@{\egroup}\fi
2864 \DN@{\expandafter\splineRecordEndBreakValue@\nextii@}\else
2865 \DN@{\splinesegment@{\crv@cnt@}\splinereverse@
2866 \readsplineparams@ \splined@@ \egroup}%
2867 \fi \next@ }
2869 \xydef@\break@start{\egroup \egroup
2870 \splinetrace@{scan for start}%
2871 \global\let\splineadvance@=\splineadvance@@  %(3)
2872 \let\spline@start=\splinefindBStart@   %(3)
2873 \let\spline@end=\egroup
2874 \let\splinefinish@=\splinefinish@@
2875 \let\splinewhich=\relax
2876 \global\let\splineadvance@=\splineadvance@@
2877 \global\let\splinepoint=\relax

2878 \let\splinegoal@=\splineRecordBreakValue@
2879 \global\dimen5=\z@  \global\splinelength@=\z@
2880 \let\splinerec@=\splineSrec@
2881 \def\breakedges@{}%
2882 \bgroup \bgroup \splined@@ }
2884 \xydef@\splinefindBStart@{\bgroup
2885 % \global\splineval@=\z@ \global\splinedepth@=.5\p@}
2886 \global\splineval@=\z@ \splinedepth@=.5\p@}
2888 \xydef@\breakendcontinue@{\bgroup
2889 \edef\tmp@{\X@p = \the\X@c \Y@p=\the\Y@c}\cv@end\tmp@ % <--- irrelevant ?
2890 \expandafter\DN@\expandafter{\the\Edge@c}\DNii@{\zeroEdge}%
2891 %\xystatus@{EE}%
2892 \ifx\next@\nextii@ \aftergroup\breakendfound@
2893 \else\aftergroup\breakendcontinue@i\fi \egroup }%
2895 \xydef@\breakendcontinue@i{%
2896 \splinetrace@{move to end edge, from (\the\X@c,\the\Y@c): val=\the\splineval@ }%
2897 % \global\let\splinetest@=\splineEndtest
2898 \global\let\splineEndtest=\splineBreakEndtest@
2899 \global\let\splinetest@=\splineBreakEndtest@
2900 \gdef\splinerec@{\global\let\splinerec@=\splineErec@\splinedecast@@}%
2901 \global\let\splinepoint=\relax
2902 \global\let\spline@end=\checkfoundEbreak@
2903 % \global\let\splinegoal@=\splineRecordEndBreakValue@
2904 \global\let\splinegoal@=\splineRecordEBreakValue@
2905 \global\let\splinefinish@=\splinefinish@@
2906 \splinerec@ }
2908 \xydef@\splineRecordEBreakValue@{%\getcrvsegsnum@
2909 \splinetrace@{\the\count@\space segments, \the\splineval@}%
2910 %  \ifnum\segmentnum@>\z@ \dimen@=\segmentnum@\p@ \else \dimen@=\p@\fi
2911 %  \advance\dimen@-\splineval@\relax
2912 %  \ifnum\count@>\@ne \divide\dimen@\count@\fi
2913 %  \global\splineval@=\dimen@
2914 \splineRecordEndBreakValue@ }
2916 \xydef@\splineRecordSBreakValue@{\getcrvsegsnum@
2917 \dimen@=\splineval@
2918 \advance\dimen@\segmentnum@\p@ \advance\dimen@-\p@
2919 \dimen@nth\count@\dimen@
2920 \global\splineval@=\dimen@ \def\segmentnum@{1}%
2921 \splineRecordBreakValue@ }
2923 \xydef@\breakendfound@{%
2924 \splinetrace@{found end edge, at (\the\X@c,\the\Y@c): val=\the\splineval@ }%
2925 \global\let\splinetest@=\splineEndtest
2926 \gdef\splinerec@{\splinegoal@ \global\let\splinerec@=\splinefinish@}%
2927 \global\let\splinepoint=\relax
2928 \global\let\spline@end=\relax  %\checkfoundEbreak@
2929 \global\let\splinegoal@=\splineRecordEndBreakValue@
2930 \global\let\splinefinish@=\splinefinish@@  }

2933 \xydef@\break@end{\egroup \egroup
2934 \global\let\splineadvance@=\splineadvance@@
2935 \let\spline@start=\splinefindBEnd@
2936 \let\spline@end=\egroup
2937 \let\splinefinish@=\splinefinish@@
2938 \let\splinewhich=\relax
2939 \global\let\splineadvance@=\splineadvance@@
2940 \global\let\splinegoal@=\splineRecordEndBreakValue@
2941 \global\splinelength@=\z@
2942 \let\splinerec@=\splineErec@
2943 \global\let\splineEndtest=\splineEndtest@
2944 \bgroup \splined@@ }
2946 \xydef@\splinefindBEnd@{\bgroup\bgroup
2947 \splinereverse@ \readsplineparams@
2948 \global\splineval@=\z@ }

This appends the new information to that currently stored in the control sequence referenced by \xysplineparams@. It is temporarily stored globally in \splineparams@, to be later transferred to (the c.s. referenced by) \xysplineparams@ when at the appropriate level of groupingl.

2958 \xydef@\splineRecordValue@{%
2959 \ifx\unknown\segmentnum@\relax
2960 \else
2961 \getcrvsegsnum@
2962 \dimen@=\splineval@ \advance\dimen@ \segmentnum@\p@
2963 \advance\dimen@-\p@ \dimen@nth\count@\dimen@
2964 \global\splineval@=\dimen@

2965 \fi

2966 \xdef\splineedges@{\splineedges@\the\splinelength@;\the\splineval@,}%
2967 \splinetrace@{found edge: \splineedges@}}
2969 \xydef@\splineRecordEndValue@{%
2970 \ifx\unknown\segmentnum@\relax
2971 \else
2972 \getcrvsegsnum@
2973 \dimen@=\splineval@ \advance\dimen@ \count@\p@
2974 \advance\dimen@-\segmentnum@\p@ \dimen@nth\count@\dimen@
2975 \global\splineval@=\dimen@

2976 \fi

2977 \xdef\splineedges@{\splineedges@\the\splinelength@;\the\splineval@,}%
2978 \splinetrace@{found edge: \splineedges@}}
2980 \xydef@\splineRecordBreakValue@{%
2981 \ifx\unknown\segmentnum@\relax
2982 \else\expandafter\advance\expandafter\splineval@\segmentnum@\p@
2983 \count@=\segmentnum@\relax
2984 \ifnum\count@>0 \advance\splineval@-\p@ \fi\fi
2985 % \ifx\breakedges@\relax\relax\else\ifx\breakedges@\empty\else
2986 %  \ifdim\splineval@<\p@\ifdim\splineval@>\z@
2987 %       \expandafter\testbreakedges@\breakedges@ @%
2988 %  \fi\fi\fi\fi
2989 \xdef\breakedges@{\breakedges@\the\splinelength@;\the\splineval@,}%

2990 \global\let\spline@end=\egroup
2991 \splinetrace@{found break edge: \breakedges@}}
2993 \xydef@\splineRecordEndBreakValue@{%
2994 \ifx\unknown\segmentnum@\relax
2995 \else\count@=\segmentnum@\relax \ifnum\count@=\z@
2996 \else \getcrvsegsnum@
2997 \count@@=\count@ \advance\count@@-\segmentnum@\relax
2998 \dimen@=\splineval@ \advance\dimen@ \count@@\p@
2999 \dimen@nth\count@\dimen@
3000 \global\splineval@=\dimen@
3001 \fi\fi
3002 % \multiply\splineval@\m@ne \advance\splineval@\p@ % <----------  !!!
3003 \ifdim\splineval@<\z@ \relax\splineval@=\z@ \fi
3004 \ifx\breakedges@\relax\relax\else\ifx\breakedges@\empty\else
3005 \ifdim\splineval@<\p@\relax \ifdim\splineval@>\z@
3006  \expandafter\testbreakedges@\breakedges@ @%
3007 \fi\fi\fi\fi
3008 \xdef\breakedges@{\breakedges@\the\splinelength@;\the\splineval@,}%
3009 \global\let\spline@end=\egroup
3010 \splinetrace@{found break edge: \breakedges@}}
3012 \xydef@\testbreakedges@#1;#2,#3@{\bgroup \dimen@=#2\relax
3013 \advance\dimen@\splineval@ \advance\dimen@-\p@
3014 \splinetrace@{testbreak: #1;#2,#3@  \the\splineval@::\the\dimen@}%
3015 \DN@{\egroup}\ifdim\dimen@>\z@
3016 \edef\next@{\egroup\def\noexpand\breakedges@{#1;1pt,#3}}%
3017 \else\ifdim\zz@\dimen@
3018 \edef\next@{\egroup\def\noexpand\breakedges@{#1;1pt,#3}}%
3019 \fi \fi \next@ }
3021 \xydef@\splineRecordBreakEValue{%
3022 \ifdim\splineval@>\z@
3023 \splineval@=-\splineval@ \advance\splineval@\p@ \fi
3024 \splineRecordBreakValue@ }%

Use the following distance approximation:

dist = \{ \begin{matrix}dX + .5dY/dXdY & if dY/dXdY < (\sqrt{2} − 1) × dX \\ \frac{3\sqrt{2}}{4}dX + \frac{\sqrt{2}}{4}dY/dXdY & if (\sqrt{2} − 1) × dX < dY/dXdY < dX \end{matrix}

and similarly, interchanging dY and dX when dY > dX.

\sqrt{2} ≈ 1.41422, (\sqrt{2})/2 ≈ 0.70711, (\sqrt{2})/4 ≈ 0.353555, 3(\sqrt{2})/4 ≈ 1.060665

3045 \xydef@\xydist@#1#2{\ifdim#1>#2\relax
3046 \quotient@@\tmp@#2#1\expandafter\dimen@ii\tmp@#2\relax
3047 \ifdim\dimen@ii>.41422#1\relax
3048 \dimen@=1.060665#1\advance\dimen@ .353555\dimen@ii\relax
3049 \else \dimen@=#1\advance\dimen@.5\dimen@ii\fi
3050 \else
3051 \quotient@@\tmp@#1#2\expandafter\dimen@ii\tmp@#1\relax
3052 \ifdim\dimen@ii>.41422#2\relax
3053 \dimen@=1.060665#2\advance\dimen@ .353555\dimen@ii\relax

3054 \else \dimen@=#2\advance\dimen@.5\dimen@ii\fi
3055 \fi}
3059 \xydef@\splineDadvance@{\splineadvance@@
3060 \expandafter\splineDadvance@@\splineDadvance@@@}
3061 \xydef@\splineDadvance@@#1#2#3#4{%
3062 {\d@X=#1\advance\d@X-#2\ifdim\d@X<\z@ \d@X=-\d@X\fi
3063 \d@Y=#3\advance\d@Y-#4\ifdim\d@Y<\z@ \d@Y=-\d@Y\fi
3064 \xydist@\d@X\d@Y
3065 \global\advance\splinelength@\dimen@
3066 \splinetrace@{d=(\the\d@X,\the\d@Y): v=\the\splineval@: l=\the\splinelength@}%

3067 }}

3071 \xydef@\spline@end@{\lastsplinepoint@ \egroup \egroup
3072 \ht\z@=\z@ \dp\z@=\z@ \wdz@=\z@ \boxz@}%
3073 \gdef\splinetest@{\splineplot@true}
3074 \xydef@\spline@end@@{\egroup \egroup}

...value for \splinerec@ for the fast find...

3081 \xydef@\splinefrec@{{%
3082 \advance\splineval@\splinedepth@
3083 \splinetrace@{F:(\the\X@p,\the\Y@p);(\the\X@c,\the\Y@c);;
3084 \the\splineval@;\the\splinedepth@}%
3085 \ifdim\dimen5=\splineval@ \aftergroup\splinefinishf@
3086 \else \dimen@=\dimen5\advance\dimen@-\splineval@
3087 \ifdim\dimen@<\z@ \dimen@=-\dimen@ \fi
3088 \ifdim\dimen@<.0001\p@ \aftergroup\splinefinishf@
3089 \else
3090 \ifdim\dimen5<\splineval@\aftergroup\splinedecast@@
3091 \else \aftergroup\splineadvance@
3092 \fi\fi\fi}}
3094 \xydef@\splinefinishf@{\global\advance\splineval@\splinedepth@
3095 \splinefinish@}%

The macro \spline@find#1#2 attempts to finds a specific point on a single spline segment. #1 is the parameter value, in the range [0,1] on that segment; #2 is a ⟨dimen⟩ denoting how much further to slide along the segment. It really only checks whether #2 has a negative value before passing the information to \spline@@find#1#2, which does the actual search.

If #2 is negative then the spline segment is searched in the reverse direction, starting at its endpoint. This is done by reversing the order of the control points, hence the parameter value found as x implies that we really want 1−x on the un-reversed segment. Similarly the resulting vaules for \d@X and \d@Y must be negated. The instructions to do this are loaded into a macro \postfind@ which is expanded once the search has been completed. For an unreversed segment \postfind@ expands to {}.

3115 \xydef@\spline@find#1#2#3{%
3116 \splinetrace@{spline@find #1 #2 #3}%
3117 \readsplineparams@
3118 \global\let\splinefinish@=\splinefinish@@
3119 \global\let\splinegoal@=\splinef@pt
3120 \global\let\splinepoint=\relax
3121 \dimen@=#1\relax\dimen@ii=#2\relax

3122 \ifdim\dimen@ii=\z@ \def\postfind@{}%
3123 \else\def\postfind@{}%
3124 \ifdim\dimen@ii<\z@ \splinereverse@
3125 \readsplineparams@
3126 \splinetrace@{reverse orientation: (\the\X@p,\the\Y@p),(\the\X@c,\the\Y@c)}%
3127 \dimen@=#1\relax\dimen@ii=#2\relax
3128 \multiply\dimen@\m@ne \advance\dimen@\p@ \multiply\dimen@ii\m@ne
3129 \def\postfind@{\d@X=-\the\d@X \d@Y=-\the\d@Y \noexpand\reversesplineval@}%
3130 \fi\fi
3131 \expandafter\splinetrace@\expandafter{\xysplineparams@}%
3132 \edef\next@{\noexpand\spline@@find{\the\dimen@}{\the\dimen@ii}{#3}}%
3133 \next@ }
3135 \xydef@\reversesplineval@{\splineval@=-\splineval@ \advance\splineval@\p@ }
3141 \xydef@\spline@@find#1#2#3{%
3142 \splinetrace@{spline@@find #1 #2 #3}%
3143 \let\splinerec@=\splinefrec@
3144 \global\let\splineadvance@=\splineadvance@@
3145 \dimen5=#1\relax
3146 \ifdim #2=\z@\relax
3147 \ifdim #1=\z@\relax \bgroup
3148  \let\splined@@=\spline@@knot
3149  \global\splineval@=\m@ne\p@
3150 \else\ifdim #1=\p@\relax \bgroup
3151  \let\splined@@=\spline@@knot
3152  \global\splineval@=\z@
3153 \else
3154  \global\splineval@=\z@
3155  \global\let\splineadvance@=\splineadvance@@
3156  \DN@{#3}\ifx\next@\empty \setsplinetest@\splineval@>{#1}{}%
3157  {{\ifdim\splineval@=\dimen5\aftergroup\splineplot@false\fi}}%
3158  \else\DNii@{>}\ifx\next@\nextii@
3159  \setsplineundertest@\splineval@>{#1}{}{}%
3160  \let\splinerec@=\splineBSrec@
3161  \else\DNii@{<}\ifx\next@\nextii@
3162  \setsplineundertest@\splineval@>{#1}{}{}%
3163  \let\splinerec@=\splineBErec@
3164  \else\xywarning@{unknown find-mode: #3}\fi\fi\fi
3165 \fi\fi
3166 \else
3167 \global\splineval@=\z@
3168 \def\splineslidetest@@{%
3169  \setsplinetest@\splinelength@<{#2}{}{}}%
3170 \let\splinefinish@=\splinefcontinue@

3171 \fi

3172 \let\spline@end=\splinef@end
3173 \let\splinepoint@=\relax
3174 \splinelength@=\z@
3175 \def\spline@start{\bgroup\xylowtolerance@}%

3176 \splined@@ }
3178 \xydef@\spline@@knot{%
3179 \let\setsplinedir@=\setsplineknotdir@
3180 \splinesetparams@\spline@start
3181 % \global\splinedepth@=\p@
3182 \splinedepth@=\p@
3183 \global\dimen@i=\X@p \global\dimen3=\Y@p
3184 \splinefinishf@ \spline@end \egroup }
3186 \xydef@\splinefcontinue@{%
3187 \splinetrace@{sliding... from (\the\X@c,\the\Y@c): val=\the\splineval@ }%
3188 \global\let\splinerec@=\splinerec@@
3189 \global\splinelength@=\z@
3190 \global\splineval@=\splineval@
3191 \global\let\splinepoint=\splinefindtest@
3192 \global\let\splinegoal@=\splinef@pt
3193 \global\let\splineadvance@=\splineDadvance@
3194 \global\let\splinefinish@=\splinefinish@@
3195 \splineslidetest@@

3196 }

3198 \xydef@\splinefindtest@{%
3199 \splinetrace@{SFT (\the\X@c,\the\Y@c); \the\splinelength@, \the\splineval@}%
3200 {\splineplot@false\splinetest@
3201 \ifsplineplot@\expandafter\splinefinishf@\fi}}
3203 \def\setsplineundertest@#1#2#3#4#5{%
3204 \splinetrace@{setsplineundertest@: #1,#2,#3,#4,#5,}%
3205 \DNii@{\gdef\splinetest@}%
3206 \DN@##1\next{\def\tmp@{{\splineplot@false
3207 \ifdim#1#2##1\relax #4\else\splineplot@true#5\fi }}}%
3208 \next@#3\relax\next
3209 \expandafter\nextii@\tmp@ }
3211 \xydef@\splinef@end{\edef\tmp@{\egroup\splinelength@=\the\splinelength@}\tmp@}
3212 \xydef@\splinef@pt{%
3213 \ifdim\splineval@>\z@
3214 \splinetrace@{found: val=\the\splineval@;c:(\the\X@c,\the\Y@c)}%
3215 \global\dimen@i=\X@c \global\dimen3=\Y@c
3216 \else
3217 \splinetrace@{found: val=\the\splineval@;p:(\the\X@p,\the\Y@p)}%

3218 \fi

3219 \setsplinedir@ \global\dimen5=\d@X \global\dimen7=\d@Y
3220 \global\splineval@=\splineval@
3221 \aftergroup\splinefocus@ }
3225 \def\setsplinetest@#1#2#3#4#5{%
3226 \DNii@{\gdef\splinetest@}%
3227 \DN@##1\next{\def\tmp@{{\splineplot@false \ifdim#1#2##1\relax
3228 #4\else\splineplot@true#5\fi}}}%
3229 \next@#3\relax\next
3230 \expandafter\nextii@\tmp@ }%

3236 \xydef@\splinefocus@{%
3237 \d@X=\dimen5\relax \d@Y=\dimen7\relax \setsplinedir@ }
3239 \xydef@\splinesegment@#1{}

There are some extra hooks.

3247 \xydef@\xyprecurve@{}
3248 \xydef@\xypostcurve@{}
3252 \xydef@\splineset@{%
3253 \splinetrace@{splineset@:}%
3254 \ifx\bstartPLACE@\empty %\splinetrace@{invisible curve}%
3255 \DN@{\xyprecurve@
3256 \edef\tmp@{\egroup \X@max=\the\X@max \X@min=\the\X@min
3257  \Y@max=\the\Y@max \Y@min=\the\Y@min}\tmp@ \xypostcurve@ }%
3258 \else
3259 \DN@{\xyprecurve@ \xysplinespecialcases@
3260 \edef\tmp@{\egroup \X@max=\the\X@max \X@min=\the\X@min
3261  \Y@max=\the\Y@max \Y@min=\the\Y@min}\tmp@ \xypostcurve@ }%

3262 \fi

3263 \next@ }

For the actual setting, provide hooks which will allow alternative back-ends to be used in the special cases.

3270 \xydef@\xysplinespecialcases@{%
3271 \ifx\empty\xycrvdrop@
3272 \ifx\empty\xycrvconn@ \DN@{\splinesolid@}%
3273 \else \DN@{ \dir{-}}\ifx\next@\xycrvconn@ \DN@{\splinesolid@}%
3274 \else \DN@{ \dir 2{-}}\ifx\next@\xycrvconn@ \DN@{\splinedoubled@}%
3275 \else \DN@{ \dir{=}}\ifx\next@\xycrvconn@ \DN@{\splineribboned@}%
3276 \else \DN@{ \dir {2.}}\ifx\next@\xycrvconn@ \DN@{\splinedoubled@}%
3277 \else \DN@{ \dir 3{-}}\ifx\next@\xycrvconn@ \DN@{\splinetrebled@}%
3278 \else \DN@{ \dir {3.}}\ifx\next@\xycrvconn@ \DN@{\splinetrebled@}%
3279 \else \DN@{ \dir{--}}\ifx\next@\xycrvconn@ \DN@{\splinedashed@}%
3280 \else \DN@{ \dir{.}}\ifx\next@\xycrvconn@ \DN@{\splinedotted@}%
3281 \else \DN@{ \dir{:}}\ifx\next@\xycrvconn@ \DN@{\splinedbldotted@}%
3282 \else \ifdim\splinetol@>\z@ \else \splinedefaulttol@ \fi
3283 \DN@{\splineset@@}\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
3284 \else
3285 \DN@{\splineset@@}%
3286 \fi \ifInvisible@\DN@{}\fi \next@ }

The special cases are handled just like the normal case except However the control sequence names provide a place for rebinding to accomodate alternative back-ends.

3294 \xydef@\splinesolid@{\setbox\splinebox@=\zerodot \def\xycrvdrop@{ }%
3295 \def\xycrvconn@{}\splineset@@}
3297 \xydef@\splinedoubled@{\splinedefaulttol@\def\xycrvdrop@{ }\def\splinedrop@{}%
3298 \def\xycrvconn@{!C\dir2{.}}\splineset@@}
3300 \xydef@\splineribboned@{\splinedefaulttol@\def\xycrvdrop@{ }\def\splinedrop@{}%
3301 \def\xycrvconn@{!C\dir{:}}\splineset@@}

3303 \xydef@\splinetrebled@{\splinedefaulttol@\def\xycrvdrop@{ }\def\splinedrop@{}%
3304 \def\xycrvconn@{!C\dir3{.}}\splineset@@}
3306 \xydef@\splinedashed@{\splinetol@=1.5pc \def\xycrvdrop@{ }%+=<10pt>[o]{}}%
3307 \def\splinedrop@{}\edef\xycrvconn@{\noexpand!C\noexpand\dir{\addDASH@{}}}%
3308 \splineset@@}
3310 \xydef@\splinedotted@{\setbox\splinebox@=\zerodot \def\xycrvdrop@{ }%
3311 \splinetol@=1.5\jot \def\xycrvconn@{}\splineset@@}
3313 \xydef@\splinedbldotted@{\def\xycrvdrop@{ }\def\splinedrop@{}%
3314 \splinetol@=1.5\jot \def\xycrvconn@{!C\dir{:}}\splineset@@}

This establishes the test appropriate to actually setting the spline curve. Global definitions are used. This may not always be necessary!!

Bug: the 7.5pt below should be the \Step@@ method to be included.

3325 \xydef@\splineset@@{%
3326 \readsplineparams@
3327 \ifx\xycrvdrop@\empty \splinetol@=7.5\p@
3328 \def\splinedefaulttol@{\splinetol@=7.5\p@}\def\splinedrop@{}%
3329 \else\edef\splinedefaulttol@{\splinetol@=\the\splinetol@}\fi
3330 \ifx\xycrvconn@\empty \def\splineconn@{}\fi
3331 \splinetrace@{set the curve: >\the\dimen5, <\the\dimen7}%
3332 \global\let\splineadvance@=\splineadvance@@
3333 \let\splinerec@=\splineTrec@
3334 \def\splineStarttest{\splinetest@}%
3335 \global\let\splinepoint=\relax %6
3336 \let\spline@start=\spline@start@
3337 \let\spline@end=\spline@end@ %5
3338 \ifdim\dimen7=\p@
3339 \gdef\splinecontinue{\splinesetting@
3340  \global\let\splinetest@=\splineplot@true}%
3341 \else
3342 \ifdim\dimen7=\tw@\p@
3343 %%   \ifdim\bendPLACE@\p@=\z@ \emptyspline@ \else
3344  \ifdim\bendPLACE@\p@=\p@ %\emptyspline@
3345 \fi %%\fi
3346 \else
3347 \xdef\splinecontinue{\noexpand\setsplinetest@
3348 \splineval@>{\the\dimen7}{\noexpand\splinebreakcancel@}{}%
3349 \noexpand\splinesetting@ }%
3350 \fi\fi
3351 \ifdim\dimen7>\z@ \DN@{\splinesetting@\splinecontinue}%
3352 \ifdim\zz@{\dimen5}%
3353 \else
3354 \edef\next@{\noexpand\setsplinetest@
3355  \splineval@<{\the\dimen5}{}%
3356  {\noexpand\expandafter\noexpand\splinecontinue}%
3357  \noexpand\splinesetting@ }%

3358 \fi

3359 \else\DN@{\dimen5=\p@}\fi  % ifdim\dimen7=\z@

3360 \next@

3361 %

3362 \ifdim\dimen5=\p@\DN@{}\else\DN@{\splined@@}\fi \next@

3363 }

3365 \xydef@\emptyspline@{\xywarning@{empty curve subsegment}%
3366 \splinetrace@{bstartPLACE@=\bstartPLACE@, bendPLACE@=\bendPLACE@,
3367 empty segment}%
3368 \gdef\splinecontinue{\splinesetting@
3369  \global\let\splinetest@=\splineplot@false
3370  \global\dimen5=\z@ }}

\splineTrec@ is the initial value for \splinerec@ when a spline is being set. It descends the tree of places on the spline (1) until the required parameter value is found (2a) or is sufficiently close (2b). At this point call \splinesetting@ and \splinecontinue to setup, and proceed with, the actual type-setting.

3380 \xydef@\splineTrec@{{%
3381 \advance\splineval@\splinedepth@                        % (1)
3382 \ifdim\dimen5=\splineval@                               % (2a)
3383 \aftergroup\splinecontinue  % (3)
3384 \else \dimen@=\dimen5\advance\dimen@-\splineval@
3385 \ifdim\dimen@<\z@ \dimen@=-\dimen@ \fi
3386 \ifdim\dimen@<.001\p@  % possibly too high ?           % (2b)
3387 \aftergroup\splinecontinue % (3)
3388 \else
3389 \ifdim\dimen5<\splineval@\aftergroup\splinedecast@@    % (1)
3390 \else \aftergroup\splineadvance@                      % (1)
3391 \fi\fi\fi}}

Setting the curve uses the current \splinerec@@ and sets \splinepoint to \splineplotpt@ to cause objects to be typeset. This must be done via a \gdef rather than a \global\let since it is sometimes necessary to omit the object when it would be too close, see \splinetooclose@.

3401 %\xydef@\splinesetting@{\xyFN@\splinesetting@@}
3402 \xydef@\splinesetting@{\splinesetting@@}
3404 \xydef@\splinesetting@@{%
3405 \splinetrace@{splinesetting@@:}%
3406 \ifdim\splinedepth@=\z@ \splinedepth@=\p@ \fi
3407 \ifdim\splinedepth@=\p@
3408 \def\splinerec@{\global\let\splinerec@=\splinerec@@\splinedecast@@}%
3409 \else \global\let\splinerec@=\splinerec@@ \fi
3410 \gdef\splinepoint{\splineplotpt@}}

This handles, for each point of the curve, whether to place an ⟨object⟩ or horizontal glue.

3417 \xydef@\splineplotpt@{{\global\advance\dimen@i-\X@c
3418 \splinetest@ \DN@{\splineglue@}\ifsplineplot@
3419 %  \splineStarttest@ \ifsplineplot@
3420 %   \splineEndtest@ \ifsplineplot@
3421 \DN@{\dosplineplotpt@}%
3422 %  \fi\fi
3423 \fi \next@ \global\dimen@i=\X@c \global\dimen3=\Y@c }}

3425 \xydef@\splineglue@{\hglue-\dimen@i
3426 \splinetrace@{N:(\the\X@c,\the\Y@c);;\the\dimen@i;\the\dimen3%
3427 ,\the\splinelength@,\the\splineval@,\the\splinedepth@}}
3429 \xydef@\dosplineplotpt@{\ifdim\dimen@i<\z@
3430 \raise\Y@c\hbox to-\dimen@i{\hfill\splinedrop@}%
3431 \else \kern-\dimen@i\raise\Y@c\hbox{\splinedrop@}\fi
3432 \ifx\splineconn@\relax\else\raise\Y@c\hbox{%
3433  \setboxz@h{\splineconn@}\Drop@@}\fi
3434 \splinetrace@{P:(\the\X@c,\the\Y@c);;\the\dimen@i;\the\dimen3
3435 ,\the\splinelength@,\the\splineval@,\the\splinedepth@}}

These handle the “cleaning up” after a point on the curve has been located.

3441 \xydef@\splinefinish@@{\postspline@ \splinegoal@ \splinecancel@ }
3443 \xydef@\splinecancel@{%
3444 \global\let\splinerec@=\relax
3445 \global\let\splinepoint=\relax
3446 \global\let\splinecontinue=\relax
3447 % \global\let\splinedecast@@=\relax
3448 \global\let\splinedecast@=\relax

3449 }

3451 \xydef@\splinebreakcancel@{\bsplinecancel@ \splinecancel@}
3452 \xydef@\bsplinecancel@{\gdef\lastbspline@{\leave@\leave@}%
3453 \global\let\middlebspline@=\lastbspline@ }
3455 \xydef@\splinegoal@{\ifdim\splineval@>\z@
3456 \global\dimen@i=\X@c \global\dimen3=\Y@c \fi
3457 \global\splineval@=\splineval@ \global\splinelength@=\splinelength@
3458 % \setsplineTangent@ }
3459 \splinesetdir@ }
3461 \xylet@\splinefinish@\splinefinish@@
3462 \xylet@\splinewhich\splineDwhich@
3464 \xydef@\squinewhich@{%
3465 \ifdim\dimen5>\squinelength % \X@c=\L@c \Y@c=\D@c
3466 \d@X=\X@c \d@Y=\Y@c \advance\d@X-\L@c \advance\d@Y-\U@c
3467 \advance\squineval-\squinedepth
3468 \else \X@c=\X@p \Y@c=\Y@p \advance\squineval-\squinedepth
3469 \d@X=\L@c \d@Y=\U@c \advance\d@X-\X@p \advance\d@Y-\Y@p \fi
3470 \d@X=-\d@X \d@Y=-\d@Y %%% hack which works.
3471 \squinefinish}
3472 \xydef@\squineDwhich@{%
3473 \ifdim\dimen5>\squinelength % \X@c=\L@c \Y@c=\D@c
3474 \d@X=\X@c \d@Y=\Y@c \advance\d@X-\L@c \advance\d@Y-\U@c
3475 \else \X@c=\X@p \Y@c=\Y@p \advance\squineval-\squinedepth
3476 \d@X=\L@c \d@Y=\U@c \advance\d@X-\X@p \advance\d@Y-\Y@p \fi
3477 \d@X=-\d@X \d@Y=-\d@Y %%% hack which works.
3478 \squinefinish}

Bézier quadratic splines — squines

3488 \xydef@\xyquadbezier@{%
3489 \global\let\splinerec@=\relax
3490 \addtocrvpts@{\def\crvconnect@{\squineconnect@}}%
3491 \xyquadmethods@ \let\splinesegment@=\squinesegment@
3492 \begingroup\setcrvobjects@ \xysplineparams@ \splined@@@
3493 \bgroup \setupsquine@ \squined@ \splineset@ \savespline@ }
3495 \xydef@\xyquadmethods@{%
3496 \def\crvconnect@{\squineconnect@}%
3497 \def\splinereverse@@{\splinereverse@@@}%
3498 \let\getsplineparams@=\getsquineparams@
3499 \let\spline@start@=\squine@start@
3500 \let\splinedecast@@=\squinedecast@
3501 \let\splinerec@@=\squinerec@
3502 \let\splined@@=\squined@@
3503 \let\splineIpt@@=\squineIpt@
3504 \let\splineIadvance@@=\squineIadvance@
3505 \let\splineinfo@=\squineinfo@
3506 \let\setsplinedir@=\setsquinedir@
3507 \let\splinetestcvxhull@=\squinetestcvxhull@
3508 \let\setsplineknotdir@=\setsquineknotdir@
3509 \let\splinereverse@=\squinereverse@
3510 \let\splineDadvance@@@=\squineDadvance@@@
3511 \let\splinesetparams@=\squinesetparams@
3512 \let\splineplot@maybe@@=\squineplot@maybe

3513 }

3515 \xydef@\squineconnect@{\splineconnect@ \crvconnect@@
3516 \let\splinesegment@=\squinesegment@ }%
3518 \xydef@\squinesegment@#1{\xyquadmethods@ \def\segmentnum@{1}%
3519 \setupsquine@ \squined@ }

Use the registers \A@ and \B@ to store the coordinates of the single control point. The whole curve lies within the convex polygon with vertices at p, (p + a)/2, (c + a)/2 and c where a denotes the control point. Set \X@max, \X@min, \Y@max and \Y@min to be the extremes of the coordinates of these 4 points. There may not actually be any point on the curve achieving these extremes, but certainly we get pretty close.

3534 \xydef@\setupsquine@{%
3535 \xycontrolpt@\z@ \X@p=\X@c \Y@p=\Y@c
3536 \xycontrolpt@\@ne \A@=\X@c \B@=\Y@c
3537 \xycontrolpt@\tw@
3538 \ifdim \A@>\X@max
3539 \dimen@=\X@p\advance\dimen@\A@ \dimen@half
3540 \ifdim \dimen@>\X@max \X@max=\dimen@ \fi
3541 \dimen@=\X@c\advance\dimen@\A@ \dimen@half
3542 \ifdim \dimen@>\X@max \X@max=\dimen@ \fi
3543 \else \ifdim \A@<\X@min
3544 \dimen@=\X@p\advance\dimen@\A@ \dimen@half

3545 \ifdim \dimen@<\X@min \X@min=\dimen@ \fi
3546 \dimen@=\X@c\advance\dimen@\A@ \dimen@half
3547 \ifdim \dimen@>\X@min \X@min=\dimen@ \fi
3548 \fi\fi
3549 \ifdim \B@>\Y@max
3550 \dimen@=\Y@p\advance\dimen@\B@ \dimen@half
3551 \ifdim \dimen@>\Y@max \Y@max=\dimen@ \fi
3552 \dimen@=\Y@c\advance\dimen@\B@ \dimen@half
3553 \ifdim \dimen@>\Y@max \Y@max=\dimen@ \fi
3554 \else \ifdim \B@<\Y@min
3555 \dimen@=\Y@p\advance\dimen@\B@ \dimen@half
3556 \ifdim \dimen@<\Y@min \Y@min=\dimen@ \fi
3557 \dimen@=\Y@c\advance\dimen@\B@ \dimen@half
3558 \ifdim \dimen@>\Y@min \Y@min=\dimen@ \fi
3559 \fi\fi }

The algorithm used for computing coordinates of points on quadratic Bézier splines is essentially that used by D. E. Knuth in picmac.tex[?] (aka gpxmac.tex). It is a recursive de Casteljau algorithm of the “divide and conquer” type. (In Knuth’s macros these types of curves were given the name “squines”. This explains some of the control sequence names used here.)

The differences from Knuth’s algorithm are simply to allow more of the available information to be used at points along the spline. In particular the tangent direction can be calculated and tests can be performed to decide when to break out of the algorithm, rather than letting it run its full course.

3579 \xydef@\squinedecast@{\halve@dimen\splinedepth@ %\divide\splinedepth@\tw@
3580 \R@c=\L@c \advance\L@c\X@p \halve@dimen\L@c    %\divide\L@c\tw@
3581 \advance\R@c\X@c \halve@dimen\R@c              %\divide\R@c\tw@
3582 \A@=\L@c \advance\A@\R@c \halve@dimen\A@       %\divide\A@\tw@
3583 \D@c=\U@c \advance\U@c\Y@p \halve@dimen\U@c    %\divide\U@c\tw@
3584 \advance\D@c\Y@c \halve@dimen\D@c              %\divide\D@c\tw@
3585 \B@=\U@c \advance\B@\D@c \halve@dimen\B@       %\divide\B@\tw@
3586 \begingroup \X@c=\A@ \Y@c=\B@ \splinerec@ \endgroup
3587 \begingroup \X@c=\A@ \Y@c=\B@ \splinepoint \endgroup
3588 \X@p=\A@ \L@c=\R@c \Y@p=\B@ \U@c=\D@c \splinerec@}
3590 \xydef@\squinerec@{{\splinefar@false \splinenear@\X@p\X@c\Y@p\Y@c
3591 \ifsplinefar@ \aftergroup\squinedecast@
3592 \else \aftergroup\splineadvance@ \fi}}
3594 \xydef@\squineDadvance@@@{\X@p\L@c\Y@p\D@c}
3596 \xydef@\squineplot@maybe{{\X@p=\L@c \Y@p=\U@c \cv@start \the\Edge@c\@ne
3597 \ifInside@\aftergroup\splineplot@false\else\aftergroup\splineplot@true\fi}}

The tangent direction is computed from the displacement to the “recursive” control point.

3606 \xydef@\setsquinedir@{%
3607 \d@X=\X@c \advance\d@X-\L@c \d@Y=\Y@c \advance\d@Y-\U@c
3608 \dimen@=\ifdim\d@X<\z@-\fi\d@X \ifdim\dimen@<.02\p@
3609 \dimen@=\ifdim\d@Y<\z@-\fi\d@Y \ifdim\dimen@<.02\p@
3610 \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p \fi\fi
3611 \ifdim\X@c=\X@p \ifdim\Y@c=\Y@p
3612 \d@X=\L@c \advance\d@X-\X@p \d@Y=\U@c \advance\d@Y-\Y@p \fi\fi
3613 \setupDirection@ii }

3615 \xydef@\setsquineknotdir@{%
3616 \ifdim\zz@\splineval@ \expandafter \setsquinezerodir@
3617 \else\expandafter \setsquinedir@ \fi }
3619 \xydef@\setsquinezerodir@{%
3620 \d@X=\L@c \advance\d@X-\X@p \d@Y=\U@c \advance\d@Y-\Y@p
3621 \ifdim\zz@\d@X \ifdim\zz@\d@Y
3622 \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p
3623 \fi\fi \setupDirection@ii }

We need a way to access the information in \splineparams.

3629 \xydef@\getsquineparams@#1,#2,#3,#4,#5,#6,#7,{%
3630 \splinelength@=#1\relax\X@p=#2\relax\Y@p=#3\relax
3631 \A@=#4\relax\B@=#5\relax\X@c=#6\relax\Y@c=#7\relax

3632 }

3633 \xydef@\squineinfo@{%
3634 \expandafter\removePT@\the\X@c\space
3635 \expandafter\removePT@\the\Y@c\space
3636 \expandafter\removePT@\the\A@\space
3637 \expandafter\removePT@\the\B@\space
3638 \expandafter\removePT@\the\X@p\space
3639 \expandafter\removePT@\the\Y@p\space
3640 \expandafter\removePT@\the\dimen5\space\space
3641 \expandafter\removePT@\the\dimen7\space

3642 }%

3643 \xydef@\squinereverse@{\readsplineparams@
3644 \expandafter\edef\xysplineparams@{\the\splinelength@,%
3645 \the\X@c,\the\Y@c,\the\A@,\the\B@,\the\X@p,\the\Y@p,}}%

Start the picture by (1) setting a box, as usual. (2) Initialize global variables; these must be global since they are used to store information which must be preserved outside the grouping which is vital to the recursive nature of the algorithm. (3) Move horizontally to the starting point at p. (4) Begin by handling the starting point; i.e. decide whether it is to be plotted or not.

3659 \xydef@\squine@start@{\setboxz@h\bgroup %   %(1)
3660 \global\splinelength@=\z@ \global\dimen@i=\z@ \global\dimen3=\z@ %  %(2)
3661 \kern\X@p  %  %(3)
3662 {\squinesetparams@ \X@c=\X@p \Y@c=\Y@p \firstsplinepoint@   %  %(4)
3663 }\bgroup }
3665 \xydef@\squinesetparams@{%
3666 \global\dimen@i=\X@p \global\dimen3=\Y@p
3667 \L@c=\A@ \U@c=\B@ \R@c=\L@c \D@c=\U@c }%
3669 \xydef@\squined@{%
3670 \expandafter\edef\xysplineparams@{%
3671 \the\z@,\the\X@p,\the\Y@p,\the\A@,\the\B@,\the\X@c,\the\Y@c,}}
3673 \xydef@\squined@@{%
3674 % \global\splinedepth@=\p@
3675 \splinedepth@=\p@
3676 \global\splineval@=\z@
3677 \global\dimen@i=\X@p \global\dimen3=\Y@p
3678 \spline@start

3679 \ifx\splinerec@\relax \let\splinerec@=\squinerec@\fi
3680 \L@c=\A@ \U@c=\B@ \R@c=\L@c \D@c=\U@c
3681 \splinerec@ \spline@end }

Bézier cubic splines

3691 \xydef@\xycubicbezier@{%
3692 \addtocrvpts@{\def\crvconnect@{\cubicconnect@}}%
3693 \xycubicmethods@ \let\splinesegment@=\cubicsegment@
3694 \begingroup \setcrvobjects@ \xysplineparams@ \splined@@@
3695 \bgroup \setupcubic@ \cubiced@ \splineset@ \savespline@ }
3697 \xydef@\xycubicmethods@{%
3698 \def\crvconnect@{\cubicconnect@}%
3699 \def\splinereverse@@{\cubicreverse@@}%
3700 \let\getsplineparams@=\getcubicparams@
3701 \let\spline@start@=\cubic@start@
3702 \let\splinedecast@@=\cubicdecast@
3703 \let\splinerec@@=\cubicrec@
3704 \let\splined@@=\cubiced@@
3705 \let\splineIpt@@=\cubicIpt@
3706 \let\splineIadvance@@=\cubicIadvance@
3707 \let\splineoutsidehull@@=\cubicoutsidehull@
3708 \let\splinetestcvxhull@=\cubictestcvxhull@
3709 \let\splineinfo@=\cubicinfo@
3710 \let\setsplinedir@=\setcubicdir@
3711 \let\setsplineknotdir@=\setcubicknotdir@
3712 \let\splinereverse@=\cubicreverse@
3713 \let\splineDadvance@@@=\cubicDadvance@@@
3714 \let\splinesetparams@=\cubicsetparams@
3715 \let\splineplot@maybe@@=\cubicplot@maybe

3716 }

3718 \xydef@\cubicconnect@{\splineconnect@ \crvconnect@@
3719 \let\splinesegment@=\cubicsegment@ }%
3721 \xydef@\cubicsegment@#1{\xycubicmethods@ \def\segmentnum@{1}%
3722 \setupcubic@ \cubiced@ }

Use the registers \A@, \B@, \dimen3 and \dimen5 to store coordinates of the two control points, denoted l and r say. The whole curve lies within the convex polygon p, (p + l)/2, (c + r)/2 and c where the vertices are not necessarily in this order. Set \X@max, \X@min, \Y@max and \Y@min to be the extremes of the coordinates of these 4 points. There may not actually be any point on the curve achieving these extremes, but certainly we get pretty close.

3737 \xydef@\setupcubic@{%
3738 \xycontrolpt@\z@ \X@p=\X@c \Y@p=\Y@c
3739 \xycontrolpt@\@ne \A@=\X@c \B@=\Y@c
3740 \xycontrolpt@\tw@ \global\dimen3=\X@c \global\dimen5=\Y@c
3741 \xycontrolpt@\thr@@
3742 \adjustmaxmin@ }
3744 \xydef@\adjustmaxmin@{%

3745 \ifdim \A@>\X@max \dimen@=\A@ \advance\dimen@\X@p \dimen@half
3746 \ifdim\dimen@>\X@max \X@max=\dimen@ \fi \else
3747 \ifdim \A@<\X@min \dimen@=\A@ \advance\dimen@\X@p \dimen@half
3748 \ifdim\dimen@<\X@min \X@min=\dimen@ \fi \fi\fi
3749 \ifdim \B@>\Y@max \dimen@=\B@ \advance\dimen@\Y@p \dimen@half
3750 \ifdim\dimen@>\Y@max \Y@max=\dimen@ \fi \else
3751 \ifdim \B@<\Y@min \dimen@=\B@ \advance\dimen@\Y@p \dimen@half
3752 \ifdim\dimen@<\Y@min \Y@min=\dimen@ \fi \fi\fi

3753 %

3754 \ifdim \dimen3>\X@max \dimen@=\dimen3\advance\dimen@\X@c \dimen@half
3755 \ifdim\dimen@>\X@max \X@max=\dimen@ \fi \else
3756 \ifdim \dimen3<\X@min \dimen@=\dimen3\advance\dimen@\X@c \dimen@half
3757 \ifdim\dimen@<\X@min \X@min=\dimen@ \fi \fi\fi
3758 \ifdim \dimen5>\Y@max \dimen@=\dimen5\advance\dimen@\Y@c \dimen@half
3759 \ifdim\dimen@>\Y@max \Y@max=\dimen@ \fi \else
3760 \ifdim \dimen5<\Y@min \dimen@=\dimen5\advance\dimen@\Y@c \dimen@half
3761 \ifdim\dimen@<\Y@min \Y@min=\dimen@ \fi \fi\fi

3762 %

3763 \dimen@=\A@ \advance\dimen@\dimen3 \dimen@half
3764 \ifdim\dimen@>\X@max \X@max=\dimen@
3765 \else \ifdim\dimen@<\X@min \X@min=\dimen@ \fi\fi
3766 \dimen@=\B@ \advance\dimen@\dimen5 \dimen@half
3767 \ifdim\dimen@>\Y@max \Y@max=\dimen@
3768 \else \ifdim\dimen@<\Y@min \Y@min=\dimen@ \fi\fi

3769 }

The recursive algorithm for cubic Bézier splines is similar to the quadratic one. Now there are two “recursive” control points to be calculated upon each subdivision.

On the p-side:

p_{p} = p
l_{p} = (p + l)/2
r_{p} = (p + 2l + r)/4
c_{p} = (p + 3l + 3r + c)/8

while on the c-side

p_{c} = (p + 3l + 3r + c)/8
l_{c} = (l + 2r + c)/4
r_{c} = (r + c)/2
c_{c} = c

Notice that c_{p} = p_{c} and that the tangents match there.

3795 \xydef@\cubicdecast@{\halve@dimen\splinedepth@ %\divide\splinedepth@\tw@
3796 \A@=\L@c \advance\A@\R@c \halve@dimen\A@      %\divide\A@\tw@
3797 \advance\R@c\X@c \halve@dimen\R@c             %\divide\R@c\tw@
3798 \B@=\U@c \advance\B@\D@c \halve@dimen\B@      %\divide\B@\tw@

3799 \advance\D@c\Y@c \halve@dimen\D@c             %\divide\D@c\tw@
3800 \advance\L@c\X@p \halve@dimen\L@c             %\divide\L@c\tw@
3801 \advance\U@c\Y@p \halve@dimen\U@c             %\divide\U@c\tw@
3802 \begingroup
3803 \X@c=\R@c \advance\X@c\L@c \halve@dimen\X@c  %\divide\X@c\tw@
3804 \advance\X@c\A@ \halve@dimen\X@c             %\divide\X@c\tw@
3805 \Y@c=\D@c \advance\Y@c\U@c \halve@dimen\Y@c  %\divide\Y@c\tw@
3806 \advance\Y@c\B@ \halve@dimen\Y@c             %\divide\Y@c\tw@
3807 \R@c=\L@c \advance\R@c\A@ \halve@dimen\R@c   %\divide\R@c\tw@
3808 \D@c=\U@c \advance\D@c\B@ \halve@dimen\D@c   %\divide\D@c\tw@
3809 \bgroup \splinerec@
3810 \egroup \splinepoint \endgroup
3811 \X@p=\L@c \advance\X@p\R@c \halve@dimen\X@p   %\divide\X@p\tw@
3812 \advance\X@p\A@ \halve@dimen\X@p              %\divide\X@p\tw@
3813 \L@c=\R@c \advance\L@c\A@ \halve@dimen\L@c    %\divide\L@c\tw@
3814 \Y@p=\U@c \advance\Y@p\D@c \halve@dimen\Y@p   %\divide\Y@p\tw@
3815 \advance\Y@p\B@ \halve@dimen\Y@p              %\divide\Y@p\tw@
3816 \U@c=\D@c \advance\U@c\B@ \halve@dimen\U@c    %\divide\U@c\tw@
3817 \splinerec@ }
3819 \xydef@\cubicrec@{{\splinefar@false \splinenear@\X@p\X@c\Y@p\Y@c
3820 \ifsplinefar@ \aftergroup\cubicdecast@
3821 \else \aftergroup\splineadvance@ \fi}}
3823 \xydef@\cubicDadvance@@@{\X@p\X@c\Y@p\Y@c}
3825 \xydef@\cubicplot@maybe{{\X@p=\L@c \Y@p=\U@c \cv@start \the\Edge@c\@ne
3826 \ifInside@\aftergroup\cubicplot@maybeii\else\aftergroup\splineplot@true\fi}}
3827 \xydef@\cubicplot@maybeii{{\X@p=\R@c \Y@p=\D@c \cv@start \the\Edge@c\@ne
3828 \ifInside@\aftergroup\splineplot@false\else\aftergroup\splineplot@true\fi}}
3832 \xydef@\cubiced@@{%
3833 % \global\splinedepth@=\p@
3834 \splinedepth@=\p@
3835 \global\splineval@=\z@
3836 \spline@start
3837 \global\dimen@i=\X@p \global\dimen3=\Y@p
3838 \splinerec@ \spline@end }

The tangent direction is computed from the displacement to the “recursive” control point.

3847 \xydef@\setcubicdir@{%
3848 \ifdim\splinedepth@<.001\p@\DN@{\cubiccoarsedir@}%
3849 \else\DN@{\cubicfinedir@}\fi \next@ }
3851 \xydef@\cubicfinedir@{%
3852 \d@X=\X@c \advance\d@X-\R@c \d@Y=\Y@c \advance\d@Y-\D@c
3853 \ifdim\zz@\d@X \ifdim\zz@\d@Y
3854 \d@X=\X@c \advance\d@X-\L@c \d@Y=\Y@c \advance\d@Y-\U@c
3855 \ifdim\zz@\d@X \ifdim\zz@\d@Y
3856 \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p
3857 \fi\fi \fi\fi
3858 % \ifdim\X@c=\X@p \ifdim\Y@c=\Y@p
3859 %  \d@X=\L@c \d@Y=\U@c \advance\d@X-\X@p \advance\d@Y-\Y@p

3860 %  \ifdim\d@X=\z@ \ifdim\d@Y=\z@
3861 %   \d@X=\R@c \d@Y=\D@c \advance\d@X-\X@p \advance\d@Y-\Y@p
3862 %  \fi\fi
3863 % \fi\fi
3864 \setupDirection@ii
3865 \splinetrace@{dir:(\the\d@X,\the\d@Y),\the\Direction; depth:\the\splinedepth@}%

3866 }

3868 \xydef@\cubiccoarsedir@{%
3869 \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p \setupDirection@ii
3870 \global\dimen5=\d@X \global\dimen7=\d@Y
3871 \splinetrace@{dir:(\the\d@X,\the\d@Y),\the\Direction; depth:\the\splinedepth@}%

3872 }

3874 \xydef@\setcubicknotdir@{%
3875 \ifdim\zz@\splineval@ \DN@{\setcubiczerodir@}%
3876 \else \DN@{\cubicfinedir@}\fi \next@ }
3878 \xydef@\setcubiczerodir@{%
3879 \d@X=\L@c \advance\d@X-\X@p \d@Y=\U@c \advance\d@Y-\Y@p
3880 \ifdim\zz@\d@X \ifdim\zz@\d@Y
3881 \d@X=\R@c \advance\d@X-\X@p \d@Y=\D@c \advance\d@Y-\Y@p
3882 \ifdim\zz@\d@X \ifdim\zz@\d@Y
3883  \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p
3884 \fi\fi \fi\fi \setupDirection@ii }

We need a way to access the information in \splineparams.

3890 \xydef@\getcubicparams@#1,#2,#3,#4,#5,#6,#7,#8,#9,{%
3891 \splinelength@=#1\relax\X@p=#2\relax\Y@p=#3\relax\L@c=#4\relax
3892 \U@c=#5\relax\R@c=#6\relax\D@c=#7\relax\X@c=#8\relax\Y@c=#9\relax

3893 }%

3894 \xydef@\cubicinfo@{%
3895 \expandafter\removePT@\the\X@p\space
3896 \expandafter\removePT@\the\Y@p\space
3897 \expandafter\removePT@\the\L@c\space
3898 \expandafter\removePT@\the\U@c\space
3899 \expandafter\removePT@\the\R@c\space
3900 \expandafter\removePT@\the\D@c\space
3901 \expandafter\removePT@\the\X@c\space
3902 \expandafter\removePT@\the\Y@c\space
3903 \expandafter\removePT@\the\dimen5\space\space
3904 \expandafter\removePT@\the\dimen7\space

3905 }%

3906 \xydef@\cubicreverse@{\readsplineparams@
3907 \expandafter\edef\xysplineparams@{\the\splinelength@,%
3908 \the\X@c,\the\Y@c,\the\R@c,\the\D@c,\the\L@c,\the\U@c,\the\X@p,\the\Y@p,}}%
3909 \xydef@\cubicreverse@@{%
3910 \splinereverse@@@
3911 \dimen@ii=\L@c \L@c=\R@c \R@c=\dimen@ii
3912 \dimen@ii=\U@c \U@c=\D@c \D@c=\dimen@ii }

Start the picture by (1) setting a box, as usual. (2) Initialize global variables; these must be global since they are used to store information which must be preserved outside the grouping which is vital to the recursive nature of the algorithm. (3) Move horizontally to the starting point at p. (4) Begin by handling the starting point; i.e. decide whether it is to be plotted or not.

3926 \xydef@\cubic@start@{\setboxz@h\bgroup %   %(1)
3927 \global\splinelength@=\z@ \global\dimen@i=\z@ \global\dimen3=\z@ %  %(2)
3928 \kern\X@p  %  %(3)
3929 {\cubicsetparams@ \X@c=\X@p \Y@c=\Y@p \R@c=\X@c \D@c=\Y@c
3930 \firstsplinepoint@ }\bgroup
3931 } %  %(4)
3933 \xydef@\cubicsetparams@{%
3934 \expandafter\expandafter\expandafter\getsplineparams@\xysplineparams@
3935 \global\dimen@i=\X@p \global\dimen3=\Y@p }
3939 \xydef@\cubiced@{%
3940 \expandafter\edef\xysplineparams@{\the\z@,\the\X@p,\the\Y@p
3941 ,\the\A@,\the\B@,\the\dimen3,\the\dimen5,\the\X@c,\the\Y@c,}%

3942 }%

B-splines

The cases of 3 and 4 control points have some special simplifying features.

3955 \xydef@\xybspline@iii{%
3956 \addtocrvpts@{\def\crvconnect@{\bsplineiiiconnect@}}%
3957 \def\crvconnect@{\bsplineiiiconnect@}\xybsplinemethods@
3958 \let\splinesegment@=\bsplinesegment@iii
3959 \begingroup\setcrvobjects@ \dobspline@ \savespline@ }
3960 \xydef@\bsplineiiiconnect@{\splineconnect@ \crvconnect@@
3961 \let\splinesegment@=\bsplinesegment@iii }%
3963 \xydef@\xybspline@iv{%
3964 \addtocrvpts@{\def\crvconnect@{\bsplineivconnect@}}%
3965 \def\crvconnect@{\bsplineivconnect@}\xybsplinemethods@
3966 \let\splinesegment@=\bsplinesegment@iv
3967 \begingroup\setcrvobjects@ \dobspline@ \savespline@ }
3968 \xydef@\bsplineivconnect@{\splineconnect@ \crvconnect@@
3969 \let\splinesegment@=\bsplinesegment@iv }%

Now for the general case of ≥ 5 control points.

3975 \xydef@\xybspline@{%
3976 \splinetrace@{B-spline with \numcontrolpts\space control points.}%
3977 \addtocrvpts@{\def\crvconnect@{\bsplineconnect@}}%
3978 \def\crvconnect@{\bsplineconnect@}\xybsplinemethods@
3979 \let\splinesegment@=\bsplinesegment@
3980 \begingroup\setcrvobjects@
3981 \dobspline@ \savespline@ }
3983 \xydef@\xybsplinemethods@{%
3984 \def\splinereverse@@{\cubicreverse@@}%
3985 \let\getsplineparams@=\getbsplineparams@
3986 \let\spline@start@=\cubic@start@

3987 \let\splinedecast@@=\cubicdecast@
3988 \let\splinerec@@=\cubicrec@
3989 %  \let\splined@@=\cubiced@@
3990 \let\splineIpt@@=\cubicIpt@
3991 \let\splineIadvance@@=\cubicIadvance@
3992 \let\splined@@=\bsplined@@
3993 \let\splineinfo@=\cubicinfo@
3994 \let\setsplinedir@=\setcubicdir@
3995 \let\setsplineknotdir@=\setcubicknotdir@
3996 \let\splinereverse@=\cubicreverse@
3997 \let\splineDadvance@@@=\cubicDadvance@@@
3998 \let\splinesetparams@=\cubicsetparams@
3999 \global\let\lastbspline@=\lastbspline@@
4000 \global\let\middlebspline@=\middlebspline@@

4001 }

4002 \xydef@\bsplined@@{%
4003 % \global\splinedepth@=\p@
4004 \splinedepth@=\p@
4005 \global\splineval@=\z@
4006 \spline@start
4007 \global\dimen@i=\X@p \global\dimen3=\Y@p
4008 \splinerec@ \spline@end }
4012 \xydef@\bsplineconnect@{\splineconnect@ \crvconnect@@
4013 \let\splinesegment@=\bsplinesegment@ }%
4015 \xydef@\getbsplineparams@{\getcubicparams@}
4017 \xydef@\dobspline@{\xysplineparams@ \scanbspline@ \firstbspline@ }%

Registers \dimen3 and \dimen5 are used globally, since the standard local registers are already used.

4024 \xydef@\firstbspline@{%
4025 \enter@{\pfromthep@ \cfromthec@}\enter@{\cfromthec@}\bgroup
4026 \def\segmentnum@{1}\xycontrolpt@\z@ \X@p=\X@c \Y@p=\Y@c
4027 \splinetrace@{0: \the\X@p, \the\Y@p}%
4028 \xycontrolpt@\@ne \A@=\X@c \B@=\Y@c
4029 \splinetrace@{1: \the\X@c, \the\Y@c}%
4030 \xycontrolpt@\tw@
4031 \splinetrace@{2: \the\X@c, \the\Y@c}%
4032 \dimen@=\X@c \advance\dimen@\A@ \dimen@half
4033 \global\dimen3=\dimen@
4034 \dimen@=\Y@c \advance\dimen@\B@ \dimen@half
4035 \global\dimen5=\dimen@
4036 \xycontrolpt@{3}%
4037 \splinetrace@{3: \the\X@c, \the\Y@c}%
4038 \expandafter\count@\xycrvcnt@\relax %%%  very important to |\relax|
4039 \ifnum\count@=3\relax
4040 \advance\X@c-\A@ \dimen@nth4\X@c    % \divide\X@c by4
4041 \advance\X@c\dimen3\relax
4042 \advance\Y@c-\B@ \dimen@nth4\Y@c    % \divide\Y@c by4

4043 \advance\Y@c\dimen5\relax
4044 \enter@{\X@p=\the\X@c \Y@p=\the\Y@c \crv@cnt@=\@ne\relax
4045  \noexpand\lastbspline@ }%
4046 \else
4047 \advance\X@c 7\dimen3 \advance\X@c-2\A@
4048  \dimen@nth6\X@c  % \divide\X@c by6\relax
4049 \advance\Y@c 7\dimen5 \advance\Y@c-2\B@
4050  \dimen@nth6\Y@c  % \divide\Y@c by6\relax
4051 \enter@{\X@p=\the\X@c \Y@p=\the\Y@c \crv@cnt@=\@ne\relax
4052  \noexpand\middlebspline@ }%
4053 \fi \adjustmaxmin@ \czeroEdge@
4054 \bsplined@ \splineset@ \leave@ }
4056 \xydef@\lastbspline@@{\bgroup
4057 \advance\crv@cnt@\@ne \edef\segmentnum@{\the\crv@cnt@}%
4058 \splinetrace@{<: \the\X@p, \the\Y@p}%
4059 \advance\crv@cnt@\@ne \xycontrolpt@{\crv@cnt@}%
4060 \global\dimen3=\X@c \global\dimen5=\Y@c
4061 \splinetrace@{\the\crv@cnt@: \the\X@c, \the\Y@c}%
4062 \advance\crv@cnt@\m@ne \xycontrolpt@{\crv@cnt@}%
4063 \splinetrace@{\the\crv@cnt@: \the\X@c, \the\Y@c}%
4064  \A@=\X@c \advance\A@\dimen3 \halve@dimen\A@  % \divide\A@\tw@
4065  \B@=\Y@c \advance\B@\dimen5 \halve@dimen\B@  % \divide\B@\tw@
4066 \adjustmaxmin@ \leave@  \relax \cv@end % <---------------
4067 \splinetrace@{>: \the\X@c, \the\Y@c}%
4068 \bsplined@ \splineset@ \leave@ }%
4069 \xylet@\lastbspline@=\lastbspline@@
4071 \xydef@\middlebspline@@{%
4072 \advance\crv@cnt@\@ne \edef\segmentnum@{\the\crv@cnt@}%
4073 \splinetrace@{<: \the\X@p, \the\Y@p}%
4074 \bgroup
4075 \xycontrolpt@{\crv@cnt@}\A@=2\X@c \B@=2\Y@c
4076 \splinetrace@{\the\crv@cnt@: \the\X@c, \the\Y@c}%
4077 \advance\crv@cnt@\@ne \xycontrolpt@{\crv@cnt@}%
4078 \splinetrace@{\the\crv@cnt@: \the\X@c, \the\Y@c}%
4079  \advance\A@\X@c \dimen@nth3\A@   % \divide\A@ by3
4080  \advance\B@\Y@c \dimen@nth3\B@   % \divide\B@ by3\relax
4081  \advance\X@c\A@ \halve@dimen\X@c % \divide\X@c\tw@
4082  \advance\Y@c\B@ \halve@dimen\Y@c % \divide\Y@c\tw@
4083  \global\dimen3=\X@c \global\dimen5=\Y@c
4084 \advance\crv@cnt@\@ne \xycontrolpt@{\crv@cnt@}%
4085 \splinetrace@{\the\crv@cnt@: \the\X@c, \the\Y@c}%
4086 \expandafter\count@\xycrvcnt@\relax
4087 \ifnum\crv@cnt@<\count@\relax
4088 \advance\X@c 7\dimen3\advance\X@c-2\A@
4089  \dimen@nth6\X@c  %  \divide\X@c by6\relax
4090 \advance\Y@c 7\dimen5\advance\Y@c-2\B@
4091  \dimen@nth6\Y@c  %  \divide\Y@c by6\relax
4092 \enter@{\X@p=\the\X@c \Y@p=\the\Y@c \crv@cnt@=\segmentnum@\relax
4093  \noexpand\middlebspline@}%

4094 \else
4095 \advance\X@c-\A@ \dimen@nth4\X@c  % \divide\X@c by4
4096 \advance\X@c \dimen3\relax
4097 \advance\Y@c-\B@ \dimen@nth4\Y@c  % \divide\Y@c by4
4098 \advance\Y@c \dimen5\relax
4099 \enter@{\X@p=\the\X@c \Y@p=\the\Y@c \noexpand\lastbspline@}%
4100 \fi \adjustmaxmin@
4101 \bsplined@ \splineset@ \leave@ }
4102 \xylet@\middlebspline@=\middlebspline@@
4106 \xydef@\scanbspline@{\splined@@@}
4110 \xydef@\bsplined@{\cubiced@
4111 \expandafter\ifx\xysplineedges@\relax\relax\DN@{}%
4112 \else\DN@{\adjustbsplineedges@}\fi \next@ }
4114 \xydef@\adjust@forsegments@{\getcrvsegsnum@
4115 \ifnum\count@>\@ne
4116 \splinetrace@{adjust for \the\count@\space segments:
4117 \the\dimen5, \the\dimen7}%
4118 \multiply\dimen5 by \count@\relax \dimen@=\segmentnum@\p@
4119 \ifnum\dimen5>\dimen@ \relax\dimen5=\p@
4120 \else \advance\dimen5-\segmentnum@\p@ \advance\dimen5 by\p@ \fi
4121 \ifnum\dimen5<\z@ \relax\dimen5=\z@\relax\fi
4122 \multiply\dimen7 by \count@\relax
4123 \dimen@=\segmentnum@\p@ %\advance\dimen@-\segmentnum@\p@
4124 \ifnum\dimen7<\dimen@ \advance\dimen@-\p@
4125 \ifnum\dimen7>\dimen@ \advance\dimen7-\dimen@
4126 \else \dimen7=\z@ \fi
4127 \else \dimen7=\p@ \fi
4128 \splinetrace@{adjusted for \the\count@\space segments:
4129 \the\dimen5, \the\dimen7}%
4130 \fi}
4132 \xydef@\adjustbsplineedges@{\bgroup % dimen5 and dimen7 are NOT global here
4133 \splinetrace@{** adjusting edges **}%
4134 \readsplineparams@ \adjust@forsegments@
4135 %   \count@@=\dimen7\divide\count@@\p@
4136 %    \advance\dimen7-\count@@\p@ \advance\count@@\@ne
4137 %   \count@=\dimen5\divide\count@\p@
4138 %    \advance\dimen5-\count@\p@ \advance\count@\@ne
4139 \splinetrace@{params:\xysplineparams@}%
4140 \splinetrace@{segment \segmentnum@:<\the\dimen5,\the\dimen7>:\xysplineedges@}%
4141 %   \expandafter\ifnum\segmentnum@=\count@
4142 %   \else
4143 %    \expandafter\ifnum\segmentnum@<\count@\dimen5=\p@
4144 %    \else\dimen5=\z@ \fi\fi
4145 %   \expandafter\ifnum\segmentnum@=\count@@
4146  \multiply\dimen7by\m@ne \advance\dimen7by\p@
4147 %   \else
4148 %    \expandafter\ifnum\segmentnum@>\count@@\dimen5=\p@\dimen7=\p@

4149 %    \else\dimen7=\z@ \fi\fi
4150 \expandafter\edef\xysplineedges@{%
4151 \noexpand\z@;\the\dimen5,\noexpand\z@;\the\dimen7,}%
4152 \edef\tmp@{\egroup
4153 \noexpand\def\expandafter\noexpand\xysplineedges@{\xysplineedges@}}%
4154 \tmp@ }

These macros select the correct Bézier control points for each segment of the spline. This is needed for finding places on the constructed curves.

In general there are 5 types of segment: first, second, middle, penultimate, final. The conversion from B-spline to Bézier is slightly different for each type. For middle segments the Bézier control points are determined in the following way:

X_{B_{i}}^{(1)} = \frac{1}{3} (2X^{(i)} + X^{(i+1)})
X_{B_{i}}^{(2)} = \frac{1}{3} (X^{(i)} + 2X^{(i+1)})
X_{B_{i}}^{(0)} = \frac{1}{6} (X^{(i−1)} + 4X^{(i)} + X^{(i+1)})
= \frac{1}{6} (X^{(i−1)} + 7X_{B_{i}}^{(1)} − 2X_{B_{i}}^{(2)})
X_{B_{i}}^{(3)} = \frac{1}{6} (X^{(i)} + 4X^{(i+1)} + X^{(i+2)})
= \frac{1}{6} (X^{(i+2)} + 7X_{B_{i}}^{(2)} − 2X_{B_{i}}^{(1)})

4178 \xydef@\bsegment@@ii@iii{%
4179 \xycontrolpt@{\count@@}\global\dimen3=\X@c \global\dimen5=\Y@c
4180 \splinetrace@{\the\count@@: \the\X@c, \the\Y@c}%
4181 \advance\count@@\@ne \xycontrolpt@{\count@@}\A@=\X@c \B@=\Y@c
4182 \advance\A@ by2\dimen3 \dimen@nth3\A@  % \divide\A@ by3\relax
4183 \advance\B@ by2\dimen5 \dimen@nth3\B@  % \divide\B@ by3\relax
4184 \dimen@=\dimen3 \advance\dimen@ by2\X@c
4185 \dimen@nth3\dimen@  %  \divide\dimen@\thr@@
4186 \global\dimen3=\dimen@
4187 \dimen@=\dimen5 \advance\dimen@ by2\Y@c
4188 \dimen@nth3\dimen@  %  \divide\dimen@\thr@@
4189 \global\dimen5=\dimen@
4190 \splinetrace@{<: \the\dimen3, \the\dimen5}%
4191 \splinetrace@{>: \the\A@, \the\B@}%
4192 \advance\count@@\m@ne }
4194 \xydef@\bsegment@@i{\bgroup
4195 \advance\count@@\m@ne \xycontrolpt@{\count@@}%
4196 \splinetrace@{\the\count@@: \the\X@c, \the\Y@c}%
4197 \edef\tmp@{\egroup \X@p=\the\X@c \Y@p=\the\Y@c}\tmp@
4198 \advance\X@p-2\dimen3\advance\X@p by7\A@
4199 \dimen@nth6\X@p  %  \divide\X@p by6\relax
4200 \advance\Y@p-2\dimen5\advance\Y@p by7\B@
4201 \dimen@nth6\Y@p  %  \divide\Y@p by6\relax

4204 \xydef@\bsegment@@iv{%
4205 \advance\count@@\tw@ \xycontrolpt@{\count@@}%
4206 \splinetrace@{\the\count@@: \the\X@c, \the\Y@c}%
4207 \advance\X@c by7\dimen3\advance\X@c-2\A@
4208 \dimen@nth6\X@c  %  \divide\X@c by6\relax
4209 \advance\Y@c by7\dimen5\advance\Y@c-2\B@
4210 \dimen@nth6\Y@c  %  \divide\Y@c by6\relax
4211 \splinetrace@{>>: \the\X@c, \the\Y@c }%

4212 }

For the second segment the expression for X_{B_{2}}^{(0)} is different. Similarly the expression for X_{B_{n−1}}^{(3)} is altered for the penultimate segment.

X_{B_{2}}^{(0)} = \frac{1}{4} (X^{(1)} + 4X_{B_{2}}^{(1)} − X_{B_{2}}^{(2)})
X_{B_{n−1}}^{(3)} = \frac{1}{4} (X^{(3)} + 4X_{B_{n−1}}^{(2)} − X_{B_{n−1}}^{(1)})

4227 \xydef@\bsegment@@ii@i{\bgroup
4228 \advance\count@@\m@ne \xycontrolpt@{\count@@}%
4229 \splinetrace@{\the\count@@: \the\X@c, \the\Y@c}%
4230 \edef\tmp@{\egroup \X@p=\the\X@c \Y@p=\the\Y@c}\tmp@
4231 \advance\X@p-\dimen3\advance\X@p by4\A@
4232 \dimen@nth4\X@p  %  \divide\X@p by4\relax
4233 \advance\Y@p-\dimen5\advance\Y@p by4\B@
4234 \dimen@nth4\Y@p  %  \divide\Y@p by4\relax
4235 \splinetrace@{<<: \the\X@p, \the\Y@p}%

4236 }

4237 \xydef@\bsegment@@y@iv{%
4238 \advance\count@@\tw@ \xycontrolpt@{\count@@}%
4239 \splinetrace@{\the\count@@: \the\X@c, \the\Y@c}%
4240 \advance\X@c by4\dimen3\advance\X@c-\A@
4241 \dimen@nth4\X@c  %  \divide\X@c by4\relax
4242 \advance\Y@c by4\dimen5\advance\Y@c-\B@
4243 \dimen@nth4\Y@c  %  \divide\Y@c by4\relax

4244 }

For the first segment the first three Bézier control points are always determined in the same way:

X_{B_{1}}^{(0)} = X^{(0)} X_{B_{1}}^{(1)} = X^{(1)} X_{B_{1}}^{(2)} = \frac{1}{2}(X_{B_{1}}^{(1)} + X^{(2)})
3+ segments  X_{B_{1}}^{(3)} = \frac{1}{6}(7X_{B_{1}}^{(2)} − 2X_{B_{1}}^{(1)} + X^{(3)})
2 segments  X_{B_{1}}^{(3)} = \frac{1}{4}(4X_{B_{1}}^{(2)} − X_{B_{1}}^{(1)} + X^{(3)})

4260 \xydef@\bsegment@i{%
4261 \xycontrolpt@\z@ \X@p=\the\X@c \Y@p=\the\Y@c
4262 % \ifx\cv@start\relax
4263 %  \bgroup\csname cv@0\endcsname

4264 %  \edef\tmp@{\egroup \X@p=\the\X@c \Y@p=\the\Y@c}\tmp@
4265 % \else\xycontrolpt@\z@ \X@p=\the\X@c \Y@p=\the\Y@c\fi
4266 \splinetrace@{0: \the\X@p \the\Y@p}%
4267 \xycontrolpt@\@ne
4268 \splinetrace@{1: \the\X@c, \the\Y@c}\A@=\X@c \B@=\Y@c
4269 \xycontrolpt@\tw@
4270 \dimen@=\X@c \advance\dimen@\A@ \dimen@half
4271 \global\dimen3=\dimen@
4272 \splinetrace@{2: \the\X@c, \the\Y@c}%
4273 \dimen@=\Y@c \advance\dimen@\B@ \dimen@half
4274 \global\dimen5=\dimen@ }
4276 \xydef@\bsegment@i@iv{%
4277 \xycontrolpt@{3}%
4278 \splinetrace@{3: \the\X@c, \the\Y@c}%
4279 \advance\X@c by7\dimen3\advance\X@c-2\A@
4280  \dimen@nth6\X@c  %  \divide\X@c by6\relax
4281 \advance\Y@c by7\dimen5\advance\Y@c-2\B@
4282  \dimen@nth6\Y@c  %  \divide\Y@c by6\relax

4283 }

The last segment is determined symmetrically from the final four control points:

X_{B_{n}}^{(3)} = X^{(n+2)} X_{B_{n}}^{(2)} = X^{(n+1)} X_{B_{n}}^{(1)} = \frac{1}{2}(X_{B_{n}}^{(2)} + X^{(n)})
3+ segments  X_{B_{n}}^{(0)} = \frac{1}{6}(X^{(n−1)} − 2X_{B_{n}}^{(2)} + 7X_{B_{n}}^{(1)})
2 segments  X_{B_{n}}^{(0)} = \frac{1}{4}(X^{(1)} − X_{B_{n}}^{(2)} + 4X_{B_{n}}^{(1)})

4298 \xydef@\bsegment@z{%
4299 \expandafter\count@@\xycrvptsnum@ \advance\count@@\@ne
4300 \xycontrolpt@{\the\count@@}\relax
4301 \splinetrace@{\the\count@@: \the\X@c, \the\Y@c}%
4302 \advance\count@@\m@ne
4303 \bgroup
4304 \xycontrolpt@{\the\count@@}%
4305 \splinetrace@{\the\count@@: \the\X@c, \the\Y@c}%
4306 \global\dimen3=\X@c \global\dimen5=\Y@c
4307 \advance\count@@\m@ne \xycontrolpt@{\the\count@@}%
4308 \splinetrace@{\the\count@@: \the\X@c, \the\Y@c}%
4309 \A@=\X@c \advance\A@\dimen3 \halve@dimen\A@   %  \divide\A@\tw@
4310 \B@=\Y@c \advance\B@\dimen5 \halve@dimen\B@   %  \divide\B@\tw@
4311 \edef\tmp@{\egroup \A@=\the\A@ \B@=\the\B@ \count@@=\the\count@@}%
4312 \tmp@ }
4314 \xydef@\bsegment@z@i{%
4315 \expandafter\count@@\xycrvptsnum@\relax\advance\count@@-\tw@
4316 \bgroup
4317 \xycontrolpt@{\count@@}\X@p=\the\X@c \Y@p=\the\Y@c
4318 \splinetrace@{\the\count@@: \the\X@c, \the\Y@c}%
4319 \advance\X@p by7\A@ \advance\X@p-2\dimen3 \dimen@nth6\X@p

4320 \advance\Y@p by7\B@ \advance\Y@p-2\dimen5 \dimen@nth6\Y@p
4321 \edef\tmp@{\egroup \X@p=\the\X@p \Y@p=\the\Y@p}%
4322 \tmp@ }

This is the switching-yard.

4328 \xydef@\bsplinesegment@#1{\xybsplinemethods@
4329 \count@@=#1\relax
4330 \ifnum\count@@=\@ne       %  first segment
4331 \bsegment@i \bsegment@i@iv
4332 \else\ifnum\count@@=\tw@  %  second segment
4333 \bsegment@@ii@iii \bsegment@@ii@i \bsegment@@iv
4334 % \else\expandafter\count@\xycrvcnt@\advance\count@\m@ne
4335 \else\expandafter\count@\xycrvptsnum@\advance\count@\m@ne
4336 \ifnum\count@@=\count@    %  last segment
4337 \bsegment@z \bsegment@z@i
4338 \else\advance\count@\m@ne
4339 \ifnum\count@@=\count@   %  penult. segment
4340 \bsegment@@ii@iii \bsegment@@i \bsegment@@y@iv
4341 \else                    %  middle segments
4342 \bsegment@@ii@iii \bsegment@@i \bsegment@@iv
4343 \fi\fi\fi\fi
4344 \expandafter\def\expandafter\segmentnum@\expandafter{\number#1}%
4345 \bsplined@ }

Here are the differences for 3 control points.

4351 \xydef@\bsplinesegment@iii#1{\xybsplinemethods@
4352 \splinetrace@{2 segments; \number#1}%
4353 \count@@=#1\relax
4354 \ifnum\count@@=\@ne \bsegment@i
4355 \xycontrolpt@{3}%
4356 \splinetrace@{3: \the\X@c, \the\Y@c}%
4357 \advance\X@c 4\dimen3\advance\X@c-\A@
4358  \dimen@nth4\X@c   %  \divide\X@c by4\relax
4359 \advance\Y@c 4\dimen5\advance\Y@c-\B@
4360  \dimen@nth4\Y@c   %  \divide\Y@c by4\relax
4361 \else\ifnum\count@@=\tw@ \bsegment@z
4362 \bgroup\xycontrolpt@{\@ne}%
4363 \splinetrace@{1: \the\X@c, \the\Y@c}%
4364 \edef\tmp@{\egroup \X@p=\the\X@c \Y@p=\the\Y@c}\tmp@
4365 \advance\X@p 4\A@ \advance\X@p-\dimen3 %
4366  \dimen@nth4\X@p   %  \divide\X@p by4\relax
4367 \advance\Y@p 4\B@ \advance\Y@p-\dimen5 %
4368  \dimen@nth4\Y@p   %  \divide\Y@p by4\relax
4369 \fi\fi
4370 \expandafter\def\expandafter\segmentnum@\expandafter{\number#1}%
4371 \bsplined@ }

Here are the differences for 4 control points.

4377 \xydef@\bsplinesegment@iv#1{\xybsplinemethods@
4378 \splinetrace@{3 segments; \number#1}%

4379 \count@@=#1\relax
4380 \ifnum\count@@=\@ne \bsegment@i \bsegment@i@iv
4381 \else\ifnum\count@@=\tw@
4382 \bsegment@@ii@iii \bsegment@@ii@i \bsegment@@y@iv
4383 \else\ifnum\count@@=3\relax
4384 \bsegment@z \bsegment@z@i %\xycontrolpt@{5}%
4385 \fi\fi\fi
4386 \expandafter\def\expandafter\segmentnum@\expandafter{\number#1}%
4387 \bsplined@ }

2.1.2 Circles and Ellipses

Here we describe the means to a specify circles of arbitrary radius, drawn with arbitrary line styles. When large-sized objects are used they are regularly spaced around the circle. Similarly ellipses may be specified, but only those having major/minor axes aligned in the standard directions; spacing of objects is no longer regular, but is bunched toward the narrower ends.

Such a circle or ellipse is specified using…

\xycircle⟨vector⟩{⟨style⟩}

where the components of the ⟨vector⟩ determine the lengths of the axis for the ellipse; thus giving a circle when equal. The ⟨style⟩ can be any ⟨conn⟩, as in 3.2 that works with curved arrows—many do. Alternatively ⟨style⟩ can be any ⟨object⟩, which will be placed equally-spaced about the circle at a separation to snugly fit the ⟨object⟩s. If ⟨empty⟩ then a solid circle or ellipse is drawn.

To Do: Recognize special ⟨style⟩s; e.g. . for dotted with \zerodot, = for a doubled circle — alter the radius, draw two circles; : for double dotted (perhaps use \doubled@, \tripled@); > and < for chevrons; any others?

To use any of these special symbols as the ⟨object⟩ for ⟨style⟩ then enclose it within extra braces,

e.g. \xycircle<20pt>{{>}}.

The curves are not truly circular or elliptical, but are approximations given by cubic Bézier segments. Hence the xycurve feature must be loaded.

4433 \message{circles,}

The circles are constructed from four Bézier cubic curves, one for each quadrant of the circle or circle. To do this it is sufficient to establish the control points for each cubic segment. This is straightforward, using the following “magic number”, given a square basis such that the desired circle is the unit circle, or rectangular basis for which the “unit circle” is the desired circle.

4444 \xydef@\Circmagic@@{0.5517847}
4445 \xylet@\Circmagic=\Circmagic@@
4446 \xydef@\twoPi@{6.2831852}
4447 \xydef@\fullPi@{3.1415926}
4448 \xydef@\halfPi@{1.5707963}

This is the magic number, exactly given by \frac{1}{12}(\sqrt{385} − 13), that helps construct the Bézier cubic curve that best approximates a quadrant of a circle. It does so with remarkable accuracy, differing by at most .5% of the radius at any angle; the average deviation along the whole quadrant being less than .13%. The basic ⟨object⟩ defined here is \circle.

4461 \xynew@{dimen}\L@
4463 \xydef@\xycircle#1#{\hbox\bgroup\afterVECTORorEMPTY{%
4464 \xy@@{\R@=\X@c \L@=\Y@c}\xycircle@}{\xy@@{\R@=\R@c \L@=\L@c}\xycircle@}#1@}

4466 \xydef@\xycircle@#1@#2{%
4467 \DN@{#1}\ifx\next@\empty\def\onlyQuad@{}\else \count@=#1\relax
4468 \ifnum\count@<5 \advance\count@-3\relax
4469 \ifnum\count@<\z@ \advance\count@ 4\relax\fi \edef\onlyQuad@{\the\count@}%
4470 \else\xyerror@{illegal circle <radius>: must be <vector> or <empty>}{}\fi
4471 \fi \xy@@{\def\circleSTYLE@{#2}}\def\circleSTYLE@{#2}\xycircle@i}
4473 \xydef@\xycircle@i{\hbox{\vbox{\vskip\L@
4474 \hbox to2\R@{\hfill \buildcircle@ \hfill}\vskip\L@ }}%
4475 \L@c=\R@ \R@c=\R@ \D@c=\L@ \U@c=\L@ \def\Leftness@{.5}\def\Upness@{.5}%
4476 \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@\relax}\Edge@c={\circleEdge}%
4477 \OBJECT@x}
4479 \xydef@\adjustMinMaxcirc@#1#2{%
4480 \dimen@=\X@c \advance\dimen@#1\relax\ifdim\dimen@>\X@max \X@max=\dimen@\fi
4481 \dimen@=\X@c \advance\dimen@-#1\relax\ifdim\dimen@<\X@min \X@min=\dimen@\fi
4482 \dimen@=\Y@c \advance\dimen@#2\relax\ifdim\dimen@>\Y@max \Y@max=\dimen@\fi
4483 \dimen@=\Y@c \advance\dimen@-#2\relax\ifdim\dimen@<\Y@min \Y@min=\dimen@\fi

4484 }

4486 %\xydef@\buildcircle@{\save@
4487 %% \cubicCircleControls@@
4488 % \ifx\circleSTYLE@\empty\DN@{\solidcircle@{}}%
4489 % \else \expandafter\DN@\expandafter{\addDASH@{}}\relax
4490 %  \ifx\next@\circleSTYLE@ \DN@{%
4491 %   \expandafter\addDASH@\expandafter{\expandafter{\addDASH@{}}}}%
4492 % \else\DN@{\circledobjects@}\fi\fi\next@ \leave@}
4496 \xydef@\cubicCircleControls@@{\X@origin=\z@ \Y@origin=\z@
4497 \X@xbase=\R@ \Y@xbase=\z@ \X@ybase=\z@ \Y@ybase=\L@
4498 \vfromcartesian@@1,0@\czeroEdge@\idfromc@{0@c}%
4499 \vfromcartesian@@0,1@\czeroEdge@\idfromc@{1@c}%
4500 \vfromcartesian@@-1,0@\czeroEdge@\idfromc@{2@c}%
4501 \vfromcartesian@@0,-1@\czeroEdge@\idfromc@{3@c}%
4502 \vfromcartesian@@1,\Circmagic@@ @\czeroEdge@\idfromc@{1@m}%
4503 \vfromcartesian@@\Circmagic@@,1@\czeroEdge@\idfromc@{2@m}%
4504 \vfromcartesian@@-\Circmagic@@,1@\czeroEdge@\idfromc@{3@m}%
4505 \vfromcartesian@@-1,\Circmagic@@ @\czeroEdge@\idfromc@{4@m}%
4506 \vfromcartesian@@-1,-\Circmagic@@ @\czeroEdge@\idfromc@{5@m}%
4507 \vfromcartesian@@-\Circmagic@@,-1@\czeroEdge@\idfromc@{6@m}%
4508 \vfromcartesian@@\Circmagic@@,-1@\czeroEdge@\idfromc@{7@m}%
4509 \vfromcartesian@@1,-\Circmagic@@ @\czeroEdge@\idfromc@{8@m}%

4510 }

4512 \xydef@\doCircleQuadrant@@#1#2{\save@ \ifcase#2\relax
4513 \doCircleQuadrant@@@{0@c}{1@m}{2@m}{1@c}{#1}\or
4514 \doCircleQuadrant@@@{1@c}{3@m}{4@m}{2@c}{#1}\or
4515 \doCircleQuadrant@@@{2@c}{5@m}{6@m}{3@c}{#1}\or
4516 \doCircleQuadrant@@@{3@c}{7@m}{8@m}{0@c}{#1}\or
4517 \doCircleQuadrant@@@{0@c}{1@m}{2@m}{1@c}{#1}\or
4518 \doCircleQuadrant@@@{1@c}{3@m}{4@m}{2@c}{#1}\or
4519 \doCircleQuadrant@@@{2@c}{5@m}{6@m}{3@c}{#1}\or

4520 \doCircleQuadrant@@@{3@c}{7@m}{8@m}{0@c}{#1}\fi \leave@ }
4522 \xydef@\doCircleQuadrant@@@#1#2#3#4#5{%
4523 \cfromid@{#1}\pfromc@\senter@
4524 \cfromid@{#2}\spushc@\cfromid@{#3}\spushc@\cfromid@{#4}%
4525 \let\bstartPLACE@=\empty \connect@\crvs{#5}\relax\sinit@\sleave@
4526 \resetbreaks@}

The hook \dosolidcircle@@ is provided so that back-ends may provide an alternative method to draw the circles/ellipses. Note that the token following \solidcircle@ will be a group representing the ⟨style⟩ to be used.

4535 \xydef@\dosolidcircle@#1{%
4536 \cubicCircleControls@@
4537 \doCircleQuadrant@@{#1}1 \relax\Clast@@
4538 \doCircleQuadrant@@{#1}2 \relax\Clast@@
4539 \doCircleQuadrant@@{#1}3 \relax\Clast@@
4540 \doCircleQuadrant@@{#1}4 \relax\Clast@@}%
4542 \xydef@\solidcircle@{\dosolidcircle@@}
4543 \xylet@\dosolidcircle@@=\dosolidcircle@

This places objects equally spaced around a circle, according to angular position.

Bug: objects are not equally spaced around ellipses constructed this way. To get regular spacing around ellipses, in terms or arc-length say, is much more difficult, both theoretically and practically.

To Do: the size of the resulting ⟨object⟩ does not take into account the size of the ⟨object⟩ dropped around the circle.

4557 \xydef@\circledobjects@{\cubicCircleControls@@
4558 \setboxz@h{\expandafter\object\circleSTYLE@{}}%
4559 \ifdim\L@>\R@ \dimen@ii=\ht\z@ \advance\dimen@ii \dp\z@
4560 \ifdim\zz@\dimen@ii \dimen@ii=\wdz@\fi
4561 \else \dimen@ii=\wdz@
4562 \ifdim\zz@\dimen@ii \dimen@ii=\ht\z@ \advance\dimen@ii \dp\z@\fi
4563 \fi \ifdim\zz@\dimen@ii \dimen@ii=2\jot\fi
4564 \expandafter\dimen@\ifdim\L@>\R@ \twoPi@\L@\else \twoPi@\R@\fi
4565 \advance\dimen@.5\dimen@ii
4566 \count@@=\dimen@ \count@=\dimen@ii \divide\count@@\count@
4567 \edef\numobjects{\the\count@@}\dimen@=4\p@
4568 \dimen@nth\numobjects\dimen@   %  \divide\dimen@\numobjects\relax
4569 \edef\circleseparation@{\expandafter\removePT@\the\dimen@}%
4570 \edef\circleplace@{-\circleseparation@}\placeQuadrants@}%
4572 \xydef@\placeQuadrants@{\DN@{\placeAllQuadrants@}%
4573 \ifx\onlyQuad@\undefined\else\ifx\onlyQuad@\empty\else
4574 \DN@{\expandafter\placeCircQuadrant@\expandafter{\onlyQuad@}}%
4575 \fi\fi \next@ }%
4576 %\def\placeQuadrants@{\placeAllQuadrants@}
4578 \xydef@\placeAllQuadrants@{%
4579 \placeCircQuadrant@{1}%
4580 \advance\dimen@-\p@\advance\dimen@-\circleseparation@\p@
4581 \edef\circleplace@{\expandafter\removePT@\the\dimen@}%
4582 \placeCircQuadrant@{2}%
4583 \advance\dimen@-\p@\advance\dimen@-\circleseparation@\p@

4584 \edef\circleplace@{\expandafter\removePT@\the\dimen@}%
4585 \placeCircQuadrant@{3}%
4586 \advance\dimen@-\p@\advance\dimen@-\circleseparation@\p@
4587 \edef\circleplace@{\expandafter\removePT@\the\dimen@}%
4588 \placeCircQuadrant@{4}}
4590 \xydef@\placeCircQuadrant@#1{%
4591 \let\bstartPLACE@=\relax \doCircleQuadrant@@{}#1%
4592 \loop@
4593 \expandafter\dimen@\circleplace@\p@
4594 \advance\dimen@\circleseparation@\p@
4595 \edef\circleplace@{\expandafter\removePT@\the\dimen@}%
4596 \ifdim\dimen@<\p@ \placeCircObject@
4597 \repeat@ }
4599 \xydef@\placeCircObject@{\begingroup
4600 \crvconnect@@ \Creset@@ \Invisible@false
4601 \expandafter\splinealong@\expandafter{\circleplace@}%
4602 \expandafter\drop\circleSTYLE@{}\endgroup }
4604 \xydef@\buildcircle@{\save@
4605 % \cubicCircleControls@@
4606 \DNii@{\circledobjects@}%
4607 \ifx\circleSTYLE@\empty\DNii@{\solidcircle@{}}%
4608 \else \expandafter\DN@\expandafter{\addDASH@{}}\relax
4609 \ifx\next@\circleSTYLE@ \DNii@{\solidcircle@{}}%
4610 \else \expandafter\DN@\expandafter{\addEQ@{}}%
4611 \ifx\next@\circleSTYLE@
4612 \expandafter\circletemplate@\expandafter{\addEQ@{}}{}%
4613 \else \expandafter\DN@\expandafter{\addDASH@ 2}%
4614 \ifx\next@\circleSTYLE@ \DNii@{\doublecircle@{}}%
4615 \else \expandafter\DN@\expandafter{\addDASH@ 3}%
4616 \ifx\next@\circleSTYLE@ \DNii@{\triplecircle@{}}%
4617 \else \expandafter\expandafter\expandafter\DN@\expandafter\expandafter
4618 \expandafter{\expandafter\addDASH@\addDASH@{}}%
4619 \ifx\next@\circleSTYLE@ \DNii@{\dashedcircle@{}}%
4620 \else \expandafter\expandafter\expandafter\DN@\expandafter\expandafter
4621 \expandafter{\expandafter\addEQ@\addEQ@{}}%
4622 \ifx\next@\circleSTYLE@ \expandafter\expandafter\expandafter
4623 \circletemplate@\expandafter\expandafter\expandafter{%
4624  \expandafter\addEQ@\addEQ@{}}2%
4625 \else \expandafter\expandafter\expandafter\DN@\expandafter\expandafter
4626 \expandafter{\expandafter\addEQ@\addEQ@2}%
4627 \ifx\next@\circleSTYLE@ \expandafter\expandafter\expandafter
4628 \circletemplate@\expandafter\expandafter\expandafter{%
4629  \expandafter\addEQ@\addEQ@{}}2%
4630 \else \expandafter\expandafter\expandafter\DN@\expandafter\expandafter
4631 \expandafter{\expandafter\addEQ@\addEQ@3}%
4632 \ifx\next@\circleSTYLE@ \expandafter\expandafter\expandafter
4633 \circletemplate@\expandafter\expandafter\expandafter{%
4634  \expandafter\addEQ@\addEQ@{}}3%

4635 \else \expandafter\DN@\expandafter{\addDOT@{}}\relax
4636 \ifx\next@\circleSTYLE@ \DNii@{\dottedcircle@{}}%
4637 \else \expandafter\DN@\expandafter{\addDOT@2}\relax
4638 \ifx\next@\circleSTYLE@ \DNii@{\dbldottedcircle@{}}%
4639 \else \expandafter\DN@\expandafter{\addDOT@3}\relax
4640 \ifx\next@\circleSTYLE@ \DNii@{\trpldottedcircle@{}}%
4641 \else \DN@{:}\relax
4642 \ifx\next@\circleSTYLE@ \DNii@{\dbldottedcircle@{}}%
4643 % \else\DN@{\circledobjects@}%
4644 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \nextii@ \leave@}
4646 \xydef@\circletemplate@#1#2{\def\circleSTYLE@{\dir#2{#1}}}
4647 \xydef@\doublecircle@#1{%
4648 \advance\R@-\p@ \advance\L@-\p@ \solidcircle@{}%
4649 \advance\R@ 2\p@ \advance\L@ 2\p@ \solidcircle@{}}
4650 \xydef@\triplecircle@#1{%
4651 \advance\R@-2\p@ \advance\L@-2\p@ \solidcircle@{}%
4652 \advance\R@ 2\p@ \advance\L@ 2\p@ \solidcircle@{}%
4653 \advance\R@ 2\p@ \advance\L@ 2\p@ \solidcircle@{}}
4655 %\xydef@\dashedcircle@#1{\expandafter\expandafter\expandafter
4656 %   \circletemplate@\expandafter\expandafter\expandafter{%
4657 %    \expandafter\addDASH@\addDASH@{}}{}\circledobjects@ }%
4659 \xydef@\dottedcircle@#1{%
4660 \expandafter\def\expandafter\circleSTYLE@\expandafter{%
4661 %  \expandafter{\addDOT@{}}}%
4662 \zerodot@i}%
4663 \circledobjects@}
4665 \xydef@\dashedcircle@#1{%
4666 \expandafter\def\expandafter\circleSTYLE@\expandafter{\zerodash@i}%
4667 \circledobjects@}
4669 \xydef@\dbldottedcircle@#1{%
4670 \advance\R@-\p@ \advance\L@-\p@ \dottedcircle@{}%
4671 \advance\R@ 2\p@ \advance\L@ 2\p@ \dottedcircle@{}}
4672 \xydef@\trpldottedcircle@{%
4673 \advance\R@-2\p@ \advance\L@-2\p@ \dottedcircle@{}%
4674 \advance\R@ 2\p@ \advance\L@ 2\p@ \dottedcircle@{}%
4675 \advance\R@ 2\p@ \advance\L@ 2\p@ \dottedcircle@{}}
4677 {\xyuncatcodes \gdef\next{=<.75\jot>{\zerodot}}}
4678 \xylet@\zerodot@i=\next
4680 {\dimen0=2\xydashl@ \xyuncatcodes
4681 \expandafter\gdef\expandafter\next\expandafter{\expandafter
4682 =\expandafter<\the\dimen0 >_\dir{|}}}
4683 \xylet@\zerodash@i=\next

[figure: •; •; c; . . .................. . .]

\xy 0;/r5pc/:*\dir{*}
 ;p+(.5,-.5)*\dir{*}="c"
,**\dir{-},*+!UL{c},"c"
,*\xycircle(1,.4){++\dir{<}}
,*\xycircle(1,1){++\dir{>}}
,*\xycircle<15pt,10pt>{}
;*\xycircle<10pt>{{.}}
\endxy

4705 {\xyuncatcodes\gdef\next{--}}
4706 \xylet@\dashcorntemp@@=\next
4707 {\xyuncatcodes\gdef\next{.}}
4708 \xylet@\dotcorntemp@@=\next
4710 \xydef@\dotcorner@#1{%
4711 \expandafter\circleCorner@\expandafter{\dotcorntemp@@}{#1}}%
4712 \xydef@\dashcorner@#1{%
4713 \expandafter\circleCorner@\expandafter{\dashcorntemp@@}{#1}}
4715 \xydef@\circleCorner@#1#2{\setboxz@h\bgroup
4716 \edef\next{#2\relax\R@=\the\R@\relax\L@=\R@ }%
4717 \expandafter\xycircle@\next @{#1}%
4718 \ifcase#2\or \setboxz@h{\lower\R@\boxz@\kern\X@c}%
4719 \or \setboxz@h{\kern-\R@\lower\R@\boxz@\kern\R@\kern\X@c}%
4720 \or \setboxz@h{\kern-\R@\lower\R@\boxz@\kern\R@\kern\X@c}%
4721 \or \setboxz@h{\lower\R@\boxz@\kern\X@c}\fi
4722 \wdz@=\R@ \ht\z@=\R@ \dp\z@=\R@ \boxz@

4723 }

2.1.3 Quadratic Splines

Quadratic Bézier splines, as distinct from cubic Bézier splines, are constructed from parabolic arcs, using ‘control points’ to determine the tangents where successive arcs are joined.

Various implementations of such curves exist. The one adopted here is consistent with the xfig drawing utility and tpic implementations. These have the property of beginning and ending with straight segments, half the length to the corresponding adjacent control-point. Furthermore the midpoint between successive control-points lies on the spline, with the line joining the control-points being tangent there.

Such curves are specified, either as a ⟨decor⟩ or as an ⟨object⟩, using…

                                  \qspline{⟨style⟩}

where the start and end of the curve are at p and c respectively. The control-points are taken from the current stack, see 1.3o. If this stack is empty then a straight line is constructed.

The following example compares the quadratic spline with the gentler curving B-spline having the same control points, using \crvs.

[figure: P; +; +; +; C]

\xy /r1.5pc/:,+<5pc,3pc>*+{P};p
@(,+(2,2)*{+}@+, +(2,-2)*{+}@+
,+(2,2)*{+}@+, +(2,0)*+{C}="C"
,*\qspline{},"C",**\crvs{.}
,@i @)\endxy

If the current stack is empty, simply pass everything to \crvs@, as if the request originated from a \crvs or \ar. Otherwise we must build up the segments of the spline.

4773 \xydef@\qspline{\hbox\bgroup\crvresetbreaks@ \xy@spline@}
4775 \xydef@\xy@spline@#1#{\if\sempty@ \DN@{\crvs@{}\resetbreaks@}%
4776 \else\DN@{\xy@spline@i{#1}}\fi \next@ }%

The #1 parameter to \xy@spline@i is to allow alternative implementations; currently it is ignored. When #1 is indeed empty,

4784 \xydef@\xy@spline@i#1#2{\def\splineSTYLE@{#2}%
4785 \DN@{\xy@spline@ii}\DNii@{#1}%
4786 \ifx\nextii@\empty\DN@{\xy@spline@ii@@}\fi \next@ }
4788 \xydef@\xy@spline@ii{\save@ \cfromp@\idfromc@{@p}%
4789 \enter@\cplusthec@ \count@@=\s@top\advance\count@@\m@ne
4790 \cfroms@{\count@@}\leave@
4791 \halve@dimen\X@c  %  \divide\X@c\tw@
4792 \halve@dimen\Y@c  %  \divide\Y@c\tw@
4793 \czeroEdge@ \idfromc@{@c}%
4794 \expandafter\doSplineStraight@\expandafter{\splineSTYLE@}%
4795 \count@=\@ne \edef\next@{\the\count@}%
4796 \ifx\next@\s@top\DN@{\xy@spline@iv}\else\DN@{\xy@spline@iii}\fi
4797 \next@ }
4798 \xylet@\xy@spline@ii@@=\xy@spline@ii
4800 \xydef@\xy@spline@iii{\crv@cnt@=\s@top
4801 \loop \advance\crv@cnt@\m@ne \xy@spline@g \ifnum\crv@cnt@>\@ne\repeat
4802 \xy@spline@iv}
4804 \xydef@\xy@spline@g{\cfromid@{@c}\idfromc@{@p}%
4805 \count@@=\crv@cnt@\cfroms@{\count@@}\idfromc@{@m}%
4806 \enter@\cplusthec@ \count@@=\crv@cnt@ \advance\count@@\m@ne
4807 \cfroms@{\count@@}\leave@
4808 \halve@dimen\X@c  %  \divide\X@c\tw@
4809 \halve@dimen\Y@c  %  \divide\Y@c\tw@
4810 \czeroEdge@\idfromc@{@c}%
4811 \expandafter\doSplineSegment@\expandafter{\splineSTYLE@}}

4813 \xydef@\xy@spline@iv{\cfromid@{@c}\idfromc@{@p}%
4814 \cfroms@{\z@}\idfromc@{@m}\leave@ \save@
4815 \enter@\cplusthec@ \cfromid@{@m}\leave@
4816 \halve@dimen\X@c  %  \divide\X@c\tw@
4817 \halve@dimen\Y@c  %  \divide\Y@c\tw@
4818 \czeroEdge@\idfromc@{@c}%
4819 \expandafter\doSplineSegment@\expandafter{\splineSTYLE@}%
4820 \xy@spline@v }
4822 \xydef@\xy@spline@v{\cfromid@{@c}\idfromc@{@p}%
4823 \leave@ \save@ \idfromc@{@c}%
4824 \expandafter\doSplineStraight@\expandafter{\splineSTYLE@}%
4825 \xy@spline@x }
4827 \xydef@\xy@spline@x{\leave@
4828 \def\Drop@@{\splineDrop@ \resetbreaks@}%
4829 \def\Connect@@{\straight@\relax\splineConnect@ \resetbreaks@}%
4830 \OBJECT@x}
4832 \xydef@\splineDrop@{\ifInvisible@\setboxz@h{}%
4833 \else\setboxz@h{\kern-\the\X@c\raise-\the\Y@c\hbox{\styledboxz@}}\fi
4834 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@ }
4836 \xydef@\splineConnect@{%
4837 \ifInvisible@\else\box\lastobjectbox@\fi }%

The initial and final points in a segment are stored as @p and @c respectively. Where needed, the control is in @m.

4844 \xydef@\doSplineStraight@#1{\begingroup \sinit@
4845 \cfromid@{@p}\pfromc@\cfromid@{@c}%
4846 \connect@\crvs{#1}\relax\sleave@\endgroup }
4848 \xydef@\doSplineSegment@#1{\begingroup \sinit@
4849 \cfromid@{@p}\pfromc@\senter@\cfromid@{@m}\spushc@\cfromid@{@c}%
4850 \connect@\crvs{#1}\relax\sinit@\sleave@\endgroup }

The end & Log

4858 \xyendinput
4860 % $Log: xycurve.doc,v $
4861 % Revision 3.7  1999/02/16 15:12:50  krisrose
4862 % Interim release (Y&Y fonts now free).

4863 %

4864 % Revision 3.6  1998/03/06 01:28:05  krisrose
4865 % Releasing (with Y&Y fonts).

4866 %

4867 % Revision 3.4  1997/05/18 01:13:24  ross
4868 % Essential bugfixes.

4869 %

4870 % Revision 3.3  1996/12/18  09:01:45  ross
4871 % major revisions for the new BREAK methods
4872 % spline edge-finding is more robust
4873 % spline-breaks fully implemented

196 CHAPTER 2. EXTENSIONS

4874 % intersections of curve with straight connections implemented
4875 % improved tracings
4876 % adjusted methods for styles

4877 %

4878 % Revision 3.2  1995/09/19  18:20:20  ross
4879 % Bug fix release.

4880 %

4881 % Revision 3.1  1995/09/05  20:36:33  ross
4882 % Release!

4883 %

4884 % Revision 3.0  1995/07/07  20:13:19  ross
4885 % Major release w/new User's Guide!

4886 %

4887 % Revision 2.13  1995/07/05  07:58:43  ross
4888 % Ready for v3 release?

4889 %

4890 % Revision 2.12  1994/10/25  03:01:14  ross
4891 % Final 3beta release [bug fixes & AMS-LaTeX fitting].

4892 %

4893 % Revision 2.12  1994/09/05  08:22:11  ross
4894 % incorporates some speed-ups, extra documentation

4895 %

4896 % Revision 2.11  1994/07/05  09:27:52  ross
4897 % Minor fixes; use 2.11 kernel stack code.

4898 %

4899 % Revision 2.9  1994/06/09  14:50:54  ross
4900 % Release 3beta.

4901 %

4902 % Revision 2.8  1994/04/08  10:36:40  ross
4903 % Second 3alpha release.

4904 %

4905 % Revision 2.7  1994/03/08  02:06:01  kris
4906 % Release 3alpha.

4907 %

4908 % Revision 2.6.9.1  1994/03/07  04:22:46  ross
4909 % Last internal 3alpha and pre-2.7 release.

4910 %

4911 % NEW for version 2.7 inspired by Knuth's picmac.tex.

2.2 Frame and Bracket extension

Vers. 3.7 by Kristoffer H. Rose ⟨krisrose@brics.dk⟩

The frame extension provides a variety of ways to puts frames in XY-pictures. Header:

1 %% $Id: xyframe.doc,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %%

3 %% Xy-pic ``Frames and Brackets'' extension.
4 %% Copyright (c) 1991-1997  Kristoffer H. Rose  <krisrose@brics.dk>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997  Kristoffer H. Rose  <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{frame}{Frame and Bracket extension}{\stripRCS$Revision: 3.7 $}%
27 {Kristoffer H.~Rose}{krisrose@brics.dk}%
28 {BRICS/Computer Science, University of Aarhus, Ny Munkegade, building 540,
29  DK--8000 Aarhus~C}

The frames are XY-pic ⟨object⟩s on the form

\frm{ ⟨frame⟩ }

to be used in ⟨pos⟩itions: Dropping a frame with *… \frm{⟨frame⟩} will frame the c object; connecting with **… \frm{… ⟨frame⟩} will frame the result of c.p.

XY-pic interface The frames are integrated in XY-pic as ⟨object⟩s as follows. They generate a dummy object, then define the \Drop@@ action to place the requested frame. The \Connect@@ operation is defined to place the requested frame around the current and the previous object (using the \cmerge@ command of the kernel).

63 \xydef@\frm{\hbox{}\dimen@=\L@c \advance\dimen@\R@c \wdz@=\dimen@
64 \ht\z@=\U@c \dp\z@=\D@c \dimen@=\U@c \advance\dimen@\D@c
65 % \ifdim\wdz@=\z@ \def\Leftness@{0}\else \quotient@\Leftness@\L@c\wdz@ \fi
66 % \ifdim\dimen@=\z@ \def\Upness@{0}\else \quotient@\Upness@\U@c\dimen@ \fi
67 \ifdim\wdz@=\z@ \def\Leftness@{.5}\else \quotient@\Leftness@\L@c\wdz@ \fi
68 \ifdim\dimen@=\z@ \def\Upness@{.5}\else \quotient@\Upness@\U@c\dimen@ \fi
69 \expandafter\Edge@c\expandafter{\prevEdge@@}\let\frmradius@@=\z@
70 \def\Drop@@{}%
71 \def\Connect@@{\xy@@{\save@\cmerge@\Y@p\X@p\D@p\U@p\L@p\R@p\Drop@@}\restore}%
72 \xyFN@\frm@i}
74 \xylet@\frmradius@@=\z@

76 \xydef@\frm@i{%
77 \addLT@\ifx\next \addGT@{\addLT@\DN@##1}{\def\frmradius@@{##1}\xyFN@\frm@i}%
78 \else \DN@##1##{\frm@{##1}}\fi \next@}

The main command is \frm@ which looks up if a custom control sequence is available for the requested frame or whether the generic ‘curve along the edge’ code should be invoked.

86 \xydef@\frm@#1#2{\DNii@{frm#1{#2}}%
87 \expandafter\let\expandafter\next@\csname\codeof\nextii@\endcsname
88 \ifx\next@\relax \DNii@{frm{#2}}%
89  \expandafter\let\expandafter\next@\csname\codeof\nextii@\endcsname
90  \ifx\next@\relax \let\next@=\frm@generic \fi\fi \next@}
92 \xydef@\frm@generic{\xyerror@{No generic frames yet!}{}}

This extra command is used to define \Drop@@ for each frame such that \frmradius@@ is available.

99 \xydef@\frmDrop@#1{%
100 \ifx\frmradius@@\z@ \addtoDrop@@{\let\frmradius@@=\z@ #1}%
101 \else \expandafter\addtoDrop@@\expandafter{%
102  \expandafter\def\expandafter\frmradius@@\expandafter{\frmradius@@}#1}\fi}
104 \xydef@\EdgefromtheEdge@{%
105 \U@c=\the\U@c \D@c=\the\D@c \L@c=\the\L@c \R@c=\the\R@c
106 \Edge@c={\expandafter\noexpand\the\Edge@c}}
107 \xydef@\prevEdgefromtheEdge@{%
108 \U@c=\the\U@c \D@c=\the\D@c \L@c=\the\L@c \R@c=\the\R@c
109 \noexpand\def\noexpand\prevEdge@@{\expandafter\noexpand\the\Edge@c}}
111 \xydef@\addtoDrop@@#1{%
112 \expandafter\def\expandafter\Drop@@\expandafter{\Drop@@#1}}
113 \xydef@\addbeforeDrop@@#1{\DNii@{#1}%
114 \expandafter\DN@\expandafter{\expandafter\nextii@\Drop@@}%
115 \expandafter\expandafter\expandafter\def
116 \expandafter\expandafter\expandafter\Drop@@
117  \expandafter\expandafter\expandafter{\next@}}

Below we distinguish between ‘ordinary’ frames, ‘brackets’ and ‘fills’; last we present how some frames can be added to other objects using object modifier ⟨shape⟩s.

2.2.1 Frames

Figure 2.2 shows the possible frames and the applicable ⟨modifier⟩s with reference to the notes below.

Notes

2.2a. The \frm{} frame is a dummy useful for not putting a frame on something, e.g., in macros that take a ⟨frame⟩ argument.

206 \xydefcsname@{frm{}}{}
207 \xyletcsnamecsname@{frm[]{}}{frm{}}
208 \xyletcsnamecsname@{frm[o]{}}{frm{}}

2.2b. Rectangular frames include \frm{.}, \frm{-}, \frm{=}, \frm{--}, \frm{==}, and \frm{o-}.

They all make rectangular frames that essentially trace the border of a rectangle-shaped object.

Framed with \frm{} frame2.2a Framed with \frm{.} frame2.2b Framed with

                              \frm<44pt>{.}

frame2.2b

Framed with \frm{-} frame2.2b Framed with

               \frm<8pt>{-}

frame2.2b

[figure]

Framed with

                              \frm<44pt>{-}

frame2.2b

[figure]

Framed with \frm{=} frame2.2b Framed with

               \frm<8pt>{=}

frame2.2b

[figure] [figure]

Framed with

                              \frm<44pt>{=}

frame2.2b

[figure] [figure]

Framed with \frm{--} frame2.2b

[figure]

Framed with \frm{o-} frame2.2b

[figure]

Framed with

                              \frm<44pt>{--}

frame2.2b

[figure]

Framed with \frm{,} frame2.2c Framed with

               \frm<5pt>{,}

frame2.2c

Framed with \frm{-,} frame2.2c

Framed with \frm{o} frame2.2d

[figure]

Framed with

               \frm<8pt>{o}

frame2.2d

[figure]

Framed with \frm{.o} frame2.2d

Framed with \frm{oo} frame2.2d

[figure] [figure]

Framed with

               \frm<8pt>{oo}

frame2.2d

[figure] [figure]

Framed with \frm{-o} frame2.2d

[figure]

Framed with \frm{e} frame2.2e

[figure]

Framed with

             \frm<20pt,8pt>{e}

frame2.2e

[figure]

Framed with \frm{.e} frame2.2e

Framed with \frm{ee} frame2.2e

[figure] [figure]

Framed with

            \frm<20pt,8pt>{ee}

frame2.2e

[figure] [figure]

Framed with \frm{-e} frame2.2e

[figure]

{ ; |

These are overlayed with the

\frm{.}

frame above to show the way they are centered on the object

Figure 2.2: Plain ⟨frame⟩s.

Framed with \frm\{_\\}\} frame2.2f  Framed with \frm\{^\\}\} frame2.2f  Framed with \frm\{\\{\} frame2.2f \{ ; |  Framed with \frm\{\\}\} frame2.2f\} ; | \begin{matrix}Framed with \\ \frm\{_)\} \\ frame2.2g \end{matrix}  \begin{matrix}Framed with \\ \frm\{^)\} \\ frame2.2g \end{matrix}  \begin{matrix}Framed with \\ \frm\{(\} \\ frame2.2g \end{matrix} \{  \begin{matrix}Framed with \\ \frm\{)\} \\ frame2.2g \end{matrix}\}

Figure 2.3: Bracket ⟨frame⟩s.

The ⟨frame⟩s \frm{-} and \frm{=} allow an optional corner radius that rounds the corners of the frame with quarter circles of the specified radius. This is not allowed for the other frames— the \frm{o-} frame always gives rounded corners of the same size as the used dashes (when \xydashfont is the default one then these are 5pt in radius).

Exercise 2.4: How do you think the author typeset the following?

[figure: A; B]

The commands still hack away with rules and stuff…

\frm{.} just fills the edges of the object rectangle border with dots using dots as in dotted connections in the kernel.

252 \xydefcsname@{frm{.}}{\frmDrop@{\let\zerocorner=\framezerodot@@
253 \let\framehfill=\frm@doth@@ \let\framevfill=\frm@dotv@@
254 \framed@@{\frmradius@@}}}
256 \xyletcsnamecsname@{frm[]{.}}{frm{.}}
258 \xydef@\frm@doth@@{\setboxz@h{\kern5\B@\framezerodot@@\kern5\B@}\ht\z@=\B@
259 \dp\z@=\B@\kern5\B@\xleaders\boxz@\hss\kern5\B@}
260 \xydef@\frm@dotv@@{\setboxz@h to2\B@{\hss\framezerodot@@\hss}\ht\z@=5\B@
261 \dp\z@=5\B@\kern5\B@\xleaders\boxz@\vss\kern5\B@}
263 \xyletcsnamecsname@{frm{..}}{frm{.}}
265 \xylet@\framezerodot@@=\zerodot

The \frm⟨variant⟩{-} and \frm⟨variant⟩{=} set a single/double frame that just surrounds the current object; if a ⟨radius⟩ is given then it should be a <⟨dimen⟩> where the ⟨dimen⟩ will be used for the corner radius.

The commands for \frm{-} and \frm{=} are quite similar in that they just call \framed@ one or two times, respectively, with the corner radius and L, R, D, U extents reflecting the size of the frame. \framed@ then sets the horizontal and vertical fill commands to generate rules of the right length, then calls \framed@@ where the real work is done.

281 \xydefcsname@{frm{-}}{\frmDrop@{\framed@\frmradius@@}}
282 \xyletcsnamecsname@{frm[]{-}}{frm{-}}
284 \xydef@\framed@{\let\zerocorner=\framezerodot@@
285 \let\framehfill=\frm@solidh@@ \let\framevfill=\frm@solidv@@ \framed@@}
287 \xylet@\framesetthick@=\relax
289 \xydef@\frm@solidh@@{\framesetthick@\leaders\hrule height\B@ depth\B@\hfill}
290 \xydef@\frm@solidv@@{\framesetthick@\leaders\vrule width2\B@\vfill}
292 \xydefcsname@{frm{=}}{\frmDrop@{\framed@\frmradius@@
293 {\advance\L@c-2\p@ \advance\R@c-2\p@ \advance\U@c-2\p@ \advance\D@c-2\p@
294  \dimen@=\frmradius@@
295  \ifdim\dimen@>2\p@ \advance\dimen@-2\p@ \else \dimen@=\z@\fi
296 \framed@\dimen@}}}
298 \xyletcsnamecsname@{frm[]{=}}{frm{=}}

2.2. FRAME AND BRACKET EXTENSION 201

When the line extension is also loaded then we use the line thickness for frames:

305 \xydef@\framesetthick@line{\B@=.5\xylinethick@}
307 \xydef@\frm@thickc@@{\hbox{\framesetthick@line
308 \vrule height.5\B@ depth.5\B@ width\B@}}
310 \xywithoption{line}{%
311 \let\framezerodot@@\frm@thickc@@ \let\framesetthick@=\framesetthick@line}

\framed@@ is where we build a box with the sides of the frame displaced appropriately. To DoGeneralise this to handle any directional!

319 %       Procedure:
320 %       %0 setup hrulefill and vrulefill as apropriate...
321 %       %1 Lower R to be less than half of both (U+D) and (L+R).
322 %       %2 Start vbox at (X-L,Y-D) except center overshoot.
323 %       %3 Generate corner CO4 at R; w[\A@] := -1/2 width(corner);
324 %          r[\B@] := 1/2 rulewidth; h[\dimen@ii] := U+D+2w;
325 %       %4 Row 1: hbox to W{kern w CO4 hrulefill CO3 kern w}.
326 %       %5 Row 2: hbox to W{kern-r vbox to h{vrulefill}
327 %                            hfill vbox to h{vrulefill} kern-r}.
328 %       %6 Row 3: hbox to W{kern w CO1 hrulefill CO2 kern w}.
330 \xydef@\framed@@#1{\setboxz@h{\R@=#1\relax
331 \dimen@=\L@c \advance\dimen@\R@c \dimen@ii=\U@c \advance\dimen@ii\D@c %1
332 \ifdim.5\dimen@<\R@ \R@=.5\dimen@ \fi
333 \ifdim.5\dimen@ii<\R@ \R@=.5\dimen@ii \fi
334 \A@=\X@c \advance\A@-\L@c \B@=\Y@c \advance\B@-\D@c                   %2
335 \ifdim\R@<\p@\else \cirrestrict@@ \fi
336 \dimen@=2\R@ \advance\dimen@-\L@c \advance\dimen@-\R@c
337 \ifdim\dimen@>\z@ \advance\A@-.5\dimen@ \fi
338 \dimen@=2\R@ \advance\dimen@-\U@c \advance\dimen@-\D@c
339 \ifdim\dimen@>\z@ \advance\B@-.5\dimen@ \fi
340 \kern\A@ \raise\B@\vbox to \dimen@ii{\framed@body@@}}%
341 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}
343 \xydef@\framed@body@{%
344 \advance\dimen@ii.22\p@ \advance\dimen@-.2\p@
345 \setboxz@h{\corn@@4\R@}\A@=-.5\wdz@ \B@=.5\xydashw@                    %3
346 \dimen@=\L@c \advance\dimen@\R@c \advance\dimen@-.2\p@
347 \setboxz@h to\dimen@{\kern\A@ \boxz@ \framehfill\corn@@3\R@\kern\A@}%4
348 \advance\dimen@ii-\dp\z@ \kern-\ht\z@ \nointerlineskip\boxz@
349 \dimen@=\L@c \advance\dimen@\R@c \advance\dimen@-.2\p@
350 \setboxz@h to\dimen@{\kern\A@\corn@@1\R@\framehfill\corn@@2\R@\kern\A@}%6
351 \advance\dimen@ii-\ht\z@
352 \dimen@=\L@c \advance\dimen@\R@c \advance\dimen@.2\p@
353 \nointerlineskip\hbox to\dimen@{%                                      %5
354 \setbox\z@=\vbox to\dimen@ii{\framevfill}\kern-.5\wdz@\copy\z@
355 \hss \copy\z@\kern-.5\wdz@ }%
356 \nointerlineskip\boxz@ \vss \kern\z@}
358 \xylet@\framed@body@@=\framed@body@
360 \xylet@\zerocorner=\framezerodot@@

362 \xydef@\solidcorner@#1#2{\hbox\bgroup \R@=#2\relax
363 \ifdim\R@<\p@ \zerocorner
364 \else \cirrestrict@@ \multiply\count@8 %
365 \setboxz@h{\corn@x@@{#1}}\dimen@=\wdz@
366 \ifcase#1\or \ht\z@=\z@ \kern\dimen@ \raise\dimen@\boxz@
367 \or \ht\z@=\z@ \raise\dimen@\boxz@ \kern\dimen@
368 \or \dp\z@=\z@ \lower\dimen@\boxz@ \kern\dimen@
369 \or \dp\z@=\z@ \kern\dimen@ \lower\dimen@\boxz@ \fi
370 \vrule height\dimen@ depth\dimen@ width\z@\fi
371 \edef\tmp@{\egroup \U@c=\the\dimen@}\tmp@ \D@c=\U@c \L@c=\U@c \R@c=\U@c
372 \Edge@c={\circleEdge}\ignorespaces}
374 \xydef@\corn@x@#1{\ifcase#1\or
375 \circhar@@\z@ \circhar@@\@ne\or\circhar@@\tw@ \circhar@@3\or
376 \circhar@@5\circhar@@4\or\circhar@@7\circhar@@6\fi}
378 \xylet@\corn@x@@=\corn@x@
380 \xydef@\corn@@{\DN@{\solidcorner@}%
381 \ifx\framehfill\frm@doth@@ \DN@{\let\cirrestrict@@=\relax
382  \let\corn@x@@=\dotcorner@@ \let\zerodot=\framezerodot@@
383  \solidcorner@ }%
384 \else\ifx\framehfill\frm@dashh@@ \DN@{\let\cirrestrict@@=\relax
385  \let\corn@x@@=\dashcorner@@ \let\zerodot=\framezerodot@@
386  \solidcorner@ }%
387 \fi\fi \next@}
389 \xydef@\dotcorner@@#1{\zerocorner}
390 \xydef@\dashcorner@@#1{\zerocorner}
392 \xywithoption{curve}{%
393 \let\dotcorner@@=\dotcorner@ \let\dashcorner@@=\dashcorner@}

The dashed frames ‘dash’ with the dash used for dashed lines.

399 \xydefcsname@{frm{--}}{%
400 \frmDrop@{\let\zerocorner=\framezerodot@@
401 \let\framehfill=\frm@dashh@@ \let\framevfill=\frm@dashv@@
402 \framed@@\frmradius@@}}
404 \xyletcsnamecsname@{frm[]{--}}{frm{--}}
406 \xydef@\frm@dashh@@{\setboxz@h{\dashhfillchar}%
407 \ht\z@=\B@ \dp\z@=\B@ \wdz@=2\xydashl@
408 \copy\z@ \xleaders\copy\z@\hss \boxz@\kern-\xydashl@}
409 \xydef@\frm@dashv@@{\setboxz@h to2\B@{\hss\dashvfillchar\hss}\ht\z@=\z@
410 \dp\z@=2\xydashl@ \nointerlineskip\copy\z@ \xleaders\copy\z@\vss
411 \nointerlineskip\boxz@\kern-\xydashl@}%
413 \xydef@\dashhfillchar{{\rDirection@\xydashl@ \line@@}}
414 \xydef@\dashvfillchar{{\dDirection@\xydashl@ \line@@}}

Bug: Setting the corner-radius to less than 10pt has no effect when using \frm{o-}; instead a default size of .8\xydashl@ is used.

421 \xydefcsname@{frm{o-}}{%
422 \ifdim\frmradius@@<2\xydashl@\relax \dimen@=.8\xydashl@

423 \expandafter\def\expandafter\frmradius@@\expandafter{\the\dimen@}\fi
424 \frmDrop@{\let\zerocorner=\framezerodot@@
425 \let\framehfill=\frm@rddashh@@ \let\framevfill=\frm@rddashv@@
426 \framed@@\frmradius@@}}%
428 \xydef@\frm@rddashh@@{\setboxz@h{\kern\xydashl@\dashhfillchar}%
429 \ht\z@=\B@ \dp\z@=\B@ \copy\z@ \xleaders\copy\z@\hss \boxz@ \kern\xydashl@}
430 \xydef@\frm@rddashv@@{\ifdim\dimen@ii<2\xydashl@\else
431 \setbox\z@=\vbox to2\xydashl@{\hbox to2\B@{\hss\dashvfillchar\hss}\vss}%
432 \kern\xydashl@ \copy\z@ \xleaders\copy\z@\vss
433 {\ifdim\dimen@ii<2\xydashl@\else\aftergroup\boxz@\fi}\fi}

2.2c. The frame \frm{,} puts a shade, built from rules, into the picture beneath the (assumed rectangular) object, thereby giving the illusion of ‘lifting’ it; \frm<⟨dimen⟩>{,} makes this shade ⟨dimen⟩ deep.

   \frm{-,} combines a \frm{-} with a \frm{,}.

A black rule is just that, a shade is two rules placed under and left of the rectangular object outline.

452 \xydefcsname@{frm{,}}{%
453 \ifx\frmradius@@\z@ \shaded@{1.2\p@}\else \shaded@\frmradius@@ \fi}
455 \xydef@\shaded@#1{\frmDrop@{\R@=#1\relax
456 {\advance\X@c\R@ \advance\Y@c-\D@c \U@c=\z@ \D@c=\R@ \blacked@}%
457 {\advance\X@c\R@c \advance\Y@c-\R@ \L@c=\z@ \R@c=\R@ \blacked@}}}
459 \xydefcsname@{frm{-,}}{\addtoDrop@@{\drop\frm{-}\drop\frm{,}}}
461 \xydef@\blacked@{\setboxz@h{%
462 \A@=\X@c \advance\A@-\L@c \dimen@=\L@c \advance\dimen@\R@c
463 \B@=\Y@c \advance\B@-\D@c \dimen@ii=\Y@c \advance\dimen@ii\U@c
464 \advance\A@-.5\xydashw@
465 % \advance\B@-\xydashw@  \advance\dimen@ii-.5\xydashw@
466 \kern\A@ \blacked@@ }%
467 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}
469 \xydef@\bblacked@{\setboxz@h{%
470 \dimen@=\L@c \advance\dimen@\R@c \B@=-\D@c \dimen@ii=\U@c
471 \kern-\L@c \blacked@@ \kern-\dimen@ \kern\L@c}%
472 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}
474 \xydef@\blacked@@{\vrule width\dimen@ depth-\B@ height\dimen@ii}

The \blacked option is subsumed within a more general \filled; see below.

2.2d. Circles done with \frm{o} have radius as (R + L)/2 and with \frm<⟨dimen⟩>{o} have radius as the ⟨dimen⟩; \frm{oo} makes a double circle with the outermost circle being the same as that

   of \frm{o}.

Exercise 2.5: What is the difference between *\cir{} and *\frm{o}?

497 \xydefcsname@{frm{o}}{%
498 \ifx\frmradius@@\z@
499 \frmDrop@{\dimen@=.5\L@c \advance\dimen@.5\R@c

500  \let\framehfill=\frm@solidh@@ \let\framevfill=\frm@solidv@@
501  \circled@\dimen@}%
502 \else
503 \frmDrop@{\let\framehfill=\frm@solidh@@
504  \let\framevfill=\frm@solidv@@ \circled@\frmradius@@}%
505 \fi}
507 \xydefcsname@{frm{oo}}{%
508 \ifx\frmradius@@\z@
509 \frmDrop@{\dimen@=.5\L@c \advance\dimen@.5\R@c
510  \let\framehfill=\frm@solidh@@ \let\framevfill=\frm@solidv@@
511  {\circled@\dimen@}\advance\dimen@-2.1\p@ \circled@\dimen@}%
512 \else
513 \frmDrop@{\dimen@=\frmradius@@
514  \let\framehfill=\frm@solidh@@ \let\framevfill=\frm@solidv@@
515  {\circled@\dimen@}\advance\dimen@-2.1\p@ \circled@\dimen@}%
516 \fi}
518 \xydef@\circled@#1{\setboxz@h\bgroup \R@=#1\relax
519 \setboxz@h{\vbox{\circled@x@@}}%
520 \A@=\X@c \advance\A@-.5\wd\z@
521 \B@=\Y@c \advance\B@-.5\ht\z@ \advance\B@.5\dp\z@ \advance\B@.2\p@
522 \edef\tmp@{\egroup\dimen@=\the\wdz@}%
523 \kern\A@ \raise\B@\boxz@
524 \tmp@ \divide\dimen@4 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}
526 \xydef@\circled@x@{\hbox{\corn@@4\R@ \corn@@3\R@}%
527  \nointerlineskip\hbox{\corn@@1\R@ \corn@@2\R@}}
528 \xylet@\circled@x@@=\circled@x@

The code here is repetitive and could be improved. The only purpose of \let\framehfill=\frm@dashh@@ etc. is to serve as a marker for the required style: solid/dashed/dotted.

536 \xydefcsname@{frm{.o}}{%
537 \ifx\frmradius@@\z@ \frmDrop@{\let\framehfill=\frm@doth@@
538 \dimen@=.5\L@c \advance\dimen@.5\R@c \circled@\dimen@}%
539 \else
540 \frmDrop@{\let\framehfill=\frm@doth@@ \circled@\frmradius@@}%
541 \fi}
543 \xydefcsname@{frm{-o}}{%
544 \ifx\frmradius@@\z@ \frmDrop@{\let\framehfill=\frm@dashh@@
545  \dimen@=.5\L@c \advance\dimen@.5\R@c \circled@\dimen@}%
546 \else
547 \frmDrop@{\let\framehfill=\frm@dashh@@ \circled@\frmradius@@}%
548 \fi}

2.2e. Ellipses specified using \frm{e} have axis lengths (R + L)/2 and (U + D)/2, while those with \frm<⟨dimen,dimen⟩>{e} use the given lengths for the axes. \frm{ee} makes a double ellipse with outermost ellipse being the same as that of \frm{e}.

Without special support to render the ellipses, either via a ⟨driver⟩ or using the arc feature, the ellipse will be drawn as a circle of radius approximately the average of the major and minor axes.

567 \xydefcsname@{frm{e}}{\ellipse@whichfrm@\ellipsesolidframed@}%
568 \xydefcsname@{frm{.e}}{\ellipse@whichfrm@\ellipsedotframed@}%
569 \xydefcsname@{frm{-e}}{\ellipse@whichfrm@\ellipsedashframed@}%
571 \xydefcsname@{frm{ee}}{\ellipse@whichdblfrm@\ellipsesolidframed@}%
572 \xydefcsname@{frm2{.e}}{\ellipse@whichdblfrm@\ellipsedotframed@}%
573 \xydefcsname@{frm2{-e}}{\ellipse@whichdblfrm@\ellipsedashframed@}%
575 \xyletcsnamecsname@{frm[o]{-}}{frm{e}}
576 \xyletcsnamecsname@{frm[o]{=}}{frm{ee}}
577 \xyletcsnamecsname@{frm[o]{.}}{frm{.e}}
578 \xyletcsnamecsname@{frm[o]{--}}{frm{-e}}
580 \xydef@\ellipse@whichfrm@#1{%
581 \ifx\frmradius@@\z@
582 \frmDrop@{#1\dimen@=.5\L@c \advance\dimen@.5\R@c
583  \dimen@ii=.5\U@c \advance\dimen@ii.5\D@c
584  \edef\next@{\noexpand\ellipsed@{\the\dimen@}{\the\dimen@ii}}\next@ }%
585 \else
586 \frmDrop@{#1\expandafter\ellipsed@i@\frmradius@@,,@@}%
587 \fi}
589 \xydef@\ellipse@whichdblfrm@#1{%
590 \ifx\frmradius@@\z@
591 \frmDrop@{#1\dimen@=.5\L@c \advance\dimen@.5\R@c
592  \dimen@ii=.5\U@c \advance\dimen@ii.5\D@c
593  \edef\next@{\noexpand\ellipsed@e@{\the\dimen@}{\the\dimen@ii}}\next@ }%
594 \else
595 \frmDrop@{#1\expandafter\ellipsed@ei@\frmradius@@,,@@}%
596 \fi}
598 \xydef@\ellipsed@i@#1,#2,#3@@{\DNii@{,}\DN@{#3}%
599 \ifx\next@\nextii@
600 \dimen@=#1\relax \dimen@ii=#2\relax
601 \edef\next@{\noexpand\ellipsed@{\the\dimen@}{\the\dimen@ii}}%
602 \else \ifx\next@\empty \DN@{#2}%
603 \ifx\next@\empty \DN@{#1}%
604  \dimen@=.5\L@c \advance\dimen@.5\R@c
605  \dimen@ii=.5\U@c \advance\dimen@ii.5\D@c
606  \edef\next@{\noexpand\ellipsed@{\the\dimen@}{\the\dimen@ii}}%
607 \else \dimen@=#1\relax
608  \edef\next@{\noexpand\ellipsed@{\the\dimen@}{\the\dimen@ii}}%
609 \fi
610 \else\xywarning@{ignoring extra tokens in elliptical frame: #3 }%
611 \dimen@=#1\relax \dimen@ii=#2\relax
612 \edef\next@{\noexpand\ellipsed@{\the\dimen@}{\the\dimen@ii}}%
613 \fi\fi \next@ }
615 \xydef@\ellipsed@ei@#1,#2,#3@@{\DNii@{,}\DN@{#3}%
616 \ifx\next@\nextii@
617 \dimen@=#1\relax \dimen@ii=#2\relax
618 \edef\next@{\noexpand\ellipsed@e@{\the\dimen@}{\the\dimen@ii}}%
619 \else \ifx\next@\empty \DN@{#2}%

620 \ifx\next@\empty \DN@{#1}%
621  \dimen@=.5\L@c \advance\dimen@.5\R@c
622  \dimen@ii=.5\U@c \advance\dimen@ii.5\D@c
623  \edef\next@{\noexpand\ellipsed@e@{\the\dimen@}{\the\dimen@ii}}%
624 \else
625  \dimen@=#1\relax
626  \edef\next@{\noexpand\ellipsed@e@{\the\dimen@}{\the\dimen@}}%
627 \fi
628 \else\xywarning@{ignoring extra tokens in elliptical frame: #3 }%
629 \dimen@=#1\relax \dimen@ii=#2\relax
630  \edef\next@{\noexpand\ellipsed@e@{\the\dimen@}{\the\dimen@ii}}%
631 \fi\fi \next@ }
633 \xydef@\ellipsed@e@#1#2{%
634 \dimen@=#1\relax \dimen@ii=#2\relax
635 \edef\next@{\noexpand\ellipsed@{\the\dimen@}{\the\dimen@ii}}\next@
636 \dimen@=#1\relax \dimen@ii=#2\relax
637 \ifdim\dimen@>2\p@ \advance\dimen@-2\p@ \else \dimen@=\z@\fi
638 \ifdim\dimen@ii>2\p@ \advance\dimen@ii-2\p@ \else \dimen@ii=\z@\fi
639 \edef\next@{\noexpand\ellipsed@{\the\dimen@}{\the\dimen@ii}}\next@ }%
641 \xydef@\ellipsed@#1#2{\setboxz@h\bgroup \relax
642 \setboxz@h{\vbox{\ellipsed@x@@{#1}{#2}}}%
643 \A@=\X@c \advance\A@-.5\wd\z@
644 \B@=\Y@c \advance\B@-.5\ht\z@ \advance\B@.5\dp\z@ \advance\B@.2\p@
645 \edef\tmp@{\egroup\dimen@=\the\wdz@}%
646 \kern\A@ \raise\B@\boxz@
647 \tmp@ \divide\dimen@4 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}
649 \xydef@\ellipsed@i#1#2{{\R@c=#1\relax\L@c=\R@c
650 \U@c=#2\relax\D@c=\U@c \ellipsed@{#1}{#2}}}
652 \xydef@\ellipsed@x@#1#2{\R@=#1\relax\advance\R@#2\relax
653 \divide\R@\tw@ \circled@x@@ }
654 \xylet@\ellipsed@x@@=\ellipsed@x@
656 \xydef@\ellipsesolidframed@{%
657 \let\framehfill=\frm@solidh@@ \let\framevfill=\frm@solidv@@}
658 \xydef@\ellipsedotframed@{%
659 \let\framehfill=\frm@doth@@ \let\framevfill=\frm@dotv@@}
660 \xydef@\ellipsedashframed@{%
661 \let\framehfill=\frm@dashh@@ \let\framevfill=\frm@dashv@@}

To Do: Allow ⟨frame variant⟩s like those used for directionals, i.e., \frm2{-} should be the same as \frm{=}. Add \frm{o,} and more brackets.

2.2.2 Brackets

The possible brackets are shown in figure 2.3 with notes below.

Notes

2.2f. Braces are just the standard plain TEX large braces inserted correctly in XY-pic pictures with the ‘nib’ aligned with the reference point of the object they brace.

Exercise 2.6: How do you think the author typeset the following?

A B

They just use the pieces of plain TEX brace delimiters at \Bigg size and those of \overbrace and

   \underbrace.

714 \xydefcsname@{frm{\{}}{\addtoDrop@@{\lbraced}}
715 \xydefcsname@{frm{\}}}{\addtoDrop@@{\rbraced}}
717 \xydefcsname@{frm{^\}}}{\addtoDrop@@{\ubraced}}
718 \xydefcsname@{frm{_\}}}{\addtoDrop@@{\dbraced}}

The horizontal ones mimick the plain TEX ones quite closely:

724 \xydef@\dbraced{\xy@@{\setboxz@h{%
725 \A@=\X@c \advance\A@-\L@c \B@=\Y@c \advance\B@-\D@c
726 \setboxz@h{$\m@th\bracelu$}\dimen@=2\wdz@ \advance\B@-.5\ht\z@
727 \ifdim\R@c<\dimen@ \R@c=\dimen@ \fi
728 \ifdim\L@c<\dimen@ \advance\A@-\dimen@ \advance\A@\L@c \L@c=\dimen@ \fi
729 \advance\A@-.25pt %
730 \kern\A@\raise\B@\hbox{%
731  \hbox to\L@c{$\m@th\bracelu\leaders\vrule\hfil\bracerd$}%
732  \kern.5pt %
733  \hbox to\R@c{$\m@th\braceld\leaders\vrule\hfil\braceru$}}}%
734 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}
736 \xydef@\ubraced{\xy@@{\setboxz@h{%
737 \A@=\X@c \advance\A@-\L@c \B@=\Y@c \advance\B@\U@c
738 \setboxz@h{$\m@th\bracelu$}\dimen@=2\wdz@
739 \ifdim\R@c<\dimen@ \R@c=\dimen@ \fi
740 \ifdim\L@c<\dimen@ \advance\A@-\dimen@ \advance\A@\L@c \L@c=\dimen@ \fi
741 \advance\A@-.25pt %
742 \kern\A@\raise\B@\hbox{%
743  \hbox to\L@c{$\m@th\braceld\leaders\vrule\hfil\braceru$}%
744  \kern.5pt %
745  \hbox to\R@c{$\m@th\bracelu\leaders\vrule\hfil\bracerd$}}}%
746 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}

The inserted extra .5pt at (1) is the authours responsibility…

The vertical ones repeat the above for the vertical brace extension characters:

756 {\catcode`\"=12 %
757 \global\mathchardef\braceur="338 %
758 \global\mathchardef\braceul="339 %
759 \global\mathchardef\bracedr="33A %
760 \global\mathchardef\bracedl="33B %
761 \global\mathchardef\bracecl="33C %
762 \global\mathchardef\bracecr="33D %
763 \global\mathchardef\bracec="33E }

208 CHAPTER 2. EXTENSIONS

765 \xydef@\lbraced{\xy@@{\setboxz@h{%
766 \A@=\X@c \advance\A@-\L@c \B@=\Y@c \advance\B@-\D@c
767 \setboxz@h{$\m@th\bracecl$}\dimen@ii=\dp\z@ \advance\A@-.5\wdz@
768 \setboxz@h{$\m@th\bracec$}\dimen@=\dp\z@
769 \ifdim\U@c<.5\dimen@ \U@c=.5\dimen@ \fi
770 \ifdim\D@c<.5\dimen@ \advance\B@-.5\dimen@ \advance\B@\D@c \D@c=.5\dimen@ \fi
771 \advance\U@c.6\p@ \advance\D@c.6\p@  \advance\B@-.6\p@
772 \kern\A@\raise\B@\vbox{\vbox to\U@c{%
773  \nointerlineskip\hbox{$\m@th\braceur$}%
774  \kern-.61\dimen@ \cleaders\copy\z@\vfil \kern-.4\dimen@
775  \nointerlineskip\hbox{$\m@th\bracecl$}\kern-.5\dimen@ii}%
776  \nointerlineskip\vbox to\D@c{\kern.5\dimen@ii
777  \kern-.4\dimen@ \cleaders\copy\z@\vfil \kern-.61\dimen@
778  \nointerlineskip\hbox{$\m@th\bracedr$}\kern\z@}}}%
779 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}
781 \xydef@\rbraced{\xy@@{\setboxz@h{%
782 \A@=\X@c \advance\A@\R@c \B@=\Y@c \advance\B@-\D@c
783 \setboxz@h{$\m@th\bracecr$}\dimen@ii=\dp\z@ \advance\A@-.5\wdz@
784 \setboxz@h{$\m@th\bracec$}\dimen@=\dp\z@
785 \ifdim\U@c<.5\dimen@ \U@c=.5\dimen@ \fi
786 \ifdim\D@c<.5\dimen@ \advance\B@-.5\dimen@ \advance\B@\D@c \D@c=.5\dimen@ \fi
787 \advance\U@c.6\p@ \advance\D@c.6\p@  \advance\B@-.6\p@
788 \kern\A@\raise\B@\vbox{\vbox to\U@c{%
789  \nointerlineskip\hbox{$\m@th\braceul$}%
790  \kern-.61\dimen@ \cleaders\copy\z@\vfil \kern-.4\dimen@
791  \nointerlineskip\hbox{$\m@th\bracecr$}\kern-.5\dimen@ii}%
792  \nointerlineskip\vbox to\D@c{\kern.5\dimen@ii
793  \kern-.4\dimen@ \cleaders\copy\z@\vfil \kern-.61\dimen@
794  \nointerlineskip\hbox{$\m@th\bracedl$}\kern\z@}}}%
795 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}

An ad hoc correction to compensate for the ‘undershoot’ of top/bottom segments is added at (1). 2.2g. Parenthesis are like braces except they have no nib and thus do not depend on where the

reference point of c is.

811 \xydefcsname@{frm{(}}{\addtoDrop@@{\lparenthesized}}
812 \xydefcsname@{frm{)}}{\addtoDrop@@{\rparenthesized}}
814 \xydefcsname@{frm{^)}}{\addtoDrop@@{\uparenthesized}}
815 \xydefcsname@{frm{_)}}{\addtoDrop@@{\dparenthesized}}

The horizontal ones repeat the braces only without a nib:

821 \xydef@\dparenthesized{\xy@@{\setboxz@h{%
822 \A@=\X@c \advance\A@-\L@c \B@=\Y@c \advance\B@-\D@c
823 \setboxz@h{$\m@th\bracelu$}\dimen@=2\wdz@ \advance\B@-.5\ht\z@
824 \ifdim\R@c<\dimen@ \R@c=\dimen@ \fi
825 \ifdim\L@c<\dimen@ \advance\A@-\dimen@ \advance\A@\L@c \L@c=\dimen@ \fi
826 \dimen@=\L@c \advance\dimen@\R@c
827 \kern\A@\raise\B@\hbox to\dimen@{%
828  $\m@th\bracelu\leaders\vrule\hfil\braceru$}}%

829 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}
831 \xydef@\uparenthesized{\xy@@{\setboxz@h{%
832 \A@=\X@c \advance\A@-\L@c \B@=\Y@c \advance\B@\U@c
833 \setboxz@h{$\m@th\bracelu$}\dimen@=2\wdz@
834 \ifdim\R@c<\dimen@ \R@c=\dimen@ \fi
835 \ifdim\L@c<\dimen@ \advance\A@-\dimen@ \advance\A@\L@c \L@c=\dimen@ \fi
836 \dimen@=\L@c \advance\dimen@\R@c
837 \kern\A@\raise\B@\hbox to\dimen@{%
838  $\m@th\braceld\leaders\vrule\hfil\bracerd$}}%
839 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}

The vertical ones are very like braces including the ad hoc correction.

846 \xydef@\lparenthesized{\xy@@{\setboxz@h{%
847 \A@=\X@c \advance\A@-\L@c \B@=\Y@c \advance\B@-\D@c
848 \setboxz@h{$\m@th\bracecr$}\dimen@ii=\dp\z@ \advance\A@-.5\wdz@
849 \setboxz@h{$\m@th\bracec$}\dimen@=\dp\z@
850 \ifdim\U@c<.5\dimen@ \U@c=.5\dimen@ \fi
851 \ifdim\D@c<.5\dimen@ \advance\B@-.5\dimen@ \advance\B@\D@c \D@c=.5\dimen@ \fi
852 \advance\U@c.6\p@ \advance\D@c.6\p@  \advance\B@-.6\p@
853 \dimen@ii\U@c \advance\dimen@ii\D@c
854 \kern\A@\raise\B@\vbox to \dimen@ii{%
855  \nointerlineskip\hbox{$\m@th\braceur$}%
856  \kern-.61\dimen@ \cleaders\copy\z@\vfil \kern-.61\dimen@
857  \nointerlineskip\hbox{$\m@th\bracedr$}\kern\z@}}%
858 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}
860 \xydef@\rparenthesized{\xy@@{\setboxz@h{%
861 \A@=\X@c \advance\A@\R@c \B@=\Y@c \advance\B@-\D@c
862 \setboxz@h{$\m@th\bracecr$}\dimen@ii=\dp\z@ \advance\A@-.5\wdz@
863 \setboxz@h{$\m@th\bracec$}\dimen@=\dp\z@
864 \ifdim\U@c<.5\dimen@ \U@c=.5\dimen@ \fi
865 \ifdim\D@c<.5\dimen@ \advance\B@-.5\dimen@ \advance\B@\D@c \D@c=.5\dimen@ \fi
866 \advance\U@c.6\p@ \advance\D@c.6\p@  \advance\B@-.6\p@
867 \dimen@ii\U@c \advance\dimen@ii\D@c
868 \kern\A@\raise\B@\vbox to \dimen@ii{%
869  \nointerlineskip\hbox{$\m@th\braceul$}%
870  \kern-.61\dimen@ \cleaders\copy\z@\vfil \kern-.61\dimen@
871  \nointerlineskip\hbox{$\m@th\bracedl$}\kern\z@}}%
872 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}

Bug: The brackets above require that the computer modern cmex font is loaded in TEX font position 3.

2.2.3 Filled regions

In addition to the above there is a special frame that “fills” the inside of the current object with ink: \frm {*} and \frm {**}; the latter is intended for emphasizing and thus “strokes” the outline, using the thinnest black line available on the printer or output device; furthermore it moits the actual filling in case this would obscure further text typeset on top. Some alteration to the shape is possible, using *\frm<dimen>{*}. Hence rectangular, oval, circular and elliptical shapes can be specified for filling. The following examples illustrate this in each case:

                      ⟨object⟩ \frm{*}  \frm{**}  \frm<6pt>{*}

However, filling non-rectangular shapes will result in a rectangle unless a driver is used that supports arbitrary filling. With some drivers the above fills will thus all be identical, as rectangular.

When the previous ⟨object⟩ has \rectangleEdge then the shape is either oval or rectangular, depending on whether a ⟨dimen⟩ has been specified, using the ⟨dimen⟩ as radius for the corners, but not exceeding half the shorter side-length.

When the current ⟨object⟩ has \circleEdge then the region is elliptical, using the extents R+L and U+D as the major/minor axes, or circular if a ⟨dimen⟩ is specified. The ⟨dimen⟩ will become the radius after reducing to a maximum of half the longest side of the enclosing rectangle. With \zeroEdge presume rectangular, or circular if a ⟨dimen⟩ is supplied.

The default for \frm{**} is to just make a plain frame.

929 \xydefcsname@{frm{*}}{%
930 \expandafter\frmDrop@\expandafter{%
931 \expandafter\def\expandafter\prevEdge@@\expandafter{\prevEdge@@}%
932 \frame@fill@@\frmradius@@}}
934 \xydefcsname@{frm{**}}{%
935 \expandafter\frmDrop@\expandafter{%
936 \expandafter\def\expandafter\prevEdge@@\expandafter{\prevEdge@@}%
937 \frame@emph@@\frmradius@@}}
939 \xydef@\frame@fill@#1{\filled@{#1}\empty}
940 \xydef@\frame@emph@#1{\framed@\frmradius@@}
942 \xylet@\frame@fill@@=\frame@fill@
943 \xylet@\frame@emph@@=\frame@emph@
945 \xydef@\filled@#1{\R@=#1\relax
946 \expandafter\DNii@\expandafter{\prevEdge@@}%
947 \DN@{\rectangleEdge}\ifx\next@\prevEdge@@
948 \ifdim\R@=\z@ \DN@{\filled@Rectangle@}%
949 \else \DN@{\filled@Oval@}\fi
950 \else \DN@{\circleEdge}\ifx\next@\prevEdge@@
951 \ifdim\R@=\z@ \DN@{\filled@Ellipse@}%
952 \else \DN@{\restR@max\filled@Circle@}\fi
953 \else
954 \ifdim\R@=\z@ \DN@{\filled@Rectangle@}%
955 \else \DN@{\filled@Circle@}\fi
956 \fi\fi \next@}
958 \xydef@\restR@max{%
959 \dimen@=\L@c\advance\dimen@\R@c
960 \dimen@ii=\U@c \advance\dimen@ii\D@c
961 \ifdim\dimen@ii>\dimen@ \dimen@=\dimen@ii\fi
962 \ifdim\dimen@>\z@ \divide\dimen@\tw@
963 \ifdim\R@>\dimen@\R@=\dimen@\fi\fi }

The default implementation uses only \bblacked@, in all cases. The distinction between \frm{*} and \frm{**} can be ignored.

970 \xylet@\filledRectangle@@=\bblacked@
971 \xylet@\filledCircle@@=\bblacked@
972 \xylet@\filledEllipse@@=\bblacked@
973 \xylet@\filledOval@@=\bblacked@

Alternative implementations may use these, in which the parameter #1 is the contents of a \vbox filling to the height, depth and width of the region to be filled.

981 \xydef@\filled@Region@#1#2{\setboxz@h\bgroup
982 \setboxz@h{\vbox{#1#2\empty}}%
983 \A@=\X@c \advance\A@-.5\wd\z@
984 \B@=\Y@c \advance\B@-.5\ht\z@ \advance\B@.5\dp\z@
985 \edef\tmp@{\egroup\dimen@=\the\wdz@}%
986 \kern\A@ \raise\B@\boxz@ \kern-\A@
987 \tmp@ \divide\dimen@\tw@ \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \styledboxz@}
989 \xydef@\filled@Rectangle@{\filled@Region@\filledRectangle@@}
990 \xydef@\filled@Oval@{\filled@Region@\filledOval@@}
991 \xydef@\filled@Circle@{\filled@Region@\filledCircle@@}
992 \xydef@\filled@Ellipse@{\filled@Region@\filledEllipse@@}

2.2.4 Framing as object modifier

In addition, frames may be accessed using the special [F⟨frame⟩] object modifier ⟨shape⟩s that will add the desired ⟨frame⟩ to the current object. The frame appropriate to the edge of the object will be chosen (presently either rectangular or elliptical).

If shape modifiers need to be applied to the ⟨frame⟩ alone then they can be included using : as separator. Thus [F-:red] will make a red frame (provided the color extension is active, of course). Additionally the variant of frames using <⟨dimen⟩> can be accessed by specifying […:<⟨dimen⟩>].

1013 \xydefcsname@{shape [F...]}#1{\xyFN@\Fshape@#1:@}
1015 \xylet@\whichframe@@=\empty
1016 \xylet@\whichoptions@@=\empty
1018 \xydef@\Fshape@#1:{\def\whichframe@@{{#1}}%
1019 \DN@{{}}\ifx\whichframe@@\next@ \def\whichframe@@{{-}}\fi
1020 \expandafter\DN@\expandafter{\the\Edge@c}\DNii@{\circleEdge}\ifx\next@\nextii@
1021 \DN@##1{\def\whichframe@@{[o]##1}}%
1022 \expandafter\next@\expandafter{\whichframe@@}\fi
1023 \let\whichoptions@@=\empty \xyFN@\Fshape@i}
1025 \xydef@\Fshape@i{%
1026 \ifx @\next \let\next@=\Fshape@x
1027 \else\addLT@\ifx\next \let\next@=\Fshape@iii
1028 \else \let\next@=\Fshape@ii \fi\fi \next@}
1030 \xydef@\Fshape@ii#1:{%
1031 \expandafter\def\expandafter\whichoptions@@\expandafter{\whichoptions@@[#1]}%
1032 \xyFN@\Fshape@i}
1034 \xydef@\Fshape@iii#1:{\DN@##1{\def\whichframe@@{#1##1}}%
1035 \expandafter\next@\expandafter{\whichframe@@}\xyFN@\Fshape@i}

1037 \xydef@\Fshape@x @{%
1038 \edef\next@##1{\noexpand\addbeforeDrop@@{{\EdgefromtheEdge@##1}}}%
1039 \DNii@##1##2{\next@{\saveframestyles@{\setbox\z@=\object##2\frm##1%
1040 \xypre@Style@@\Drop@@\xypost@Style@@\restoreframestyles@}}}%
1041 \expandafter\expandafter\expandafter\nextii@
1042 \expandafter\expandafter\expandafter{%
1043 \expandafter\whichframe@@\expandafter}\expandafter{\whichoptions@@}}

The following are used to ensure that the current styles, after typesetting, are those of the ⟨object⟩, rather than the ⟨frame⟩.

1052 \xydef@\saveframestyles@{%
1053 \edef\afterframe@preStyle@{\preXY@style@}%
1054 \edef\afterframe@postStyle@{\postXY@style@}}
1056 \xydef@\restoreframestyles@{%
1057 \xdef\preXY@style@{\afterframe@preStyle@}\def\afterframe@preStyle@{}%
1058 \xdef\postXY@style@{\afterframe@postStyle@}\def\afterframe@postStyle@{}}

Here are some simple examples using this feature.

text with background

bold white on black

\xy *+<1.5pt>[F**:white]++[F**:red]
\txt{text with background}
,+!D+/d1pc/,*++[F**:black][white]
\txt\bf{bold white on black}\endxy

Notice that when multiple frame-modifiers are used, the frames are actually placed in reverse order, so that earlier ones are printed on top of later ones.

To Do: The frame option is not quite complete yet: some new frames and several new brackets should be added.

2.2.5 Using curves for frames

If the curve option is loaded, then circular and elliptical frames of arbitrary radius can be constructed, by specifying \UseCurvedFrames. This can be negated by \UseFontFrames. Both of these commands obey normal TEX grouping. Furthermore, dotted and dashed frames now have a regular spacing of their constituent objects. The usual warnings about memory requirements for large numbers of curves apply here also.

Use the \xycircle setup in xycurve.doc to implement circular and elliptical frames.

1098 \xydef@\xycircleframe@x@{\L@=\R@ \xycircleframe@x@i}%
1099 \xydef@\xyellipseframe@x@#1#2{\R@=#1\relax \L@=#2\relax \xycircleframe@x@i}
1101 \xydef@\xycircleframe@x@i{%
1102 \ifx\framehfill\frm@solidh@@\def\circleSTYLE@{}%
1103 \else\ifx\framehfill\frm@doth@@
1104 \expandafter\def\expandafter\circleSTYLE@\expandafter{\addDOT@{}}%
1105 \else\ifx\framehfill\frm@dashh@@
1106 \expandafter\expandafter\expandafter\def\expandafter\expandafter
1107 \expandafter\circleSTYLE@\expandafter\expandafter\expandafter

1108 {\expandafter\addDASH@\addDASH@{}}%
1109 \fi\fi\fi \xycircleframe@x@x }
1111 \xydef@\xycircleframe@x@x{\hbox{\vbox{\vskip\L@
1112 \hbox to2\R@{\hfill \buildcircle@ \hfill}\vskip\L@ }}}
1114 \xydef@\UseCurveFrames@{%
1115 \let\circled@x@@=\xycircleframe@x@
1116 \let\ellipsed@x@@=\xyellipseframe@x@ }
1117 \def\UseCurveFrames{\xywithoption{curve}{\UseCurveframes@}}%
1119 \xydef@\UseFontFrames@{%
1120 \let\circled@x@@=\circled@x@
1121 \let\ellipsed@x@@=\ellipsed@x@ }
1122 \xylet@\UseFontFrames=\UseFontFrames@

Finally, the frame extension is added to the ⟨driver⟩ system:

1130 \xydef@\UnloadFrames@{%
1131 \let\framed@body@@=\framed@body@
1132 \let\circled@x@@=\circled@x@
1133 \let\ellipsed@x@@=\ellipsed@x@
1134 \let\frame@fill@@=\frame@fill@
1135 \let\frame@emph@@=\frame@emph@
1136 \let\filledRectangle@@=\bblacked@
1137 \let\filledCircle@@=\bblacked@
1138 \let\filledEllipse@@=\bblacked@
1139 \let\filledOval@@=\bblacked@

1140 }

1142 \xyaddunsupport{frame}\UnloadFrames@

End & log

1150 \xyendinput
1152 % $Log: xyframe.doc,v $
1153 % Revision 3.7  1999/02/16 15:12:50  krisrose
1154 % Interim release (Y&Y fonts now free).

1155 %

1156 % Revision 3.6  1998/03/06 01:28:05  krisrose
1157 % Releasing (with Y&Y fonts).

1158 %

1159 % Revision 3.4  1997/05/18 01:14:25  krisrose
1160 % Essential bugfixes.

1161 %

1162 % Revision 3.3  1996/12/19 03:31:56  krisrose
1163 % Maintenance release

1164 %

1165 % Revision 3.2  1995/09/19  18:22:27  kris
1166 % Bug fix release.

1167 %

1168 % Revision 3.1  1995/09/05  20:31:32  kris
1169 % Releasing!

1170 %

1171 % Revision 3.0  1995/07/07  20:14:21  kris
1172 % Major release w/new User's Guide!

1173 %

1174 % Revision 2.14  1995/07/05  22:11:03  kris
1175 % Buglets...

1176 %

1177 % Revision 2.13  1995/07/04  15:11:17  kris
1178 % Ready to release v3?

1179 %

1180 % Revision 2.12  1994/10/25  11:34:25  kris
1181 % Interim release just before v3 [works with AMS-LaTeX 1.2]...

1182 %

1183 % Revision 2.10  1994/06/15  12:55:07  kris
1184 % Second 3beta release: bug fixes.

1185 %

1186 % Revision 2.9  1994/06/09  14:59:19  kris
1187 % Release 3beta.

1188 %

1189 % Revision 2.8  1994/04/08  04:30:00  kris
1190 % Second (bug fix) 3alpha release.

1191 %

1192 % Revision 2.7  1994/03/08  02:06:01  kris
1193 % Release 3alpha.

1194 %

1195 % Revision 2.6.9.1  1994/03/07  04:22:46  kris
1196 % Last internal 3alpha and pre-2.7 release.

1197 %

1198 % NEW for version 2.7 based on frame code in xypic.doc 2.6.1.1.

2.3 More Tips extension

Vers. 3.3 by Kristoffer H. Rose ⟨kris@diku.dk⟩

This extension provides several additional styles of ‘tips’ for use (primarily) as arrow heads, and makes it possible to define customised tips. This is used to support tips that mimic the style of the Computer Modern fonts^{1} by Knuth (see [8] and [6, appendix F]) and of the Euler math fonts distributed by the

AMS.

Header:

1 %% $Id: xytips.doc,v 3.3 1996/12/19 04:12:13 krisrose Exp $
2 %%
3 %% Xy-pic ``More Tips'' extension.
4 %% Copyright (c) 1992-1996  Kristoffer H. Rose  <kris@diku.dk>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% Copyright (c) 1991-1996  Kristoffer H. Rose  <kris@diku.dk>

1This function was earlier supported by the cmtip extension which is still included in the distribution but is now obsolete.

2.3. MORE TIPS EXTENSION 215

8 %%
9 %% The Xy-pic package is free software; you can redistribute it and/or modify
10 %% it under the terms of the GNU General Public License as published by the
11 %% Free Software Foundation; either version 2 of the License, or (at your
12 %% option) any later version.
13 %%
14 %% The Xy-pic package is distributed in the hope that it will be useful, but
15 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 %% for more details.
18 %%
19 %% You should have received a copy of the GNU General Public License along
20 %% with this package; if not, write to the Free Software Foundation, Inc.,
21 %% 675 Mass Ave, Cambridge, MA 02139, USA.
22 %%
23 \ifx\xyloaded\undefined \input xy \fi
25 \xyprovide{tips}{More Tips extension}{\stripRCS$Revision: 3.3 $}%
26 {Kristoffer H.~Rose}{kris@diku.dk}%
27 {BRICS/Computer Science, University of Aarhus, Ny Munkegade, building 540,
28  DK--8000 Aarhus~C}

First save the XY-commands that may need restoring.

48 \xylet@\tip@xy=\tip@
49 \xylet@\atip@xy=\atip@
50 \xylet@\btip@xy=\btip@
52 \xylet@\Tip@xy=\Tip@
53 \xylet@\Ttip@xy=\Ttip@
55 \xylet@\tipjot@xy=\tipjot@

Next declare the fonts (initially the original cm style).

61 \xyfont@\xy@@atfont=xycmat10
62 \xyfont@\xy@@btfont=xycmbt10

Font selection is done with the command

                            \SelectTips {⟨family⟩} {⟨size⟩}

74 \xydef@\tipfamily@@{cm}
75 \xydef@\tipsize@@{10}
77 \xydef@\SelectTips#1#2{%
78 \DN@{#1}\ifx\next@\empty\else \def\tipfamily@@{#1}\fi
79 \DN@{#2}\ifx\next@\empty\else \def\tipsize@@{#2}\fi
80 \csname tipfamily \tipfamily@@\endcsname \ignorespaces}

where the ⟨family⟩ and ⟨size⟩ should be selected from the following table.

                       Family  10         11         12

[figure: xy; −; −; −]
[figure: cm; −; −; −]
[figure: eu; −; −; −]

The table is really encoded in control sequences \tipfamily ⟨family⟩ that look very much alike since all the currently existing combinations are merely alternative fonts. This is likely to change,

however, … ◯_{¨⌣}

First cm, i.e., computer modern: these are simplified by the fact that we can use the normal double arrows.

115 \xydefcsname@{tipfamily cm}{\loadtipfonts@
116 \let\tip@=\tip@cm \let\atip@=\atip@cm \let\btip@=\btip@cm
117 \let\Tip@=\Tip@xy \let\Ttip@=\Ttip@xy \def\tipjot@{.2em}}
119 \xydef@\loadtipfonts@{\edef\next##1##2{##1=xy\tipfamily@@##2\tipsize@@}%
120 \next{\font\xy@@atfont}{at}
121 \next{\font\xy@@btfont}{bt}

122 }

124 \xydef@\tip@cm{\activatetips@ \tip@x\tip@@}
125 \xydef@\atip@cm{\activatetips@ \tip@x\atip@@}
126 \xydef@\btip@cm{\activatetips@ \tip@x\btip@@}
128 \xydef@\activatetips@{\let\xyatipfont=\xy@@atfont \let\xybtipfont=\xy@@btfont}

Next Euler tips: the single tips merely reuse the cm code except for the sligtly smaller distance between double tips; the double arrows have to be recoded to mimic the steeper Euler appearance.

136 \xydefcsname@{tipfamily eu}{\loadtipfonts@
137 \let\tip@=\tip@cm \let\atip@=\atip@cm \let\btip@=\btip@cm
138 \let\Tip@=\Tip@eu \let\Ttip@=\Ttip@eu \def\tipjot@{.15em}}
140 \xydef@\Tip@eu{\kern1.5pt \vrule height1.5pt depth1.5pt width\z@
141 \Tip@@eu \kern1.5pt \egroup
142 \U@c=1.5pt \D@c=1.5pt \L@c=1.5pt \R@c=1.5pt \Edge@c={\circleEdge}%
143 \Invisible@false \Hidden@false \def\Leftness@{.5}\def\Upness@{.5}%
144 \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
146 \xydef@\Tip@@eu{\count@=\DirectionChar
147 \advance\count@-10 \ifnum\count@<\z@ \advance\count@128 \fi
148 \xyatipfont\char\count@
149 \advance\count@ 20 \ifnum127<\count@ \advance\count@-128 \fi
150 \xybtipfont\char\count@}
152 \xydef@\Ttip@eu{\kern2.4pt \vrule height2.4pt depth2.4pt width\z@
153 \Ttip@@eu \kern2.4pt \egroup
154 \U@c=2.4pt \D@c=2.4pt \L@c=2.4pt \R@c=2.4pt \Edge@c={\circleEdge}%
155 \Invisible@false \Hidden@false
156 \def\Leftness@{.5}\def\Upness@{.5}%
157 \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
159 \xydef@\Ttip@@eu{%
160 \setboxz@h\bgroup\reverseDirection@\line@ \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@
161 \kern-\L@c \boxz@ \kern\L@c \Tip@@eu}

Once a selection is made, the following commands are available:

\UseTips activate selected tips
\NoTips deactivate

174 \xydef@\UseTips{\csname tipfamily \tipfamily@@\endcsname}

176 \xydef@\NoTips{\let\tip@=\tip@xy \let\atip@=\atip@xy \let\btip@=\btip@xy
177 \let\Tip@=\Tip@xy \let\Ttip@=\Ttip@xy \let\tipjot@=\tipjot@xy}

They are local and thus can be switched on and/or off for individual pictures using the TEX grouping mechanism, e.g.,

\SelectTips{cm}{10}
\xy*{} \ar
 @{*{\UseTips\dir_{<<}}-*{\NoTips\dir{>}}}
 (20,5)*{} \endxy

will typeset

[figure]

regardless of which tips are used otherwise in the document.

2.3.1 End & log

204 \xyendinput
206 % $Log: xytips.doc,v $
207 % Revision 3.3  1996/12/19 04:12:13  krisrose
208 % New for this maintenance release.

209 %

210 % Generalisation of xycmtip.doc,v 3.1 1995/09/05 20:31:32 kris Exp krisrose

211 %

212 % Revision 3.1  1995/09/05  20:31:32  kris
213 % Releasing!

214 %

215 % Revision 3.0  1995/07/07  20:14:21  kris
216 % Major release w/new User's Guide!

217 %

218 % Revision 2.13  1995/07/04  15:11:17  kris
219 % Ready to release v3?

220 %

221 % Revision 2.12  1994/10/25  11:34:25  kris
222 % Interim release just before v3 [works with AMS-LaTeX 1.2]...

223 %

224 % Revision 2.6  1993/10/21  20:36:09  kris
225 % NEW file to go in version 2.7!

226 %

227 % Extracted from xypic.doc 2.6.1.1.

2.4 Line styles extension

Vers. 3.6 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This extension provides the ability to request various effects related to the appearance of straight lines; e.g.. thickness, non-standard dashing, and colour.

Header:

1 %% $Id: xyline.doc,v 3.6 1998/03/06 01:28:05 krisrose Exp $

2 %%
3 %% Xy-pic ``Line Width'' extension.
4 %% Copyright (c) 1993-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose  <krisrose@ens-lyon.fr>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{line}{Line styles extension}{\stripRCS$Revision: 3.6 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

These are effects which are not normally available within TEX. Instead they require a suitable ‘back-end’ option to provide the necessary \special commands, or extra fonts, together with appropriate commands to implement the effects. Thus

Using this extension will have no effect on the output unless used with a backend that explicitly supports it.

The extension provides special effects that can be used with any XY-pic ⟨object⟩, by defining [⟨shape⟩] modifiers. The modification is local to the ⟨object⟩ currently being built, so will have no effect if this object is never actually used.

Adjusting line thickness The following table lists the modifiers primarily to alter the thickness of lines used by XY-pic. They come in two types — either a single keyword, or using the key-character | with the following text parsed.

[thicker] double line thickness
[thinner] halve line thickness
[|(⟨num⟩)] multiple of usual thickness
[|<⟨dimen⟩>] set thickness to ⟨dimen⟩
[|⟨dimen⟩] also sets to ⟨dimen⟩
[|=⟨word⟩] make [⟨word⟩] set current style settings
[|*]  reuse previous style
[butt]  butt cap at ends

[roundcap] round cap at ends
[projcap] projecting square cap.

Later settings of the linewidth override earlier settings; multiple calls to [thicker] and [thinner] compound, but the other variants set an absolute thickness. The line-thickness specification affects arrow-tips as well as the thickness of straight lines and curves. Three kinds of line-caps are available; they are discussed below in the section on ‘poly-lines’.

\xymatrix{P \ar[r] \ar[r] \ar[r] \ar[r] & C}

\xy/r8pc/:*++\txt\huge{C}="c"
,0*++\txt\huge{P}="p",
,"p",{\ar@*{[|(1)]}"p";"c"<20pt>}
,"p",{\ar@*{[|(4)]}"p";"c"<14pt>}
,"p",{\ar@*{[|(10)]}"p";"c"<4pt>}
,"p",{\ar@*{[|(20)]}"p";"c"<-16pt>}
\endxy

Using the PostScript back-end, the size of the arrow-head grows aesthetically with the thickness of the line used to draw it. This growth varies as the square-root of the thickness; thus for very thick lines (20+ times normal) the arrowhead begins to merge with the stem.

Load the style extension to establish the necessary infra-structure.

113 %\xydefcsname@{shape [|...]}#1{\xyFN@\xywidthchar@#1@@}%
114 \xydefcsname@{*stylechar@|@}#1{\xyFN@\xywidthchar@#1@@}%
116 %\xydefcsname@{shape [thinner]}{\xyshape@thinner@}
117 %\xydefcsname@{shape [thicker]}{\xyshape@thicker@}
118 \xydefcsname@{style [thinner]}{\xyshape@thinner@}
119 \xydefcsname@{style [thicker]}{\xyshape@thicker@}

Implementation Record the line thickness locally in a dimen register. The initial value is read from the xydash10 font. Each time \xylinethick@ is changed, its previous value is stored as the expansion of \xyprevwidth@@, in case this is needed by a specific back-end.

132 \xynew@{dimen}\xylinethick@ \xylinethick@=\xydashw@
134 \xydef@\xyshape@thicker@{\xylinewidth@i{\multiply\xylinethick@\tw@}}
135 \xydef@\xyshape@thinner@{\xylinewidth@i{\divide\xylinethick@\tw@}}
137 \xydef@\xylinewidth@i#1{\edef\xyprevwidth@@{\the\xylinethick@}%
138 #1\edef\next@{\xylinethick@=\the\xylinethick@}%
139 \edef\next@ii{\noexpand\addtotoks@{%
140 \noexpand\xylinewidth@@{\next@}{\xyprevwidth@@}}}%
141 \next@ii }
144 \xydef@\xywidthchar@{%
145 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xywidthchar@}%gobble spaces
146 % \else\ifx @\next \DN@ @@{\addtotoks@{\checkXyStyle@}}%
147 \else\ifx @\next \DN@ @@{\checkXyStyle@}%
148 \else\ifx (\next \DN@ (##1)##2@@{%

149 \xylinewidth@i{\xylinethick@=##1\xydashw@}}%
150 \else\addLT@\ifx \next \addGT@{\addLT@\DN@ ##1}##2@@{%
151 \xylinewidth@i{\xylinethick@=##1\relax}}%
152 % \else\ifx *\next \DN@ *@@{\addtotoks@{\checkXyStyle@}}%
153 % \else\ifx *\next \DN@ *@@{\checkXyStyle@}%
154 \else\ifx *\next \DN@ *@@{\recoverXyStyle@}%
155 % \else\addEQ@\ifx \next \addEQ@\DN@##1@@{%
156 %  \addtotoks@{\checkXyStyle@\xynamestyle@{##1}}}%
157 \else\addEQ@\ifx \next \addEQ@\DN@##1@@{\checkXyStyle@
158 \addtotoks@{\xynamestyle@{##1}}}%
159 \else\ifx C\next \DN@ C##1@@{\xysetlinecap@{##1}@}%
160 \else\ifx J\next \DN@ J##1@@{\xysetlinejoin@{##1}@}%
161 \else\ifx M\next \DN@ M(##1)@@{\xymiterlimit@{##1}@}%
162 \else \DN@##1@@{\xylinewidth@i{\xylinethick@=##1\relax}}%
163 \fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}

The diagram in figure 2.4, page 233, uses different line-thicknesses and colours.

Poly-lines By a ‘poly-line’ we mean a path built from straight line segments having no gaps where each segment abuts the next. The poly-line could be the edges of a polygon, either closed or open if the end-points are different.

The reason for considering a poly-line as a separate ⟨object⟩, rather than simply as a ⟨path⟩ built from straight lines, becomes apparent only when the lines have appreciable thickness. Then there are several standard ways to fashion the ‘joins’ (where segments meet). Also the shape of the ‘caps’ at either end of the poly-line can be altered.

The following modifiers are used to determine the shapes of the line ‘caps’ and ‘joins’:

[|J⟨val⟩]  join style, ⟨val⟩ = 0, 1 or 2
[mitre]  mitre-join, same as [|J0]

               [roundjoin] round join, same as [|J1]

[bevel]  bevel-join, same as [|J2]
[|C⟨val⟩]  end-cap, ⟨val⟩ = 0, 1 or 2
[butt]  “butt” cap, same as [|C0]

               [roundcap] round cap, same as [|C1]

               [projcap]

“projecting square” cap, same as [|C2]

[|M(⟨num⟩)] set mitrelimit to ⟨num⟩≥ 1

These effects are currently implemented only with the PostScript back-end or when using \xypolyline (described below) with a PostScript ⟨driver⟩. In this case the ‘cap’ setting can be applied to any segment, straight or curved, whether part of a poly-line or not; however the ‘join’ setting applies only to poly-lines. Arrow-tips are not affected. The defaults are to use round joins and round-cap ends.

Adjusting the miter-limit affects how far miters are allowed to protrude when two wide lines meet at small angles. The ⟨num⟩ is in units of the line-thickness. Higher values mean using bevels only at smaller angles, while the value of 1 is equivalent to using bevels at all angles. The default miter-limit is 10.

Current values are stored in case these are needed within nested portions of diagrams.

221 \xydef@\xylinecap@{2}
222 \xydef@\xylinejoin@{2}
223 \xydef@\xylinemiter@{10}

2.4. LINE STYLES EXTENSION 221

Recognise keywords for ‘line-caps’ and ‘line-joins’:

251 \xydefcsname@{style [bevel]}{\xyshape@bevel@}
252 \xydefcsname@{style [roundjoin]}{\xyshape@rdjoin@}
253 \xydefcsname@{style [miter]}{\xyshape@miter@}

254 %

255 \xydefcsname@{style [butt]}{\xyshape@butt@}
256 \xydefcsname@{style [roundcap]}{\xyshape@rdcap@}
257 \xydefcsname@{style [projcap]}{\xyshape@projcap@}
261 \xydef@\xyshape@butt@{\xysetlinecap@@0}
262 \xydef@\xyshape@rdcap@{\xysetlinecap@@1}
263 \xydef@\xyshape@projcap@{\xysetlinecap@@2}
265 \xydef@\xyshape@miter@{\xysetlinejoin@@0}
266 \xydef@\xyshape@rdjoin@{\xysetlinejoin@@1}
267 \xydef@\xyshape@bevel@{\xysetlinejoin@@2}
269 \xydef@\xysetlinecap@#1@{\DN@ii{#1}\count@=#1\relax
270 \expandafter\DN@\expandafter{\the\count@}%
271 \ifx\next@\next@ii\else
272 \xywarning@{ignoring extra tokens in line-cap: \next@}\fi
273 \expandafter\xysetlinecap@@\expandafter{\next@}}
275 \xydef@\xysetlinejoin@#1@{\DN@ii{#1}\count@=#1\relax
276 \expandafter\DN@\expandafter{\the\count@}%
277 \ifx\next@\next@ii\else
278 \xywarning@{ignoring extra tokens in line-join: \next@}\fi
279 \expandafter\xysetlinejoin@@\expandafter{\next@}}
281 \xydef@\xysetmiterlimit@#1@{\DN@ii{#1}\dimen@=#1\p@\relax
282 \edef\next@{\expandafter\removePT@\the\dimen@}%
283 \ifx\next@\next@ii\else
284 \xywarning@{ignoring extra tokens in miter-limit: \next@}\fi
285 \expandafter\xysetmiterlimit@@\expandafter{\next@}}

These use the more sophisticated approach that is easier to adjust for different ⟨driver⟩s.

294 \xydef@\xysetlinecap@@#1{\xy@linecap@i{\def\xylinecap@{#1}}}
295 \xydef@\xysetlinejoin@@#1{\xy@linejoin@i{\def\xylinejoin@{#1}}}
296 \xydef@\xysetmiterlimit@@#1{%
297 \xy@linemiter@i{\def\xylinemiter@{#1}}}
299 \xydef@\xy@linecap@i#1{#1\addtotoks@{\xy@linecap@@{#1}}}
300 \xydef@\xy@linejoin@i#1{#1\addtotoks@{\xy@linejoin@{#1}}}
301 \xydef@\xy@linemiter@i#1{#1\addtotoks@{\xy@linemiter@{#1}}}

Implementation of line-caps:

307 \xydef@\xy@linecap@#1{\checkXyStyle@ \edef\xyprevcap@@{\xylinecap@}%
308 #1\let\prexylinecap@=\prexylinecap@@ \let\postxylinecap@=\postxylinecap@@
309 \applyLIFOstyle@\prexylinecap@{\xylinecap@}%
310 \postxylinecap@{\xyprevcap@@}}
312 \xydef@\prexylinecap@@{\let\prexylinecap@=\eat@
313 \let\postxylinecap@=\postxylinecap@@ \outputxylinecap@ }
314 \xydef@\postxylinecap@@{\let\postxylinecap@=\eat@

315 \let\prexylinecap@=\prexylinecap@@ \resetxylinecap@@ }
316 \xylet@\prexylinecap@=\prexylinecap@@
317 \xylet@\postxylinecap@=\postxylinecap@@
319 \xydef@\outputxylinecap@#1{\xycapSpecial@@{#1}}
320 \xydef@\resetxylinecap@#1{\resetxylinecap@i{#1}\outputxylinecap@{#1}}
321 \xydef@\resetxylinecap@i#1{\def\xylinecap@{#1}}
322 \xylet@\resetxylinecap@@=\resetxylinecap@
324 \xylet@\xycapSpecial@@=\eat@

Implementation of line-joins:

330 \xydef@\xy@linejoin@#1{\checkXyStyle@
331 \edef\xyprevjoin@@{\xylinejoin@}#1%
332 \let\prexylinejoin@=\prexylinejoin@@
333 \let\postxylinejoin@=\postxylinejoin@@
334 \applyLIFOstyle@\prexylinejoin@{\xylinejoin@}%
335 \postxylinecap@{\xyprevjoin@@}}
337 \xydef@\prexylinejoin@@{\let\prexylinejoin@=\eat@
338 \let\postxylinejoin@=\postxylinejoin@@ \outputxylinejoin@ }
339 \xydef@\postxylinejoin@@{\let\postxylinejoin@=\eat@
340 \let\prexylinejoin@=\prexylinejoin@@ \resetxylinejoin@@ }
341 \xylet@\prexylinejoin@=\prexylinejoin@@
342 \xylet@\postxylinejoin@=\postxylinejoin@@
344 \xydef@\outputxylinejoin@#1{\xyjoinSpecial@@{#1}}
345 \xydef@\resetxylinejoin@#1{\resetxylinejoin@i{#1}\outputxylinejoin@{#1}}
346 \xydef@\resetxylinejoin@i#1{\def\xylinejoin@{#1}}
347 \xylet@\resetxylinejoin@@=\resetxylinejoin@
349 \xylet@\xyjoinSpecial@@=\eat@

Implementation of miter-limit:

355 \xydef@\xy@linemiter@#1{\checkXyStyle@
356 \edef\xyprevmiter@@{\xylinemiter@}#1%
357 \let\prexylinemiter@=\prexylinemiter@@
358 \let\postxylinemiter@=\postxylinemiter@@
359 \applyLIFOstyle@\prexylinemiter@{\xylinemiter@}%
360 \postxylinecap@{\xyprevmiter@@}}
362 \xydef@\prexylinemiter@@{\let\prexylinemiter@=\eat@
363 \let\postxylinemiter@=\postxylinemiter@@ \outputxylinemiter@ }
364 \xydef@\postxylinemiter@@{\let\postxylinemiter@=\eat@
365 \let\prexylinemiter@=\prexylinemiter@@ \resetxylinemiter@@ }
366 \xylet@\prexylinemiter@=\prexylinemiter@@
367 \xylet@\postxylinemiter@=\postxylinemiter@@
369 \xydef@\outputxylinemiter@#1{\xymiterSpecial@@{#1}}
370 \xydef@\resetxylinemiter@#1{\resetxylinemiter@i{#1}\outputxylinemiter@{#1}}
371 \xydef@\resetxylinemiter@i#1{\def\xylinemiter@{#1}}
372 \xylet@\resetxylinemiter@@=\resetxylinemiter@
374 \xylet@\xymiterSpecial@@=\eat@

The path taken by the ‘poly-line’ this is read as the list of ⟨pos⟩itions in the current ‘stack’, ignoring size extents. The macro \xypolyline is used as a ⟨decor⟩; it reads the ⟨pos⟩itions from the stack, but leaves the stack intact for later use.

Implementation of ‘poly-lines’.

389 \xydef@\xypolyline#1{\xypolyline@{#1}}
391 \xydef@\xypolyline@#1{\hbox\bgroup
392 \enter@{\pfromthep@ \basefromthebase@ \cfromthec@}%
393 \def\xyps@list{}\edef\smapp@@{\s@bot}%
394 \smapxy@i{\enter@{\pfromthep@ \basefromthebase@ }%
395  \edef\xyps@list{\expandafter\removePT@\the\X@c\space
396  \expandafter\removePT@\the\Y@c\space \xyps@list}\leave@}%
397 \leave@ \xy@polystyle@@{#1}\xydopoly@style\egroup
398 \def\Drop@@{\styledboxz@}\def\Connect@@{\styledboxz@}}%

The following diagram illustrates the use of line-thickness, line-joins and line-caps with poly-lines. It contains an example of each of the styles.

A  B

\xycompileto{poly}%
{/r4pc/:,*[|<5pt>][thicker]\xybox{%
 *+(3,2){}="X"
;@={p+CU,p+LU,p+LD,p+RD,p+RU,p+CU}
 ,{0*[miter]\xypolyline{}}
 ,{\xypolyline{*}},@i@)
,"X",*+(2.5,1.5){}="X"
,@={!CU,!LU,!LD,!RD,!RU,!CU}
 ,{0*[gray][roundjoin]\xypolyline{}}
 ,{0*[gray]\xypolyline{*}},@i@)
,"X",*+(2,1){}="X"
,@={!CU,!LU,!LD,!RD,!RU,!CU}
 ,{0*[white]\xypolyline{*}}
 ,{0*[bevel]\xypolyline{}},@i@)
,"X"-(.7,0)*++\txt\LARGE{A}="a"
,"X"+(.7,0)*++\txt\LARGE{B}="b"
,{\ar@{-}@*{[butt][thinner]}"a";"b"<1pc>}
,{\ar@{-}@*{[roundcap][thinner]}"a";"b"}
,{\ar@{-}@*{[projcap][thinner]}"a";"b"<-1pc>}
}}

Note the use of {0*[...]\xypolyline{..}} to apply style-modifiers to a polyline. The @={!..} method for loading the stack gives equivalent results to using ;@={p+..}, since \xypolyline ignores the edge extents of each ⟨pos⟩ in the stack.

Note also that the argument #1 to \xypolyline affects what is typeset. Allowable arguments are:

             \xypolyline{}  solid line

             \xypolyline{.} dotted line
             \xypolyline{-} dashed line

\xypolyline{*} fill enclosed polygon
\xypolyline{?} fill enclosed polygon using even-odd rule

             \xypolyline{{*}} use \dir{*} for lines
             \xypolyline{<toks>} using \dir{<toks>}

The latter cases one has **\dir{...} being used to connect the vertices of the polyline, with {{*}} being needed to get **\dir{*}. Similarly **\dir is used when a ⟨driver⟩ is not available to specifically support polylines; in particular the two ‘fill’ options * and ? will result in a dotted polygon outline the region intended to be filled.

In all cases it is up to the user to load the stack before calling \xypolyline{… }. A particularly common case is the outline of an existing XY-pic ⟨object⟩, as in the example above. Future extensions to \frm will provide a simplified mechanism whereby the user need not call \xypolyline explicitly for such effects.

464 \xylet@\xypolyline@Special=\eat@
465 \xylet@\xypolyfill@Special=\eat@
466 \xylet@\xypolyeofill@Special=\eat@
467 \xylet@\xypolydot@Special=\eat@
468 \xylet@\xypolydash@Special=\eat@
470 \xydef@\UnloadpolySpecials@{%
471 \let\xypolyline@Special=\eat@
472 \let\xypolyfill@Special=\eat@
473 \let\xypolyeofill@Special=\eat@
474 \let\xypolydot@Special=\eat@
475 \let\xypolydash@Special=\eat@

476 }

478 \xydef@\xy@polystyle@#1{%
479 \let\poly@style@@=\xypolyline@Special
480 \DNii@{#1}\ifx\nextii@\empty
481 \else\DN@{*}\ifx\next@\nextii@ \let\poly@style@@=\xypolyfill@Special
482 \else\DN@{?}\ifx\next@\nextii@ \let\poly@style@@=\xypolyeofill@Special
483 \else\expandafter\DN@\expandafter{\addDOT@{}}\ifx\next@\nextii@
484 \let\poly@style@@=\xypolydot@Special
485 \else\expandafter\DN@\expandafter{\addDASH@{}}\ifx\next@\nextii@
486 \let\poly@style@@=\xypolydash@Special
487 \else\DN@{{*}}\ifx\next@\nextii@ \def\poly@style@@{\xypolystraight@{*}}%
488 \else \def\poly@style@@{\xypolystraight@{#1}}%
489 \fi\fi\fi\fi\fi\fi }
491 \xydef@\xydopoly@style{\expandafter\poly@style@@\expandafter{\xyps@list}}
492 \xydef@\xynopolystyle@#1#2{\xyundefinedLine@{polyline}{{#1}}@@}

When there is no special support this handles the various cases using ordinary thin line types.

501 \xydef@\xypolynospec@#1{\DNii@{#1}%
502 \ifx\nextii@\empty\def\poly@style@@{\xypolystraight@{-}}%
503 \else\DN@{.}\ifx\next@\nextii@ \def\poly@style@@{\xypolystraight@{.}}%
504 \else\DN@{-}\ifx\next@\nextii@ \def\poly@style@@{\xypolystraight@{--}}%
505 \else\DN@{*}\ifx\next@\nextii@ \def\poly@style@@{\xypolystraight@{.}}%
506 \else\DN@{?}\ifx\next@\nextii@ \def\poly@style@@{\xypolystraight@{.}}%

507 \else\DN@{{*}}\ifx\next@\nextii@ \def\poly@style@@{\xypolystraight@{*}}%
508 \else \def\poly@style@@{\xypolystraight@{#1}}%
509 \fi\fi\fi\fi\fi\fi }

Gobble the collected positions in {\xyps@list}; recover the vertices from the stack, then set straight lines in the appropriate style.

516 \xydef@\xypolystraight@#1#2{%
517 \enter@{\pfromthep@ \basefromthebase@ \cfromthec@}%
518 \edef\smapp@@{\s@bot}\csname S@0\endcsname\czeroEdge@\pfromc@\def\smapp@@{0}%
519 \smapxy@i{\czeroEdge@\enter@{\pfromthec@}{\connect@\dir{#1}}\leave@}\leave@ }

Initially poly-lines are uninstalled, until loaded by a ⟨driver⟩.

527 \xylet@\xy@polystyle@@=\xypolynospec@
529 \xydef@\UninstallPolylines@{%
530 \UnloadpolySpecials@
531 \let\xy@polystyle@@=\xypolynospec@ }
532 \UninstallPolylines@

Installation Initially there is no support for the actual effects.

541 \xydef@\xyundefinedLine@#1#2@@{%
542 \xywarning@{The #1 #2 effect is not implemented with the current driver.}}%
544 \xydef@\xynolinewidth@#1#2{%
545 \xyundefinedLine@{linewidth}{\the\xylinethick@}@@}%
546 \xydef@\xynolinecap@#1{\xyundefinedLine@{linecap}{\xylinecap@}@@}%
547 \xydef@\xynolinejoin@#1{\xyundefinedLine@{linejoin}{\xylinejoin@}@@}%
548 \xydef@\xynolinemiter@#1{\xyundefinedLine@{miterlimit}{\xylinemiter@}@@}%

Nothing further can be done unless allowed by a specific ⟨driver⟩, which must establish an alternative expansions to be bound to \xylinewidth@@ and the other hooks.

556 \xylet@\xylinewidth@@=\xynolinewidth@
557 \xylet@\xy@linecap@@=\xynolinecap@
558 \xylet@\xy@linejoin@@=\xynolinejoin@
559 \xylet@\xy@linemiter@@=\xynolinemiter@
561 \xydef@\UnloadLine@#1{%
562 \ifx#1\relax\else\xyunload@{line width extension}\fi
563 \let\resetxyline@@=\resetxyline@
564 \let\resetxylinecap@@=\resetxylinecap@
565 \let\resetxylinejoin@@=\resetxylinejoin@
566 \let\resetxylinemiter@@=\resetxylinemiter@
567 \let\transxyline@@=\DN@
568 \let\xylineSpecial@@=\eat@
569 \let\xycapSpecial@@=\eat@
570 \let\xyjoinSpecial@@=\eat@
571 \let\xymiterSpecial@@=\eat@
572 \let\xylinewidth@@=\xynolinewidth@
573 \let\xy@linecap@@=\xynolinecap@
574 \let\xy@linejoin@@=\xynolinejoin@
575 \let\xy@linemiter@@=\xynolinemiter@

576 \UninstallPolylines@ }
578 \xyaddunsupport{line}{\UnloadLine@\relax}

This is a possible alternative for \xylinewidth@@. Indeed it is used with the PostScript support, which then redefines just \xylineSpecial@@.

587 \xydef@\xylinewidth@#1#2{\checkXyStyle@
588 #1\let\prexyline@=\prexyline@@ \let\postxyline@=\postxyline@@
589 \applyLIFOstyle@\prexyline@{\the\xylinethick@}\postxyline@{#2}}
590 \xydef@\prexyline@@{\let\prexyline@=\eat@
591 \let\postxyline@=\postxyline@@ \outputxyline@ }
592 \xydef@\postxyline@@{\let\postxyline@=\eat@
593 \let\prexyline@=\prexyline@@ \resetxyline@@ }
594 \xylet@\prexyline@=\prexyline@@
595 \xylet@\postxyline@=\postxyline@@
597 \xydef@\resetxyline@#1{\resetxyline@i{#1}\outputxyline@{#1}}
598 \xydef@\resetxyline@i#1{\xylinethick@=#1\relax}
599 \xydef@\outputxyline@#1{\transxyline@@{#1}%
600 \expandafter\xylineSpecial@@\expandafter{\next@}}
601 \xylet@\resetxyline@@=\resetxyline@

These need to be rebound by a back-end which supports variation in the line-thickness.

608 \xydef@\transxyline@#1{\edef\next@{\removePT@#1}}
610 \xylet@\transxyline@@=\DN@
611 \xylet@\xylineSpecial@@=\eat@

The end & Log

619 \xyendinput
621 % $Log: xyline.doc,v $
622 % Revision 3.6  1998/03/06 01:28:05  krisrose
623 % Releasing (with Y&Y fonts).

624 %

625 % Revision 3.3  1996/12/18  09:22:29  ross
626 % adjustments for styles now within the kernel code
627 % fixed problem with line-widths

628 %

629 % Revision 3.2  1995/09/19  18:21:41  ross
630 % Bug fix release.

631 %

632 % Revision 3.1  1995/09/05  20:36:33  ross
633 % Release!

634 %

635 % Revision 3.0  1995/07/07  20:13:19  ross
636 % Major release w/new User's Guide!

637 %

638 % Revision 2.13  1995/07/04  15:04:51  ross
639 % Ready for release of v3.

640 %

641 % Revision 2.12  1994/10/25  03:01:14  ross

2.5. ROTATE AND SCALE EXTENSION 227

642 % Final 3beta release [bug fixes & AMS-LaTeX fitting].

643 %

644 % Revision 2.11  1994/07/05  09:27:49  ross
645 % fixed documentation bug

646 %

647 % Revision 2.10  1994/06/15  12:46:03  ross
648 % Second release 3beta.
649 % Colour and line style saving works; label colouring bug fixed.

650 %

651 % Revision 2.9  1994/06/09  14:39:49  ross
652 % Release 3beta.

653 %

654 % NEW for version 2.9 by Ross Moore.

2.5 Rotate and Scale extension

Vers. 3.3 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This extension provides the ability to request that any object be displayed rotated at any angle as well as scaled in various ways. Header:

1 %% $Id: xyrotate.doc,v 3.3 1996/12/18 09:40:16 ross Exp $
2 %%
3 %% Xy-pic ``Rotate and Scale extension'' option.
4 %% Copyright (c) 1993-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{rotate}{Rotate and Scale extension}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%

28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

These are effects which are not normally available within TEX. Instead they require a suitable ‘back-end’ option to provide the necessary \special commands, or extra fonts, together with appropriate commands to implement the effects. Thus

Using this extension will have no effect on the output unless used with a backend that explicitly supports it.

53 \xydef@\xyundefinedRotate@#1#2@@{%\egroup %
54 \xywarning@{The #1 #2 effect is not implemented with the current driver.}}%

The extension provides special effects that can be used with any XY-pic ⟨object⟩ by defining [⟨shape⟩] modifiers. The modification is local to the ⟨object⟩ currently being built, so will have no effect if this object is never actually used.

The following table lists the modifiers that have so far been defined. They come in two types – either a single keyword, or a key-character with the following text treated as a single argument.

[@]  align with current direction
[@⟨direction⟩]  align to ⟨direction⟩
[@!⟨number⟩]  rotate ⟨number⟩ degrees
[*⟨number⟩]  scale by ⟨number⟩
[*⟨num⟩_{x},⟨num⟩_{y}] scale x and y separately
[left]  rotate anticlockwise by 90^{∘}
[right]  rotate (clockwise) by 90^{∘}
[flip]  rotate by 180^{∘}; same as [*-1,-1]
[dblsize]  scale to double size
[halfsize]  scale to half size

These [⟨shape⟩] modifiers specify transformations of the ⟨object⟩ currently being built. If the object has a rectangle edge then the size of the rectangle is transformed to enclose the transformed object; with a circle edge the radius is altered appropriately.

To Do: There should be an [@*] form which repeats the set of transformations applied to the last object which has been transformed, possibly in an earlier diagram. Also an [@=⟨word⟩] form allowing a set of transformations to be saved and used later, simply by specifying [⟨word⟩].

Each successive transformation acts upon the result of all previous. One consequence of this is that the order of the shape modifiers can make a significant difference in appearance—in general, transformations do not commute. Even successive rotations can give different sized rectangles if taken in the reverse order.

Sometimes this change of size is not desirable. The following commands are provided to modify this behaviour.

\NoResizing prevents size adjustment
\UseResizing restores size adjustments

120 \xydef@\NoResizing{\xyNoResizing@}
121 \xydef@\UseResizing{\xyUseResizing@}
123 \xydef@\xyNoResizing@{%
124 \global\let\origxyrescale@=\xyrescale@

125 \global\let\origxyrotSizeMod@=\xyrotateSizeMod@
126 \global\let\xyNoResizing@=\xyNoResizing@@
127 \global\let\xyUseResizing@=\xyUseResizing@@
128 \xyNoResizing@@ }
130 \xydef@\xyNoResizing@@{%
131 \global\let\xyrescale@=\xyignorescale@
132 \global\let\xyrotateSizeMod@=\xyignoreSizeMod@

133 }

135 \xylet@\xyUseResizing@=\relax
136 \xydef@\xyUseResizing@@{%
137 \global\let\xyrescale@=\origxyrescale@
138 \global\let\xyrotateSizeMod@=\origxyrotSizeMod@

139 }

The \NoResizing command is also useful to have at the beginning of a document being typeset using a driver that cannot support scaling effects, in particular when applied to whole diagrams. In any case an unscaled version will result, but now the spacing and positioning will be appropriate to the unscaled rather than the scaled size.

Interface Recognize the ⟨shape⟩ characters and keywords.

158 \xydefcsname@{shape [@...]}#1{\xyrotatechar@#1@@}%
159 \xydefcsname@{shape [<...]}#1{\xyshearchar@{#1}@@}%
160 \xydefcsname@{shape [*...]}#1{\xyscalechar@{#1}@@}%
162 \xydefcsname@{shape [left]}{\xyshape@left@}
163 \xydefcsname@{shape [right]}{\xyshape@right@}
164 \xydefcsname@{shape [flip]}{\xyshape@flip@}
165 \xydefcsname@{shape [halfsize]}{\xyshape@halfsize@}
166 \xydefcsname@{shape [dblsize]}{\xyshape@dblsize@}
167 \xydefcsname@{shape [vflip]}{\xyshape@vflip@}
168 \xydefcsname@{shape [hflip]}{\xyshape@hflip@}

Each style modifier adds code to one, or both, of two global lists. These contents of these lists, called \preXYtransform@@ and \postXYtransform@@. An implementation must define macros which are to be bound to the control sequence names \preXYtransform@ and \postXYtransform@, which are prepended and appended to the \Drop@@ and Connect@@ methods for the current ⟨object⟩.

Also \Drop@@ and \Connect@@ must be modified, if this has not already been done as indicated

by \xy@transform@ having expansion \relax.

185 \xydef@\preXYtransform@{}
186 \xydef@\postXYtransform@{}
188 \xywarnifdefined\preXYtransform@@
189 \xywarnifdefined\postXYtransform@@
190 \gdef\preXYtransform@@{}
191 \gdef\postXYtransform@@{}
192 \xydef@\xy@transform@{}
193 \xydef@\preShape@@{}
194 \xydef@\postShape@@{}

The transformations must be implemented by emulating the adjoint coordinate transformations. This requires that code be added to preXYtransform@@ in reverse order to the order of occurrence of the ⟨shape⟩ modifiers. The code is added to \postXYtransform@@ in natural order, so that each addition to \preXYtransform@@ can be closed off, if necessary, in a correctly nested sequence.

205 \xydef@\modXYtransform@{%
206 \ifx\xy@transform@\empty
207 \transformDrop@\transformConnect@\resetTransform@\fi
208 %\show\preShape@@
209 \DN@##1{\expandafter\def\expandafter\tmp@\expandafter{##1}}%
210 \expandafter\next@\expandafter{\preShape@@}%
211 \DN@##1{\expandafter\gdef\expandafter\preXYtransform@@\expandafter{%
212  \tmp@ ##1}}\expandafter\next@\expandafter{\preXYtransform@@}%
213 \DN@##1{\expandafter\def\expandafter\tmp@\expandafter{##1}}%
214 \expandafter\next@\expandafter{\postShape@@}%
215 \DN@##1{\expandafter\gdef\expandafter\postXYtransform@@\expandafter{%
216  \postXYtransform@@ ##1}}\expandafter\next@\expandafter{\tmp@}}%
218 \xydef@\transformDrop@{\let\xy@transform@=\relax
219 \expandafter\def\expandafter\Drop@@\expandafter{%
220 \expandafter\preXYtransform@\Drop@@\postXYtransform@}}
222 \xydef@\transformConnect@{\let\xy@transform@=\relax
223 \expandafter\def\expandafter\Connect@@\expandafter{%
224 \expandafter\preXYtransform@\Connect@@\postXYtransform@}}
226 \xydef@\resetTransform@{\gdef\preXYtransform@@{}\gdef\postXYtransform@@{}}

Bug: The reference point does not move correctly in PostScript when a shift modifier has been applied before a rotation. The object prints outside of its bounding \rectangleEdge. Fix this!!

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.

Saving transformations Once specified for an ⟨object⟩, the collection of transformations can be assigned a name, via [>⟨name⟩]. The ⟨name⟩ here is any collection of letters or other characters up to the closing ]. Subsequent use of [>⟨name⟩], with the same or other ⟨objects⟩s, will re-establish the saved transformations, acting on the new ⟨object⟩ with initial reference point appropriate to this ⟨object⟩.

Note: Such namings are global and permanent. They are intended to allow a particular set of transformations to be easily repeated for different objects inside various pictures and diagrams within the same document.

255 \xydef@\xynametransform@#1{%
256 \DN@{\expandafter\gdef\expandafter#1\expandafter{\the\toks@}}\next@ }

Scaling and Scaled Text The ⟨shape⟩ modifier can contain either a single scale factor, or a pair indicating different factors in the x- and y-directions. Negative values are allowed, to obtain reflections in the coordinate axes, but not zero.

269 \xydef@\xyscalechar@#1@@{\xyscalechars@#1,#1,@@}
271 \xydef@\xyscalechars@#1,#2,#3@@{%
272 \DN@{\xyrescale@(#1,#2)}%
273 \dimen@=#1\p@
274 \ifdim\dimen@>\z@ \else \ifdim\dimen@<\z@ \else
275 \DN@{\xywarning@{invalid scaling factors #1, #2}}%

276 \fi\fi  \dimen@=#2\p@
277 \ifdim\dimen@>\z@ \else \ifdim\dimen@<\z@ \else
278 \DN@{\xywarning@{invalid scaling factors #1, #2 }}%
279 \fi\fi \next@ }
281 \xydef@\xyrescale@(#1,#2){%
282 \setboxz@h{\xyscale@@{#1}{#2}%
283 \dimen@=\ifx-#1\R@c\advance\dimen@-\R@c \dimen@=-\dimen@
284 \else#1\L@c \advance\dimen@-\L@c\fi
285 \kern\dimen@\boxz@\kern-\dimen@}%
286 \R@c=\if-#1\L@c\else#1\R@c\fi
287 \L@c=\if-#1\R@c\else#1\L@c\fi
288 \U@c=\if-#2\D@c\else#2\U@c\fi
289 \D@c=\if-#2\U@c\else#2\D@c\fi }
291 \xydef@\xyignorescale@(#1,#2){\xywarning@{Ignoring rescale: #1,#2}%
292 \setboxz@h{\xyscale@@{#1}{#2}\boxz@}}%

Some particular scalings.

300 \xydef@\xyshape@halfsize@{\xyrescale@(.5,.5)}
301 \xydef@\xyshape@dblsize@{\xyrescale@(2,2)}
302 \xydef@\xyshape@flip@{\xyrescale@(-1,-1)}
303 \xydef@\xyshape@vflip@{\xyrescale@(1,-1)}
304 \xydef@\xyshape@hflip@{\xyrescale@(-1,1)}

Rotation and Rotated Text Within [@...] the ... are parsed as a ⟨direction⟩ locally, based on the current direction. The value of count register \Direction contains the information to determine the requested direction. When no ⟨direction⟩ is parsed then [@] requests a rotation to align with the current direction.

The special sequence [@!...] is provided to pass an angle directly to the back-end. The XY-pic size and shape of the ⟨object⟩ with \rectangleEdge is unchanged, even though the printed form may appear rotated. This is a feature that must be implemented specially by the back-end. For example, using the PostScript back-end, [@!45] will show the object rotated by 45^{∘} inside a box of the size of the unrotated object.

325 \xydef@\xyrotatechar@{\bgroup
326 \afterDIRECTIONorEMPTY{\xyrotateSizeMod@}{\xyFN@\xySpecialRotate@i}}
328 \xydef@\xySpecialRotate@i{%
329 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xySpecialRotate@i}%
330 \else\ifx @\next \let\next@=\xyrotateSizeMod@
331 \else\addEQ@\ifx \next
332 \addEQ@\DN@##1@@{%\transformDrop@
333  \expandafter\xynametransform@\csname shape [##1]\endcsname\egroup}%
334 \else\ifx !\next \DN@!{\egroup\getSpecialRotate@}%
335 \else\ifx *\next \DN@*@@{\egroup\transformDrop@}%
336 \else \DN@{\xySpecialRotate@@}%
337 \fi\fi\fi\fi\fi \next@ }
339 \xydef@\getSpecialRotate@{\doSpecialRotate@@}

To Do: Provide example of repeated, named transformation.

Installation Initially there is no support for the actual effects. They will be processed according to size/shape requirements, but the actual rotation or re-sizing is ommitted. A ⟨driver⟩ file is required to implement the effects. It need to define alternative expansions to which \xyRotate@@#1,

\xySpecialRotate@@#1@@, \doSpecialRotate@@#1@@ and \xyscale@@#1#2 can be bound.

357 \xydef@\xyRotate@#1{\xyundefinedRotate@{rotate}{#1}@@}
358 \xydef@\xySpecialRotate@#1@@{\xyundefinedRotate@{rotate}{#1}@@\egroup}
359 \xydef@\doSpecialRotate@#1@@{\xyundefinedRotate@{special rotate}{#1}@@}
360 \xydef@\xyscale@#1#2{\xyundefinedRotate@{scale}{#1,#2}@@}
362 \xydef@\UnloadRotate@#1{%
363 \ifx#1\relax\else\xyunload@{rotation extension}\fi
364 \let\xyRotate@@=\xyRotate@
365 \let\xySpecialRotate@@=\xySpecialRotate@
366 \let\doSpecialRotate@@=\doSpecialRotate@
367 \let\xyscale@@=\xyscale@ }
369 \UnloadRotate@\relax
371 \xyaddunsupport{rotate}{\UnloadRotate@\relax}

This adjusts the sizes of \L@c, \R@c, \U@c and \D@c appropriately.

379 \xydef@\xyrotateSizeMod@ @@{%
380 \L@p=\L@c \R@p=\R@c \U@p=\U@c \D@p=\D@c
381 \ifdim\cosDirection\p@>\z@
382 \R@c=\cosDirection\R@p  \L@c=\cosDirection\L@p
383 \U@c=\cosDirection\U@p  \D@c=\cosDirection\D@p
384 \else
385 \R@c=\cosDirection\L@p  \L@c=\cosDirection\R@p
386 \U@c=\cosDirection\D@p  \D@c=\cosDirection\U@p
387 \fi
388 \advance\L@c \if-\sinDirection\D@p\else\sinDirection\U@p\fi
389 \advance\R@c \if-\sinDirection\U@p\else\sinDirection\D@p\fi
390 \advance\U@c \if-\sinDirection\L@p\else\sinDirection\R@p\fi
391 \advance\D@c \if-\sinDirection\R@p\else\sinDirection\L@p\fi
392 \dimen@ii=\L@c \advance\dimen@ii-\L@p
393 \edef\tmp@{\egroup \L@c=\the\L@c \R@c=\the\R@c \U@c=\the\U@c \D@c=\the\D@c
394 \dimen@ii=\the\dimen@ii \noexpand\setboxz@h\bgroup
395 \noexpand\xyRotate@@{\the\Direction}}\tmp@
396 \xydropRotated@ }
398 \xydef@\xydropRotated@@{%
399 \kern\dimen@ii \boxz@ \kern-\dimen@ii \modXYtransform@ \egroup }
400 \xylet@\xydropRotated@=\xydropRotated@@
402 \xydef@\xyignoreSizeMod@ @@{\xywarning@{Ignoring rotation}}

Some particular rotations.

408 \xydef@\xyshape@left@{\xyrotatechar@ v(0,1)@@}
409 \xydef@\xyshape@right@{\xyrotatechar@ v(0,-1)@@}

Reflections Reflections can be specified by a combination of rotation and a flip — either [hflip]

or [vflip].

[figure: A; B; ♡; ♣; label 1; .; label 2; ×; label 3; label 4; label 5; ×; label 6; label 7; label 8; special effect: aligned text]

Figure 2.4: Rotations, scalings and flips

424 \xydef@\xyshearchar@{\xyundefinedRotate@{shearing}}

Shear transformations To Do: Provide the structure to support these; then implement it in PostScript.

The following diagram requires various options to be loaded and installed.

Example The diagram in figure 2.4 illustrates many of the effects described above as well as some additional ones defined by the color and rotate extensions.

Exercise 2.7: Suggest the code used by the author to typeset 2.4.

The actual code is given in the solution to the exercise. Use it as a test of the capabilities of your DVI-driver. The labels should fit snugly inside the accompanying rectangles, rotated and flipped appropriately.

Bug: This figure also uses colours, alters line-thickness and includes some PostScript drawing. The colours may print as shades of gray, with the line from A to B being thicker than normal. The wider band sloping downwards may have different width and length according to the DVI-driver used; this depends on the coordinate system used by the driver, when ‘raw’ PostScript code is included.

The end & Log

497 \xyendinput
499 % $Log: xyrotate.doc,v $
500 % Revision 3.3  1996/12/18  09:40:16  ross
501 % no changes

502 %

503 % Revision 3.2  1995/09/19 18:21:41  ross
504 % Bug fix release.

505 %

506 % Revision 3.1  1995/09/05  20:36:33  ross
507 % Release!

508 %

509 % Revision 3.0  1995/07/07  20:13:19  ross
510 % Major release w/new User's Guide!

234 CHAPTER 2. EXTENSIONS

512 % Revision 2.13  1995/07/04  15:04:51  ross
513 % Ready for release of v3.

514 %

515 % Revision 2.12  1994/10/25  03:01:14  ross
516 % Final 3beta release [bug fixes & AMS-LaTeX fitting].

517 %

518 % Revision 2.11  1994/07/05  06:38:37  ross
519 % some documentation was left out previously

520 %

521 % Revision 2.10  1994/06/15  12:46:03  ross
522 % Second release 3beta.
523 % Colour and line style saving works; label colouring bug fixed.

524 %

525 % Revision 2.9  1994/06/09  14:39:49  ross
526 % Release 3beta.

527 %

528 % NEW file to go in version 2.9 by Ross Moore.

2.6 Colour extension

Vers. 3.3 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This extension provides the ability to request that any object be displayed in a particular colour.

It requires a suitable ‘driver’ option to provide the necessary \special commands to implement the effects. Thus

Using this extension will have no effect on the output unless used with a dvi-driver that explicitly supports it.

Header:

1 %% $Id: xycolor.doc,v 3.3 1996/12/19 03:50:08 ross Exp $
2 %%
3 %% Xy-pic ``Colour extension'' option.
4 %% Copyright (c) 1993-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%

20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{color}{Colour extension}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

All effects defined in the color extension can be implemented using most PostScript ⟨driver⟩s, and some non-PostScript ones, loaded using \xyoption{xyps}. This file provides ‘generic’ code which is known to work correctly with most drivers. For driver-specific variations, consult the appropriate ⟨driver⟩ file.

Colours are specified as a ⟨shape⟩ modifier which gives the name of the colour requested. It is applied to the whole of the current ⟨object⟩ whether this be text, an XY-pic line, curve or arrow-tip, or a composite object such as a matrix or the complete picture. However some DVI drivers may not be able to support the colour in all of these cases.

[⟨colour name⟩]  use named colour
\newxycolor{⟨name⟩}{⟨code⟩} define colour

         \UseCrayolaColors  load colour names

If the DVI-driver cannot support colour then a request for colour only produces a warning message in the log file. After two such messages subsequent requests are ignored completely.

77 \xydef@\xycolorwarning@@{\xycolormessage@
78 \gdef\xycolorwarning@{\xycolormessage@
79  \xywarning@{...no further colour warnings will be given.}%
80 \global\let\xycolorwarning@=\relax }}
81 \xylet@\xycolorwarning@=\xycolorwarning@@
83 \xydef@\xycolormessage@{%
84  \xywarning@{Current driver does not support colour.}}%

There are two methods, perhaps used simultaneously, for handling requests for colour. The \xylocalColor@ is the normal method, colouring whatever objects TEX typesets from fonts. The more specialized \xycolor@ is used with the PostScript back-end. This is necessary since some ⟨driver⟩s assume that the current colour should be ‘black’ when the contents of a \special is interpreted, e.g. within PostScript.

Thus a ⟨driver⟩ which supports both colour and PostScript must define a method to handle \xylocalColor@ but should leave alone \xycolor@. The latter method will be adjusted appropriately when a PostScript ⟨driver⟩ is installed.

101 \xydef@\xyNoColor@#1{}
102 \xylet@\xycolor@@=\xyNoColor@
103 \xydef@\xyNoColor@@#1#2{\xycolorwarning@}
105 \xydef@\xycolor@{\xycolor@@}
106 \xylet@\xylocalColor@=\xyNoColor@@
108 \xydef@\UnloadColor@{%
109 \let\xylocalColor@=\xyNoColor@@
110 % \let\xycolor@=\xyNoColor@

111 \let\xycolor@@=\xyNoColor@
112 \let\xycolorwarning@=\xycolorwarning@@ }
113 \xylet@\UnloadColor@@=\UnloadColor@
115 \xyaddunsupport{color}{\UnloadColor@@\relax}

This next macro is to inherit a default colour from the surrounding document, perhaps using one already defined by L^{A}TEX 2ε

122 \ifx\current@color\undefined \xydef@\xybasecolor@{}%
123 \else \def\xybasecolor@{\current@color}\fi
125 %\xydef@\xycmath@{\hbox\bgroup\dimen@=.55ex \checkxycolor@ \xyinside@}
126 %\xydef@\xycnomath@{\hbox\bgroup\dimen@=\z@ \checkxycolor@ \xyinside@}
128 %\xydef@\checkxycolor@{\ifx\xybasecolor@\empty\else
129 % \expandafter\imposexycolor@\fi}
130 %\xydef@\imposexycolor@{\xylocalColor@}

A commonly used method is to maintain a colour-stack. The following commands are for use with such a setup, however they should only be called from code installed from a ⟨driver⟩-file. Different

drivers may do things differently; e.g. dvips uses a single \special via: \def\xycolor@push@@#1{\special{color push #1}},
but Textures uses two: \xydef@\xycolor@push#1{\special{color push}\special{color #1}}.

Since the colour-stack idea was proposed by Tomas Rokicki,the dvips method is the default behaviour.

143 \xydef@\xystackcolor@{\bgroup \DN@##1##2{\egroup}%
144 \ifInvisible@\else\ifHidden@\else\DNii@{\no@@}\ifx\nextii@\Connect@@
145 \else\DN@{\xystackcolor@i}\fi\fi\fi \next@ }
147 \xydef@\xystackcolor@i#1#2{\checkXyStyle@
148 \DN@{#2}\ifx\next@\empty
149 \def\tmp@##1{\DN@{\xycolor@push{#1}##1\xycolor@pop}}%
150 \else\def\tmp@##1{\DN@{\xycolor@push{#2 #1}##1\xycolor@pop}}\fi
151 \toks@={\egroup \let\xy@style@=\relax \def\Drop@@}%
152 \expandafter\tmp@\expandafter{\Drop@@}%
153 \expandafter\addtotoks@\expandafter{\expandafter{\next@}\def\Connect@@}%
154 \expandafter\tmp@\expandafter{\Connect@@}%
155 \expandafter\addtotoks@\expandafter{\expandafter{\next@}}%
156 \the\toks@ }%
158 \xydef@\xycolor@push@@#1{\special{color push #1}}
159 \xydef@\xycolor@pop{\special{color pop}}
160 \xylet@\xycolor@push=\xycolor@push@@

Named colours and colour models New colour names are created with \newxycolor, taking two arguments. Firstly a name for the colour is given, followed by the code which will ultimately be passed to the output device in order to specify the colour. If the current driver cannot support colour, or grayscale shading, then the new name will be recognised, but ignored during typesetting.

174 \xydef@\newxycolor#1#2{\newxyColor{#1}{}{}{#2}{}}
175 \xydef@\newxyColor#1#2#3#4{\newxycolor@{#1}{#2}{#3}{#4}{}}

For PostScript devices, the XY-ps PostScript dictionary defines operators rgb, cmyk and gray corresponding to the standard RGB and CMYK colour models and grayscale shadings. Colours and shades are described as: r g b rgb or c m y k cmyk or s gray, where the parameters are numbers in the range 0 ≤ r, g, b, c, m, y, k, s ≤ 1. The operators link to the built-in colour models or, in the case of cmyk for earlier versions of PostScript, give a simple emulation in terms of the RGB model.

Existing color names can be overridden using \newxycolor@#1#2\relax.

193 \xydef@\newxycolor@#1#2#3#4#5{%
194 \expandafter\let\expandafter\next@\csname shape [#1]\endcsname
195 \ifx\next@\relax
196 \DN@{#4}\ifx\next@\empty
197  \DN@{#2}\ifx\next@\empty
198  \DN@{\newxystyle{#1}{\xylocalColor@{}{#3}\xycolor@{#3}}}%
199  \else
200  \DN@{\newxystyle{#1}{\xylocalColor@{#2}{#3}\xycolor@{#2 #3}}}%
201  \fi
202 \else\DN@{#2#3}\ifx\next@\empty
203  \DN@{\newxystyle{#1}{\xylocalColor@{#4}{}\xycolor@{#4}}}%
204  \else
205  \DN@{\newxystyle{#1}{\xylocalColor@{#2}{#3}\xycolor@{#4}}}%
206 \fi \fi
207 \else \def\tmp@{\relax}\DNii@{#5}%
208 \ifx\nextii@\tmp@
209 \DN@{#4}\ifx\next@\empty
210  \DN@{#2}\ifx\next@\empty
211  \DN@{\newxystyle{#1}{\xylocalColor@{}{#3}\xycolor@{#3}}}%
212  \else
213  \DN@{\newxystyle{#1}{\xylocalColor@{#2}{#3}\xycolor@{#2 #3}}}%
214  \fi
215 \else
216  \DN@{#2#3}\ifx\next@\empty
217  \DN@{\newxystyle{#1}{\xylocalColor@{#4}{}\xycolor@{#4}}}%
218  \else
219  \DN@{\newxystyle{#1}{\xylocalColor@{#2}{#3}\xycolor@{#4}}}%
220 \fi \fi
221 \else\DN@{}\fi\fi \next@\relax}

Standard colour names which are defined automatically correspond to the three primaries red, green, blue and their complements cyan, magenta, yellow as well as three extreme grayscale shades

black, white, gray.

230 \xydef@\xystandardcolors@{%
231 % \newxycolor@{black}{1.}{gray}{}\relax  % Textures reverses gray-scales
232 % \newxycolor@{white}{0.}{gray}{}\relax  %
233 % \newxycolor@{black}{0.}{gray}{}\relax  % This is normal for PostScript
234 % \newxycolor@{white}{1.}{gray}{}\relax  %
235 \newxycolor@{black}{0. 0. 0.}{rgb}{}\relax   % avoid the hassles.
236 \newxycolor@{white}{1. 1. 1.}{rgb}{}\relax   %
237 \newxycolor@{gray}{.5}{gray}{}\relax
238 \newxycolor@{grey}{.5}{gray}{}\relax
239 \newxycolor@{red}{1. 0. 0.}{rgb}{}\relax
240 \newxycolor@{green}{0. 1. 0.}{rgb}{}\relax
241 \newxycolor@{blue}{0. 0. 1.}{rgb}{}\relax
242 \newxycolor@{cyan}{0. 1. 1.}{rgb}{}\relax
243 \newxycolor@{magenta}{1. 0. 1.}{rgb}{}\relax

244 \newxycolor@{yellow}{1. 1. 0.}{rgb}{}\relax
245 \xyuncatcodes }

Note: The driver file must call \xystandardcolors@ before these colours become accessible. This is to allow any ⟨driver⟩-specific definitions to be active when these colours are defined.

Saving colour and styles When styles are saved using [=⟨word⟩], see , then the current colour setting (if any) is saved also. Subsequent use of [⟨word⟩] recovers the colour and accompanying line-style settings.

Further colour names are defined by the command \UseCrayolaColours that loads the crayon option, in which more colours are defined. Consult the file xyps-col.doc for the colours and their specifications in the RGB or CMYK models.

269 \xydef@\UseCrayolaColors{\xyrequire{crayon}\xyuncatcodes}%
270 % \xyinputorelse@{xyps-col}{\xyerror@{Could not load xyps-col}{}}}

xycrayon.doc:

This option provides the command to install definitions for the 68 colours recognised by name by Tomas Rokicki’s dvips driver [11]. This command must be called from a ⟨driver⟩-file which can actually support the colours.

1 %% $Id: xycrayon.doc,v 3.3 1996/12/18 08:58:16 ross Exp $
2 %%
3 %% Xy-pic ``Crayola colours'' PostScript backend support.
4 %% Copyright (c) 1995-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{crayon}{Crayola Colours}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

The colour definitions themselves are in the file xyps-col.tex. They are not loaded directly here since it is not known which ⟨driver⟩ is to be used. Different ⟨driver⟩s may redefine the \xynewcolor@ macro to set the colour by name or colour-model.

46 \xydef@\installCrayolaColors@{%
47 \xyinputorelse@{xyps-col}{\xyerror@{Could not load Crayola colours}{}}%
48 \let\installCrayolaColors@=\relax
49 \xyuncatcodes }
55 \xyendinput
57 % $Log: xycrayon.doc,v $
58 % Revision 3.3  1996/12/18  08:58:16  ross
59 % cosmetic updates

60 %

61 % Revision 3.1  1995/09/05  20:36:33  ross
62 % Release!

63 %

64 % Revision 3.0  1995/07/07  20:13:19  ross
65 % Major release w/new User's Guide!

66 %

67 % Revision 2.13  1995/07/05  07:58:43  ross
68 % Ready for v3 release?

69 %
70 #

71 % NEW for version 3.1 by Ross Moore  1995/03/18.

72 %

PostScript colour When PostScript driver support is available, the method for handling colour within diagrams may be different. The reason for this is that some dvi-drivers reset the colour to black before placing the contents of the \special. To counter this, the PostScript code maintains its own colour-stack. Support is established within a separate file xyps-c.tex, loaded from the appropriate ⟨driver⟩-files.

295 \xydef@\xyBEcolorcheck@{\ifx\xycolor@@\xyNoColor@\else
296 \xywarning@{PostScript colour support should be OK.}\fi }%
298 \xywithoption{ps}{%
299 \xyinputorelse@{xyps-c}{\xyerror@{Could not load xyps-c}{}}}%
300 \xycatcodes

The end & Log

308 \xyendinput
310 % $Log: xycolor.doc,v $
311 % Revision 3.3  1996/12/19 03:50:08  ross
312 % Maintenance release.

313 %

314 % Revision 3.3  1996/12/18  08:56:49  ross
315 % minor updates

317 % Revision 3.2  1995/09/19  18:20:20  ross
318 % Bug fix release.

319 %

320 % Revision 3.1  1995/09/05  20:36:33  ross
321 % Release!

322 %

323 % Revision 3.0  1995/07/07  20:13:19  ross
324 % Major release w/new User's Guide!

325 %

326 % Revision 2.14  1995/07/06  02:56:02  kris
327 % Buglets...

328 %

329 % Revision 2.13  1995/07/04  15:04:51  ross
330 % Ready for release of v3.

331 %

332 % Revision 2.10  1994/06/15  12:46:03  ross
333 % Second release 3beta.
334 % Colour and line style saving works; label colouring bug fixed.

335 %

336 % Revision 2.9  1994/06/09  14:39:49  ross
337 % Release 3beta.

338 %

339 % NEW for version 2.9 by by Ross Moore.

2.7 Pattern and Tile extension

Vers. 3.4 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This extension provides the ability to request that a filled region be tiled using a particular pattern.

This is an effect not normally available within TEX. Instead it requires a suitable ⟨driver⟩ option to provide the necessary \special commands, together with any extra commands needed to implement the effects. Thus

Using this extension will have no effect on the output unless used with a dvi-driver that explicitly supports it.

All effects defined in the tile extension can be implemented using most PostScript ⟨driver⟩s, loaded

as \xyoption{⟨driver⟩}.

Header:

1 %% $Id: xytile.doc,v 3.4 1997/05/18 01:13:24 ross Exp $
2 %%
3 %% Xy-pic ``Pattern and Tile extension'' option.
4 %% Copyright (c) 1993-1997 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997 Kristoffer H. Rose <krisrose@brics.dk>
9 %%

10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{tile}{Pattern and Tile extension}{\stripRCS$Revision: 3.4 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

Like using color, tiling with patterns is an instance of a special style, since use of a pattern has no effect on the size or shape of the ⟨object⟩ being typeset. It only affects how the ⟨object⟩ will appear on the printed page or on-screen.

mac01 mac02 mac03 mac04 mac05 mac06 mac07 mac08 mac09 mac10 mac11 mac12 mac13 mac14 mac15 mac16 mac17 mac18 mac19 mac20 mac21 mac22 mac23 mac24 mac25 mac26 mac27 mac28 mac29 mac30 mac31 mac32 mac33 mac34 mac35 mac36 mac37 mac38

Figure 2.5: The 38 standard Macintosh patterns.

Patterns Patterns are specified as a ⟨shape⟩ modifier, similar to the way colours are specified by name. The pattern is applied to the whole of the current ⟨object⟩ whether this be text, an XY-pic line, curve or arrow-tip, or a composite object such as a matrix or the complete picture. However some DVI-drivers may not support use of patterns in all cases.

If the current DVI-driver cannot support patterns then a request for one simply produces a warning message in the log file. After two such messages subsequent requests are ignored completely.

100 \xydef@\xypatternwarning@@{\xypatternmessage@

101 \gdef\xypatternwarning@{\xypatternmessage@
102 \xywarning@{...no further pattern warnings will be given.}%
103 \global\let\xypatternwarning@=\relax }}
104 \xylet@\xypatternwarning@=\xypatternwarning@@
106 \xydef@\xypatternmessage@{%
107 \xywarning@{Current driver does not support patterns.}}%

This allows new patterns to be specified from raw data. Make sure the usual catcodes are in place before the data is tokenised.

114 \xydef@\newxypattern{\begingroup\xycatcodes\newxypattern@i}
115 \xydef@\newxypattern@i#1#2{\edef\next@{\endgroup
116 \noexpand\newxyPattern{#1}{}{#2}{}}\next@}
117 \xydef@\newxyPattern#1#2#3#4{\newxypattern@{#1}{#2}{#3}{#4}{}}

Existing pattern names can be overridden using \newxypattern@#1#2\relax.

123 \xydef@\newxypattern@#1#2#3#4#5{%
124 \expandafter\let\expandafter\next@\csname shape [#1]\endcsname
125 \ifx\next@\relax
126 \DN@{#4}\ifx\next@\empty
127  \DN@{#2}\ifx\next@\empty
128  \DN@{\newxystyle{#1}{\xylocalpattern@{}{#3}\xypattern@{#3}}}%
129  \else
130  \DN@{\newxystyle{#1}{\xylocalpattern@{#2}{#3}\xypattern@{#2 #3}}}%
131  \fi
132 \else\DN@{#2#3}\ifx\next@\empty
133  \DN@{\newxystyle{#1}{\xylocalpattern@{#4}{}\xypattern@{#4}}}%
134  \else
135  \DN@{\newxystyle{#1}{\xylocalpattern@{#2}{#3}\xypattern@{#4}}}%
136 \fi\fi
137 \else \def\tmp@{\relax}\DNii@{#5}%
138 \ifx\nextii@\tmp@
139 \DN@{#4}\ifx\next@\empty
140  \DN@{#2}\ifx\next@\empty
141  \DN@{\newxystyle{#1}{\xylocalpattern@{}{#3}\xypattern@{#3}}}%
142  \else
143  \DN@{\newxystyle{#1}{\xylocalpattern@{#2}{#3}\xypattern@{#2 #3}}}%
144  \fi
145 \else
146  \DN@{#2#3}\ifx\next@\empty
147  \DN@{\newxystyle{#1}{\xylocalpattern@{#4}{}\xypattern@{#4}}}%
148  \else
149  \DN@{\newxystyle{#1}{\xylocalpattern@{#2}{#3}\xypattern@{#4}}}%
150 \fi\fi
151 \else\DN@{}\fi\fi \next@\relax }

[⟨name⟩] use named pattern

                 \newxypattern{⟨name⟩}{⟨data⟩}

specify new pattern using ⟨data⟩

                 \UsePatternFile{⟨file⟩}

sets default file for patterns

                 \LoadAllPatterns{⟨file⟩}

load all patterns in ⟨file⟩

                 \LoadPattern{⟨name⟩}{⟨file⟩}

load named pattern from ⟨file⟩

                 \AliasPattern{⟨alias⟩}{⟨name⟩}{⟨file⟩}

let ⟨alias⟩ denote pattern from ⟨file⟩.

Although pattern data may be specified directly using \newxypattern, it is more usual to load it from a ⟨file⟩ in which many patterns are defined by name, each on a separate line. By convention such files always end in .xyp (XY-pattern) so no extension should be specified. The pattern is then requested using either the name supplied in the file or by an alias. Once \UsePatternFile has been used, then a null ⟨file⟩ argument to the other commands will still find patterns in the default file. The default remains in effect for the current level of TEX grouping.

For example, the following picture

uses ‘filled’ frames from the frame feature:

\AliasPattern{bricks}{mac12}{xymacpat}
\AliasPattern{bars}{mac08}{xymacpat}
\xy *+<5pc,3.1pc>{},{*[bricks]\frm{**}}
 ,*+<2.5pc>[o]{},*[bars]\frm{**}
\endxy

There are two methods, perhaps used simultaneously, for handling requests for a pattern. The \xylocalpattern@ is the normal method, patterning whatever objects TEX typesets from fonts or rules. The more specialized \xypattern@ is used with a PostScript ⟨driver⟩.

Thus a ⟨driver⟩ which supports both pattern and PostScript must define a method to handle \xylocalpattern@ but should leave alone \xypattern@. The latter method will be adjusted appropriately when a PostScript ⟨driver⟩ is installed.

208 \xydef@\xyNopattern@#1{}
209 \xylet@\xypattern@@=\xyNopattern@
210 \xydef@\xyNopattern@@#1#2{\xypatternwarning@}
212 \xylet@\xypattern@=\xypattern@@
213 \xylet@\xylocalpattern@=\xyNopattern@@

This is to facilitate unloading patterns when the ⟨driver⟩ is changed to one that does not support this feature. This is the default state, until an appropriate ⟨driver⟩ is loaded.

221 \xydef@\Unloadpattern@{%
222 \let\xylocalpattern@=\xyNopattern@@
223 \let\xypattern@=\xyNopattern@
224 \let\xypatternwarning@=\xypatternwarning@@ }
226 \Unloadpattern@

Pattern data A region is tiled using copies of a single ‘cell’ regularly placed so as to seamlessly tile the entire region. The ⟨data⟩ appearing as an argument to \newxypattern is ultimately passed to the dvi-driver.

The simplest form of pattern data is: ⟨num⟩ ⟨Hex-data⟩, where the data is a 16-character string of Hexadecimal digits; i.e. 0–9, A–F. Each Hex-digit equates to 4 binary bits, so this data contains 64 bits representing pixels in an 8 × 8 array. The ⟨num⟩ is an integer counting the number of ‘0’s among the 64 bits. Taken as a fraction of 64, this number or its complement, represents the average density of ‘on’ pixels within a single cell of the pattern. Drivers unable to provide the fine detail of a pattern may simply use this number, or its complement, as a gray-level or part of a colour specification for the whole region to be tiled.

A desirable set of standard patterns could be specified to be always loaded. If such a set emerges indeed as being frequently desirable then it will be included here.

254 \xydef@\xystandardpatterns@{}%

Note: The driver file must call \xystandardpatterns@ before these patterns become accessible. This is to allow any ⟨driver⟩-specific definitions to be active when these patterns are defined.

264 \xynew@{read}{\xypatread@}
265 \xydef@\defaultpattfile@{}
267 \xydef@\xygetfilepatterns@#1{\DN@{#1}%
268 \ifx\next@\empty
269 \ifx\defaultpattfile@\empty \xywarning@{No pattern file specified.}%
270 \else \DN@{\expandafter\openpattfile@\expandafter{\defaultpattfile@}}\fi
271 \else \DN@{\openpattfile@{#1}}\fi \next@ }
273 \xydef@\openpattfile@#1{\openin\xypatread@=#1.xyp %
274 \ifeof\xypatread@\xywarning@{No patterns in file: #1.xyp}%
275 \closein\xypatread@
276 \else \expandafter \xyreadpatfile@ \fi }%
278 \xydef@\UsePatternFile#1{\def\defaultpattfile@{#1}}
280 \xydef@\LoadAllPatterns{\let\parsepattern@=\parsepattern@@
281 \xygetfilepatterns@ }
283 \xydef@\LoadPattern#1{\let\parsepattern@=\filepattern@@
284 \def\pattname@{#1}\xygetfilepatterns@}
286 \xydef@\AliasPattern#1#2{\let\parsepattern@=\aliaspattern@@
287 \def\aliasname@{#1}\def\pattname@{#2}\xygetfilepatterns@}

The character ! is used to delimit comments within pattern-data files.

294 \xydef@\xyreadpatfile@{%
295 \loop@ \bgroup\xycatcodes
296 \global\read\xypatread@ to\xypatline@
297 \ifeof\xypatread@ \aftergroup\endpatread@
298  \else\aftergroup\morepatread@\fi \edef\next@{%
299 \egroup\noexpand\getxypattern@{\xypatline@!!!}\relax}\next@
300 \repeat@ }
301 \xydef@\endpatread@{\closein\xypatread@\iffalse}
302 \xydef@\morepatread@{\iftrue}
304 %\xydef@\getxypattern@{\futurelet\next\getxypattern@@}
305 \xydef@\getxypattern@#1{\def\next{#1}\getxypattern@@}
306 \xydef@\getxypattern@@{\DN@{!!!}\ifx\next\next@\DN@{}%
307 \else\DN@{\expandafter\parsepattern@\next}\fi \next@ }
309 \xydef@\parsepattern@@#1 #2!#3\relax{\newxypattern{#1}{#2}}

310 \xydef@\filepattern@@#1 #2!#3\relax{\DN@{#1}%
311 \ifx\next@\pattname@
312 \DN@{\expandafter\foundpattern@\expandafter{\pattname@}{#2}}%
313 \else\DN@{}\fi \next@ }
314 \xydef@\foundpattern@#1#2{\newxypattern{#1}{#2}\endpatread@\fi
315 \expandafter\eat@}
316 \xydef@\aliaspattern@@#1 #2!#3\relax{\DN@{#1}%
317 \ifx\next@\pattname@
318 \DN@{\expandafter\foundpattern@\expandafter{\aliasname@}{#2}}%
319 \else\DN@{}\fi \next@ }
321 %\xydef@\parsepattern@#1 #2!#3\relax{\message{#1:#2}}

The file xymacpat.xyp contains defining data for the 38 standard patterns available with the Macintosh Operating system. Figure 2.5 displays all these patterns.

Rotating and Resizing Patterns Some implementations of patterns are sufficiently versatile to allow extra parameters to affect the way the pattern data is interpreted. PostScript is one such implementation in which it is possible to rotate the whole pattern and even to expand or contract the sizes of the basic cell.

Due to the raster nature of output devices, not all such requests can be guaranteed to produce aesthetic results on all devices. In practice only rotations through specific angles (e.g 30^{∘}, 45^{∘}, 60^{∘}) and particular scaling ratios can be reliably used. Thus there is no sophisticated interface provided by XY-pic to access these features. However the ‘PostScript escape’ mechanism does allow a form of access, when a PostScript ⟨driver⟩ is handling pattern requests.

Special PostScript operators pa and pf set the pattern angle (normally 0) and ‘frequency’ measured in cells per inch. Hence, when used as an ⟨object⟩-modifier, [! 30 pa 18.75 pq] rotates the pattern by 30^{∘} clockwise and uses a smaller pattern cell (larger frequency). The default frequency of 12.5 = 300/(8 × 3) means that each pixel in a pattern cell corresponds, on a device of resolution 300dpi, to a 3 × 3 square of device pixels; on such a device 18.75 uses 2 × 2 squares.

At 300dpi a frequency of 9.375 = 300/(8 × 4) uses 4 × 4 squares. These match the natural size for pixels on a 75dpi screen and are pretty close for 72dpi screens. Though appropriate for screen displays, these are ‘too chunky’ for high quality printed work. Doubling the frequency is too fine for some patterns, hence the intermediate choice of 12.5 as default. In order for printed output to match the screen view, a PostScript operator macfreq has been defined to facilitate requests for 9.375, via

[!macfreq].

The next diagram displays changes to the frequency.

filled pattern 9.375  filled pattern 12.5  filled pattern 18.75  filled pattern 37.5 filled pattern 9.375  filled pattern 12.5  filled pattern 18.75  filled pattern 37.5

Saving patterns: When styles are saved using ⟨word⟩], see note 1.4k of §1.4, then the current pattern (if any) is also saved. Subsequent use of [⟨word⟩] recovers the pattern as well as colour and line-style settings. This includes any explicit variations applied using the “Style Escape” mechanism.

Here is a variation of an earlier example, with extra effects.

[figure: Kilroy was here]

\UsePatternFile{xymacpat}
\AliasPattern{bricks}{mac12}{}
\LoadPattern{mac28}{}\LoadPattern{mac05}{}
\xy *=0[! macfreq -45 pa][mac28][|=Bars]{}
,*+<12pc,4pc>{}*[bricks]\frm{**}
,-<3.5pc,0pt>,*+<2.65pc>[o]{},*[Bars]\frm{**}
,*[thicker]\frm{o},+<6pc,0pt>
,*+<5pc, 2.7pc>{},*[mac05]\frm{**},*\frm{-,}
,*[white]\txt\Large\bf\sf{Kilroy\\was here}
\endxy

Add this extension to the driver-tables as “unload”, unless an already-loaded driver can support it:

423 \DN@{\xyaddunsupport{tile}\Unloadpattern@}%
424 \ifx\xyeverywithoption@tile@\undefined
425 \else\ifx\xyeverywithoption@tile@\empty
426 \else
427 \DN@{\xysetup@@{\xywithoption{tile}{\xyeverywithoption@tile@\xydriversloaded@@}}}%
428 \fi\fi \next@

The end & Log

440 \xyendinput
442 % $Log: xytile.doc,v $
443 % Revision 3.4  1997/05/18 01:13:24  ross
444 % Essential bugfixes.

445 %

446 % Revision 3.3  1996/12/18  09:43:06  ross
447 % documentation change

448 %

449 % Revision 3.2  1995/09/19  18:21:41  ross
450 % Bug fix release.

451 %

452 % Revision 3.1  1995/09/05  20:36:33  ross
453 % Release!

454 %

455 % Revision 3.0  1995/07/07  20:13:19  ross
456 % Major release w/new User's Guide!

457 %

458 % Revision 2.13  1995/07/04  15:04:51  ross
459 % Ready for release of v3.

460 %
461 %

462 % NEW for version 3.0 by by Ross Moore.

2.8 Import graphics extension

Vers. 3.6 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This feature provides the ability to easy add labels and annotations to graphics prepared outside TEX or L^{A}TEX. An XY-pic graphics environment is established whose coordinates match that within the contents of the imported graphic, making it easy to specify exactly where a label should be placed, or arrow drawn to highlight a particular feature.

Header:

1 %% $Id: xyimport.doc,v 3.6 1998/03/06 01:28:05 krisrose Exp $
2 %%
3 %% Xy-pic ``Import feature'' option.
4 %% Copyright (c) 1993-1997 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997 Kristoffer H. Rose  <krisrose@ens-lyon.fr>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{import}{Import graphics extension}{\stripRCS$Revision: 3.6 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

A command \xyimport is defined which is used, in conjunction with imported graphics, to establish a coordinate system appropriate to the particular graphics. This enables ⟨pos⟩itions within the graphic to be easily located, either for labelling or adding extra embellishing features. It is used in either of the follow ways:

\xyimport(width,height){⟨graphic⟩}

\xyimport(width,height)(x-off,y-off){⟨graphic⟩}

Normally the ⟨graphics⟩ will be a box containing a graphic imported using the commands from packages such as graphics, epsf or epsfig, or using other commands provided by the local TEX implementation. However the ⟨graphic⟩ could be any balanced TEX material whatsoever; provided it occupies non-zero size, both vertically and horizontally.

   import1.eps

framed contents of graphics file

[figure: import1.eps; Rational points on the elliptic curve: x^{3} + y^{3} = 7; 1; −1; 1; −1; P; −P; −2P; 2P; 3P; −3P; ∞; ∞; ∞]

Figure 2.6: importing a graphic for labelling

The width and height are ⟨number⟩s given in the coordinate system for the contents of the ⟨graphics⟩. These are not dimensions, but coordinate-lengths, using the units appropriate to the picture displayed by ⟨graphic⟩.

When provided, (x-off,y-off) give the distance in coordinate units from bottom-left corner to where the origin of coordinates should be located, usually within area covered by the ⟨graphic⟩. Usually the negatives of these numbers will give the coordinate location of the bottom-left corner of the ⟨graphic⟩. If no offsets are supplied then the origin is presumed to lie at the bottom-left corner.

112 \xydef@\xyimport#1#{\xyimport@{#1}}
113 \xydef@\xyimport@#1#2{\xydelayimport@{#1}{#2}}
114 \xydef@\xydelayimport@#1#2{\xy@@ix@{#1{#2}}%
115 \xy@@{\expandafter\xyextern@\the\toks9}}
117 \xydef@\xyextern@(#1,#2){\hbox\bgroup\R@c=#1\p@ \U@c=#2\p@\xyextern@i}
119 \xydef@\xyextern@i#1#{\DN@{#1}%
120 \ifx\next@\empty \L@c=\z@ \D@c=\z@ \DN@{\xyextern@x}%
121 \else \DN@{\xyextern@ii#1}\fi \next@ }
123 \xydef@\xyextern@ii(#1,#2){\L@c=#1\p@ \D@c=#2\p@
124 \advance\R@c-\L@c \advance\U@c-\D@c \xyextern@x}
126 \xydef@\xyimportdefault@{3}
127 \xydef@\xyexportwarning@#1#2#3{\xywarning@{%
128 #1 for import has zero #2; using \xyimportdefault@#3 default}}
130 \xydef@\xyextern@x#1{\toks@={\egroup\L@c=}\setboxz@h{#1}%
131 \dimen@ii=\L@c \advance\dimen@ii\R@c \dimen@=\wdz@
132 \ifdim\dimen@=\z@ \xyexportwarning@{graphic}{width}{cm}%
133 \dimen@=\xyimportdefault@ cm\fi
134 \ifdim\dimen@ii=\z@ \xyexportwarning@{coords}{width}{unit}%
135 \dimen@ii=\xyimportdefault@\p@\fi

136 \quotient@\next@\dimen@\dimen@ii \dimen@=\next@\p@
137 \edef\tmp@{\expandafter\removePT@\the\L@c}\L@c=\tmp@\dimen@
138 \expandafter\addtotoks@\expandafter{\the\L@c\relax\R@c=}%
139 \edef\tmp@{\expandafter\removePT@\the\R@c}\R@c=\tmp@\dimen@
140 \expandafter\addtotoks@\expandafter{\the\R@c\relax\setbase@\z@\z@}%

141 %

142 \expandafter\addtotoks@\expandafter{\expandafter{\the\dimen@}\z@\D@c=}%
143 \dimen@ii=\U@c \advance\dimen@ii\D@c \dimen@=\ht\z@\advance\dimen@\dp\z@
144 \ifdim\dimen@=\z@ \xyexportwarning@{graphic}{height}{cm}%
145 \dimen@=\xyimportdefault@ cm\fi
146 \ifdim\dimen@ii=\z@ \xyexportwarning@{coords}{height}{unit}%
147 \dimen@ii=\xyimportdefault@\p@\fi
148 \quotient@\next@\dimen@\dimen@ii \dimen@=\next@\p@
149 \edef\tmp@{\expandafter\removePT@\the\D@c}\D@c=\tmp@\dimen@
150 \expandafter\addtotoks@\expandafter{\the\D@c\relax\U@c=}%
151 \edef\tmp@{\expandafter\removePT@\the\U@c}\U@c=\tmp@\dimen@
152 \expandafter\addtotoks@\expandafter{\the\U@c\relax\setbase@@\z@}%
153 \expandafter\addtotoks@\expandafter{\expandafter{\the\dimen@}}%

154 %

155 \setboxz@h{\kern-\L@c\lower\D@c\boxz@\kern\L@c}%
156 \wd\z@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@ \the\toks@ \X@c=\z@ \Y@c=\z@
157 \ifdim\X@min>-\L@c \X@min=-\L@c \fi \ifdim\X@max<\R@c \X@max=\R@c \fi
158 \ifdim\Y@min>-\D@c \Y@min=-\D@c \fi \ifdim\Y@max<\U@c \Y@max=\U@c \fi
159 \idfromc@{import}\POS }

Normally the \xyimport command is used at the beginning of an \xy..\endxy environment. It is not necessary to give any basis setup, for this is deduced by measuring the dimensions of the ⟨graphic⟩ and using the supplied width, height and offsets. The ⟨graphic⟩ itself defines named ⟨pos⟩ called "import", located at the origin and having appropriate extents to describe the area covered by the ⟨graphic⟩. This makes it particularly easy to surround the ⟨graphic⟩ with a frame, as on the left side of figure 2.6, or to draw axes passing through the origin.

Here is the code used to apply the labelling in figure 2.6:

\def\ellipA{\resizebox{6cm}{!}{%
  \includegraphics{import1.eps}}}
\xy
\xyimport(3.7,3.7)(1.4,1.4){\ellipA}*\frm{-}
,!D+<2pc,-1pc>*+!U\txt{%
 framed contents of graphics file}\endxy
\qquad\qquad
\xy\xyimport(3.7,3.7)(1.4,1.4){\ellipA}
,!D+<2pc,-1pc>*+!U\txt{Rational points
 on the elliptic curve: $x^3+y^3=7$}
,(1,0)*+!U{1},(-1,0)*+!U{-1}
,(0,1)*+!R{1},(0,-1)*+!R{-1}
,(2,-1)*+!RU{P},(-1,2)*+!RU{-P}
,(1.3333,1.6667)*+!UR{-2P}
,(1.6667,1.3333)*!DL{\;2P}
,(-.5,1.9)*++!DL{3P},(1.9,-.5)*!DL{\;-3P}
,(-1,2.3)*+++!D{\infty}*=0{},{\ar+(-.2,.2)}
,(.5,2.3)*+++!D{\infty}*=0{},{\ar+(-.2,.2)}

,(2.3,-1)*+++!L{\infty}*=0{},{\ar+(.2,-.2)}
\endxy

This example uses the L^{A}TEX 2ε standard graphics package to import the graphics file import1.eps; other packages could have been used instead. e.g. epsfig, epsf, or the \picture or \illustration commands in Textures on the Macintosh.

The only possible problems that can occur are when the graphics package is loaded after XY-pic has been loaded. Generally it is advisable to have XY-pic loading after all other macro packages.

The end & Log

196 \xyendinput
198 % $Log: xyimport.doc,v $
199 % Revision 3.6  1998/03/06 01:28:05  krisrose
200 % Releasing (with Y&Y fonts).

201 %

202 % Revision 3.4  1997/05/18 01:13:24  ross
203 % Essential bugfixes.

204 %

205 % Revision 3.3  1996/12/18  09:19:22  ross
206 % no changes

207 %

208 % Revision 3.1  1995/09/05 20:36:33  ross
209 % Release!

210 %

211 % Revision 3.0  1995/07/07  20:13:19  ross
212 % Major release w/new User's Guide!

213 %

214 % Revision 2.14  1995/07/05  22:10:51  kris
215 % Buglets...

216 %

217 % Revision 2.13  1995/07/04  15:04:51  ross
218 % Ready for release of v3.

219 %
220 %

221 % NEW for version 3.0 by by Ross Moore.

2.9 Movie Storyboard extension

Vers. 3.5 by Kristoffer H. Rose ⟨krisrose@brics.dk⟩

This extension interprets the \scene primitive of the movie class, setting the progress indicators to dummy values. The following assumes that your are familiar with the movie class.

Header:

1 %% $Id: xymovie.doc,v 3.5 1997/05/28 13:05:01 krisrose Exp $
2 %%
3 %% Xy-pic ``Movie Storyboard extension'' option.
4 %% Copyright (c) 1996-1997 Kristoffer H. Rose <krisrose@brics.dk>

5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{movie}{Movie Storyboard extension}{\stripRCS$Revision: 3.5 $}%
27 {Kristoffer H.~Rose}{krisrose@brics.dk}%
28 {BRICS/Computer Science, University of Aarhus, Ny Munkegade, building 540,
29  DK--8000 Aarhus~C}

The size of the frame is determined by the command

                      \MovieSetup{width=width,height=height,. . . }

(the … indicate the other arguments required by the movie class but silently ignored by the XY-pic movie extension).

Note: This extension still experimental and subject to change. The only documentation is in the movie.cls source file.

The implementation mimics the aspects of the keyval package needed here, namely reading the height and width parameters.

61 \xynew@{dimen}\m@height
62 \xynew@{dimen}\m@width
64 \xydef@\extractparameterm@#1#2#3{%
65 \DN@##1,#1=##2,##3@{\csname m@#1\endcsname=##2\relax}%
66 \next@,#2,#3,@}
68 \xydef@\MovieSetup#1{%
69 \extractparameterm@{height}{#1}{height=2in}%
70 \extractparameterm@{width}{#1}{width=2in}%

71 }

The progress macros all default to

77 \xydef@\theScene{0}
78 \xydef@\theF{0}
79 \xydef@\theFr{1}

80 \xydef@\F#1{#1(0)}
81 \xydef@\Fr#1{#1(1)}

We need to interpret and ignore the arguments to \scene except the * which is used on the last scene since this means that we should output the scene with progress values corresponding to “The End”.

89 \xynew@{if}\iflastframe@
90 \xynew@{count}\m@scene
92 \xydef@\scene{\advance\m@scene\@ne
93 \DN@{\ifx*\next \lastframe@true \DN@*{\xyFN@\scene@}%
94  \else \let\next@=\scene@ \fi \next@}%
95 \xyFN@\next@}
97 \xydef@\scene@{%
98 \ifx[\next \DN@[##1]{\scene@i}\else \let\next@=\scene@i \fi \next@}
100 \long\def\scene@i#1{{%

101 %

102 \def\caption##1{\gdef\m@caption{Scene \the\m@scene. ##1}}%
103 \edef\theScene{\the\m@scene}%
104 \def\theF{0}\def\theFr{1}%
105 \def\F##1{##1(0)}\def\Fr##1{##1(1)}%
106 \scene@frame{#1}%

107 %

108 \iflastframe@
109  \def\caption##1{}%
110  \gdef\m@caption{The End.}%
111  \def\theF{1}\def\theFr{0}%
112  \def\F##1{##1(1)}\def\Fr##1{##1(0)}%
113  \scene@frame{#1}%
114 \fi
115 }\ignorespaces}
117 \def\scene@frame#1{\vbox{\null
118 \dimen@=\m@width \advance\dimen@2\xydashw@
119 \hrule width\dimen@
120 \hbox to\dimen@{\vrule width\xydashw@ \hss
121  \vbox to\m@height{\hsize=\m@width \null\vfil{#1}\vfil\null}%
122  \hss \vrule width\xydashw@}%
123 \hrule width\dimen@
124 \setbox0=\hbox{%
125  \setbox0=\hbox to\m@width{\hss\strut \m@caption\hss}%
126  \dimen0=\dp0 \ht0=0pt \dp0=0pt \raise\dimen0\box0}%
127 \ht0=0pt \dp0=0pt \box0\relax
128 \null}}

The end & Log

134 \xyendinput
136 % $Log: xymovie.doc,v $
137 % Revision 3.5  1997/05/28 13:05:01  krisrose

138 % Fixed missing breaks bug.

139 %

140 % Revision 3.4  1997/05/18 02:37:17  krisrose
141 % Fits movie.cls 3.4...still experimental.

142 %

143 % Revision 1.1  1997/05/18 01:22:10  krisrose
144 % Initial revision

145 %

146 % NEW for version 3.4.

2.10 PostScript backend

Vers. 3.7 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

XY-ps is a ‘back-end’ which provides XY-pic with the ability to produce DVI files that use PostScript \specials for drawing rather than the XY-pic fonts.

In particular this makes it possible to print XY-pic DVI files on systems which do not have the ability to load the special fonts. The penalty is that the generated DVI files will only function with one particular DVI driver program. Hence whenever XY-ps is activated it will warn the user:

XY-pic Warning: The produced DVI file is not portable: It contains PostScript \specials for ⟨one particular⟩ driver

A more complete discussion of the pros and cons of using this backend is included below.

Header:

1 %% $Id: xyps.doc,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %%
3 %% Xy-pic ``PostScript backend''.
4 %% Copyright (c) 1993-1997 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%

24 %% As a special exception, you may use this file and all files derived
25 %% from it without restrictions.  This special exception was added with
26 %% version 3.7 of Xy-pic.
27 %%
28 \ifx\xyloaded\undefined \input xy \fi
30 \xyprovide{ps}{PostScript backend}{\stripRCS$Revision: 3.7 $}%
31 {Ross Moore}{ross@mpce.mq.edu.au}%
32 {Mathematics Department, Macquarie University, NSW~2109, Australia}

2.10.1 Choosing the DVI-driver

Including \xyoption{ps} within the document preamble, tells XY-pic that the PostScript alternative to the fonts should be used, provided the means to do this is also specified. This is done by also specifying a dvi-driver which is capable of recognising and interpreting \special commands. Although the file xyps.tex is read when the option request is encountered, the macros contained therein will have no effect until an appropriate driver has also been loaded.

With L^{A}TEX 2ε both the backend and driver may be specified, along with other options, via a single \usepackage command, see [4, page 317]; e.g.

                      \usepackage[ps,textures,color,arrow]{xy}

The rebindings necessary to support PostScript are not effected until the \begin{document} command is encountered. This means that an alternative driver may be selected, by another \xyoption{⟨driver⟩}, at any time until the \begin{document}. Only the macros relevant to last named ⟨driver⟩ will actually be installed.

The following table describes available support for PostScript drivers. Please consult the individual driver sections in part ?? for the exact current list. For each ⟨driver⟩ there is a corresponding file named xy⟨driver⟩.tex which defines the necessary macros, as well as a documentation file named xy⟨driver⟩.doc. The spelling is all lower-case, designed to be both descriptive and unique for the 1st 8 characters of the file names.

⟨driver⟩  Description
dvips  Tomas Rokicki’s dvips

dvips  Karl Berry’s dvipsk

dvips  Thomas Kiffe’s dvips for Macintosh
textures  Blue Sky Research’s Textures v1.7+
16textures Blue Sky Research’s Textures v1.6
oztex  Andrew Trevorrow’s OzTEX v1.8+
17oztex  Andrew Trevorrow’s OzTEX v1.7

Other DVI-drivers may also work using one of these files, if they use conventions similar to dvips, OzTEX or Textures. Alternatively it should not be too difficult to write the files required, using these as a basis indicating the type of information needed to support the specific \special commands. Anyone attempting to do this should inform the author and convey a successful implementation to him for inclusion within the XY-pic distribution.

Note: In some previous versions of XY-pic the PostScript backend and driver were loaded simultaneously by a command of the form \UsePSspecials{⟨driver⟩}. For backward-compatibility these commands should still work, but now loading the latest version of the given ⟨driver⟩. However their future use is discouraged in favour of the option-loading mechanism, via \xyoption{⟨driver⟩}.

This latter mechanism is more flexible, both in handling upgrades of the actual driver support and in being extensible to support more general forms of \special commands.

Once activated the PostScript backend can be turned off and on again at will, using the user following commands:

\NoPSspecials  cancels PostScript
\UsePSspecials {} restores PostScript

These obey normal TEX scoping rules for environments; hence it is sufficient to specify \NoPSspecials within an environment or grouping. Use of PostScript will be restored upon exiting from the environment.

The default level of PostScript is [4], see below.

171 \xydef@\UsePSspecials{\DNii@{{[4]}}\xyFN@\UsePSspecials@i}
172 \xydef@\UsePSspecials@i{%
173 \ifx \space@\next \expandafter\DN@\space{\xyFN@\UsePSspecials@i}%
174 \else\ifx [\next \DN@[##1]{\DNii@{{[##1]}}\xyFN@\UsePSspecials@i}%
175 \else\ifcat 5\noexpand\next \DN@##1{\DNii@{{[##1]}}\xyFN@\UsePSspecials@i}%
176 \else\ifx\bgroup\next \DN@{\expandafter\UsePS@specials\nextii@}%
177 \else \DN@{\UsePS@specials{[4]}}%
178 \fi\fi\fi\fi \next@ }

To Do: There is redundancy between here and \UsePSspecials@. The value of \setupxyPS@ PostScript level could be set here rather than later in \PSspecials@.

186 \xydef@\UsePS@specials#1#2{%
187 \ifx\empty\whichPSspecials@
188 \DN@{#2}\ifx\next@\empty
189 \else
190  \expandafter\let\expandafter\next\csname#2@\endcsname
191 %   \ifx\next\relax \DN@{\xyerror@{PostScript specials for `#2' not supported}{}}%
192  \ifx\next\relax \DN@{\UsePSspecials@{#2}{}}%
193 %   \else \DN@{\expandafter\UsePSspecials@\csname#2@\endcsname#1}\fi
194  \else \DN@{\UsePSspecials@{#2}{#1}}\fi
195 \fi
196 \else
197 \DN@{#2}\ifx\next@\empty \DN@{\PSspecials@true}%
198 \else
199 %   \edef\next@{\expandafter\string\csname#2@\endcsname}%
200  \DN@{#2}%
201  \edef\nextii@{\expandafter\string\whichPSspecials@}%
202  \ifx\next@\nextii@\DN@{\PSspecials@true}%
203  \else
204  \ifx\firstPS@@\relax
205  \DN@{\xyerror@{Only one PS <driver> allowed: \dvitype@ already loaded}{}}%
206  \else
207  \expandafter\let\expandafter\next\csname#2@\endcsname
208  \ifx\next\relax
209  \DN@{\xyerror@{PostScript specials for `#2' not supported}{}}%
210  \else
211  \xywarning@{Changing PS <driver> to #2 }%
212 %      \DN@{\expandafter\UsePSspecials@\csname#2@\endcsname#1}%

213  \DN@{\UsePSspecials@{#2}{#1}}%
214  \fi
215  \fi
216  \fi
217 \fi
218 \fi \next@}

The following control sequences will also load the corresponding driver. They are retained for backwards compatibility only; they may be phased out of future releases:

          \UseDVIPSspecials      dvips
          \UsePostScriptSpecials dvips
          \UseTexturesPSspecials Textures
          \UseTexturesSpecials   Textures

235 \xydef@\UseDVIPSspecials{\UsePSspecials@\dvips@}
236 \xydef@\UseTexturesPSspecials{\UsePSspecials@\Textures@}
237 \xydef@\UseTexturesSpecials{\UsePSspecials@\Textures@}
238 \xydef@\UsePostScriptSpecials{\UsePSspecials@\dvips@}
239 \xydef@\UseOzTeXspecials{\UsePSspecials@\OzTeX@}
240 \xydef@\UseDVITOPSspecials{\UsePSspecials@\dvitops@}
241 %\xylet@\UseDVIPSSpecials=\UseDVIPSspecials
242 %\xylet@\UsePSspecials=\UsePostScriptSpecials
243 %\xylet@\UseTeXturesPSspecials=\UseTexturesPSspecials
244 %\xylet@\UseTexturesSpecials=\UseTexturesPSspecials
245 %\xylet@\UseTeXturesSpecials=\UseTexturesSpecials
251 \message{drivers,}

First the driver is specified by \UsePSspecials{⟨driver⟩}. This causes a special driver file to be read. Use of fonts is restored at any point by calling \NoPSspecials, after which use of PostScript is re-instated by simply \UsePSspecials, without need of an argument. The commands described above for specific drivers are simply aliases for \UsePSspecials@{⟨driver⟩}.

Once the new bindings have been setup, then the use of \specials is governed by the value of the

conditional \ifPSspecials@.

266 \xydef@\loadPSdriver@#1#2{\xyinputorelse@{xy#1}%
267 {\xyrequire{#2}\expandafter\ifx\csname xy#2loaded\else %
268 {\xyerror@{Unable to load xy#1.tex for #2 driver}{}}\fi}}
270 \xydef@\dvips@{\loadPSdriver@{ps-dvi}{dvips}}
271 \xydef@\Textures@{\loadPSdriver@{ps-txt}{Textures}}
272 \xydef@\OzTeX@{\loadPSdriver@{ps-oz}{OzTeX}}
273 \xydef@\dvitops@{\loadPSdriver@{ps-dto}{dvitops}}
274 \xydef@\dvipsone@{\loadPSdriver@{ps-one}{dvipsone}}
275 %\xydef@\dviwindo@{\loadPSdriver@{ps-wdo}{dviwindo}}
276 %\xydef@\dviwin@{\loadPSdriver@{ps-win}{dviwin}}
277 %\xydef@\pubps@{\loadPSdriver@{ps-pub}{pubps}}

The driver file contains definitions which are specific to the particular driver. Note that some drivers may not be able to support all of the PostScript effects that can be requested from within XY-pic. When an unsupported effect is encountered, it is simply ignored; a warning message will be produced unless too many such messages have already been issued.

288 \global\newif\ifPSspecials@
289 %\xydef@\UsePSspecials@#1{\gdef\whichPSspecials@{#1}\xyFN@\PSspecials@}
290 \xydef@\UsePSspecials@#1{\def\whichPSspecials@{#1}%
291 \DN@{\Textures@}\ifx\next@\whichPSspecials@
292 \DN@##1{\xyrequire{textures}%
293  \def\whichPSspecials@{textures}\xyps@options}%
294 \else\DN@{\dvips@}\ifx\next@\whichPSspecials@
295 \DN@##1{\xyrequire{dvips}%
296  \def\whichPSspecials@{dvips}\xyps@options}%
297 \else\DN@{\OzTeX@}\ifx\next@\whichPSspecials@
298 \DN@##1{\xyrequire{oztex}%
299  \def\whichPSspecials@{oztex}\xyps@options}%
300 \else\DN@{\dvitops@}\ifx\next@\whichPSspecials@
301 \DN@##1{\xyrequire{dvitops}%
302  \def\whichPSspecials@{dvitops}\xyps@options}%
303 \else
304 \DN@##1{\xyrequire{ps}\xyrequire{#1}\xyps@options}%
305 \fi\fi\fi\fi \next@ }
307 \xydef@\xyps@options{%
308 \xyrequire{ps}\xyrequire{line}\xyrequire{color}\xyrequire{crayon}%
309 \xyrequire{rotate}\xyrequire{tile}\xyrequire{frame}\xyuncatcodes }
310 \xydef@\whichPSspecials@{}
312 \xydef@\NoPSspecials{\xyPSwarning@{off}%
313 \PSspecials@false\aftergroup\resetPS@}
314 \xydef@\resetPS@{\ifPSspecials@\xyPSwarning@{back on}\fi}
315 \xydef@\UsePSspecials@x{\PSspecials@true\resetPS@}
317 \xydef@\xyPSwarning@#1{\xywarning@{PostScript switched #1}}

318 %

319 %\xydef@\xyPSraw@{%
320 % \ifPSspecials@\expandafter\PSraw@@\else\expandafter\eat@\fi }

Unloading the PostScript-backend is handled by the unload ⟨driver⟩.

397 \xyaddunsupport{ps}{\csname UnloadPS@@\endcsname}

adding new drivers Other drivers can be added by including an appropriate control-sequence name for the driver at this point. The purpose of an expansion such as \xydef@\OzTeX@{\noexpand\OzTeX@} is so that this name always refers to a unique token. The macro \PSspecials@@ defined below, detects this token and then calls up the appropriate macro to make the necessary bindings.

Thus adding a new driver involves 5 steps:

• 1 Define a new control sequence, as just explained.

• 2 Define appropriately named macros to generate the desired \specials. (See the existing ones for examples of what is needed here.)

• 3 Define a macro that will perform the appropriate bindings of the different classes of \special. (See the existing ones for examples of what is needed here.)

• 4 Determine how frequently the XY-ps dictionary must be included within the PostScript file. Once (at the beginning) is the ideal, however it may be necessary to include it with every page— this is the case with Textures. Also if the dictionary can be loaded as a header or prolog, determine whether this can be done only once or must be for each page. Also check whether a specific name is required, as with OzTEX.

• 5 Check to see whether the \dumpPSdict macro correctly writes the dictionary to a file. The \endlinechar can be important here.

XY-ps works by rebinding existing control sequence names, in the XY-pic kernel and extensions, to have new expansions. These new expansions may eventually typeset nothing, or at most an empty box; instead they use a \special command to place PostScript code directly into the .dvi file (or DVI2 resources in the case of Textureson the Macintosh). The new expansions alter the TEX processing, often simplifying it considerably hence leading to savings in both time and memory requirement.

It should not be possible to mix \specials intended for different drivers. Thus the first use of \PSspecials@ will establish which driver is required then rebinds \UsePSspecials@ so that no other driver can be used; subsequent attempts to use \UsePSspecials@ simply result in the same driver being reinstated.

448 \xydef@\PSspecials@{%
449 \ifx\next[\DN@[##1]{\setxyPSlevel@{##1}\xyFN@\PSspecials@}%
450 \else\DN@{\whichPSspecials@\PSspecials@@}%
451 \fi \next@ }%
453 \xydef@\PSspecials@@{%
454 \ifx\und@fined\PSmessage\hidePSmessages\fi \setupxyPS@}

An optional argument to the \UsePSspecials command allows for some control over precisely

when PostScript \specials will be used. Similarly \UseDVIPSspecials and \UseTexturesSpecials,

etc. can take an optional argument.

For example, \UsePSspecials[1] replaces only font characters with a PostScript drawing of the same character. Both the PostScript and the bitmapped fonts should produce (virtually) identical printed images. This is primarily a test mode.

\UsePSspecials[2] also only replaces font characters but such that the number of possible directions is 8192, so that arrowheads turns and hooks fit better.

\UsePSspecials[3] draws straight and dotted lines from a single \special command, and similarly for circle segments. The printed output should be identical to that obtained with \UsePostScriptSpecials[2], but the size of the .ps file should be smaller.

\UsePSspecials[4] is the default level; all PostScript is turned on. Dotted curves use equally spaced dots, dashed curves have curved dashes; even dashed lines are better.

\UsePSspecials[0] does no rebinding of fonts at all. It allows the special effects, such as rotation, scaling, colour, etc defined in extensions, to be implemented while using the Xy-pic fonts.

487 \xydef@\setupxyPSlevelO@{\relax}
489 \xydef@\setxyPSlevel@#1{\ifcase#1%
490  \gdef\setupxyPS@{\setupxyPSlevelO@}%
491 \or\gdef\setupxyPS@{\setupxyPSlevelA@}%
492 \or\gdef\setupxyPS@{\setupxyPSlevelB@}%
493 \or\gdef\setupxyPS@{\setupxyPSlevelC@}%
494 \or\gdef\setupxyPS@{\setupxyPSlevelD@}%
495 \else\gdef\setupxyPS@{\setupxyPSlevelD@}\fi }
497 \xywarnifdefined\setupxyPS@
498 \gdef\setupxyPS@{\setupxyPSlevelD@ \gdef\setupxyPS@{\PSspecials@true}}
500 \xydef@\PSincrease@#1{%

501 \xywarning@{The PS level may only increase: #1 is already active}}

2.10.2 Why use PostScript

At some sites users have difficulty installing the extra fonts used by XY-pic. The .tfm files can always be installed locally but it may be necessary for the .pk bitmap fonts (or the .mf fonts) to be installed globally, by the system administrator, for printing to work correctly. If PostScript is available then XY-ps allows this latter step to be bypassed.

Note: with XY-ps it is still necessary to have the .tfm font metric files correctly installed, as these contain information vital for correct typesetting.

Other advantages obtained from using XY-ps are the following:

• Circles and circle segments can be set for arbitrary radii.

• solid lines are straighter and cleaner. They are no longer typeset as a collection of fixed-sized segments (drawn from the xydash10 font). Previously special placement algorithms were required, to construct lines of arbitrary length in up to 8192 distinct directions, from the 128 characters in the font. These algorithms are no longer required, giving improved TEX processing, as well as having smooth lines of arbitrary length and direction limited only by the resolution of the PostScript device.

• The range of possible angles of directionals is greatly increased. For arrow tips, hooks, and turns, there are now 8192 possible orientations rather than just the 128 contained in the xyatip10,

xybtip10, and xybsql10 fonts.

• Spline curves are smoother. True dotted and dashed versions are now possible, using equally spaced segments which are themselves curved.

• The PostScript file produced by a driver from an XY-ps DVI file is in general significantly smaller than one produced by processing an ‘ordinary’ DVI file using the same driver. One reason for this is that no font information for the XY-pic fonts is required in the PostScript file; this furthermore means that the use of XY-pic does not in itself limit the PostScript file to a particular resolution.^{2}

• The latest version of XY-pic now enables special effects such as variable line thickness, graylevel and colour. Also, rotation of text and (portions of) diagrams is now supported with some drivers. Similarly whole diagrams can be scaled up or down to fit a given area on the printed page. Future versions will allow the use of regions filled with colour and/or patterns, as well as other attractive effects.

Some of the above advantages are significant, but they come at a price. Known disadvantages of using XY-ps include the following:

• A DVI file with specials for a particular PostScript driver can only be previewed if a previewer is available that supports exactly the same \special format. A separate PostScript previewer will usually be required.

However recent versions of xdvi support viewing of PostScript using either the GhostScript program or via “Display PostScript”. The PostScript produced by XY-ps can be viewed this way • DVI files created using XY-ps in fact lose their “device-independence”. So please do not distribute

2Most TEX PostScript drivers store the images of characters used in the text as bitmaps at a particular resolution.

This means that the PostScript file can only be printed without loss of quality (due to bitmap scaling) at exactly this resolution.

DVI files with PostScript specials—send either the TEX source code, expecting the recipient to have XY-pic ◯_{¨⌣}, or send a (compressed) PostScript file.

The latter comment applies to files in which any special ‘back-end’ support is required, not just to PostScript. Of course it can be ignored when you know the configuration available to the intended recipient.

PostScript header file: With some DVI-drivers it is more efficient to have the PostScript commands that XY-ps needs loaded initially from a separate “header” file. To use this facility the following commands are available…

                              \UsePSheader {}
                              \UsePSheader {<filename>}
                              \dumpPSdict {<filename>}
                              \xyPSdefaultdict

Normally it is sufficient to invoke \UsePSheader{}, which invokes the default name of xy37dict.pro, referring to the current version of XY-pic. The optional ⟨filename⟩ allows a different file to be used. Placing \dumpPSdict{..} within the document preamble causes the dictionary to be written to the supplied ⟨filename⟩.

625 \DN@{\csname newif\endcsname\ifUsePSdict@@\DN@{}}
626 \ifx\undefined\UsePSdict@@true\else\DN@{}\fi \next@
628 \ifx\undefined\xyPSdefaultdict
629 \xydef@\xyPSdefaultdict{%
630 \DN@##1.##2.##3@{\gdef\xyPSdictname{xy##1##2dict.pro}}%
631 \expandafter\next@\xyversion.@}%
632 \fi
634 \ifx\undefined\UsePSheader@
635 \xydef@\UsePSheader@#1{%
636 \DN@{#1}\ifx\next@\empty
637 %  \ifx\xyPSdictname\undefined\xyPSdefaultdict\fi
638 \else \gdef\xyPSdictname{#1}\fi
639 \ifx\xyPSdictname\undefined\xyPSdefaultdict\fi
640 \gdef\xyHeaderMessage@{%
641  It includes a reference to the PostScript file \xyPSdictname.^^J}%
642 \UsePSdict@@true}%
643 \let\UsePSheader=\UsePSheader@
644 \fi

See the documentation for the specific driver to establish where the dictionary file should be located on any particular TEX system. Usually it is sufficient to have a copy in the current working directory. Invoking the command \dumpPSdict{} will place a copy of the requisite file, having the default name, in the current directory. This file will be used as the dictionary for the current processing, provided it is on the correct directory path, so that the driver can locate it when needed. Consult your local system administrator if you experience difficulties.

The ‘dump’ cannot be performed until a driver has been installed. This ensures that the correct ‘end-of-line’ character is used.

663 \xydef@\dumpPSdict#1{\DN@{#1}\ifx\next@\empty

664 \ifx\undefined\xyPSdictname\xyPSdefaultdict\fi
665 \else\gdef\xyPSdictname{#1}\fi
666 \def\dumpPSdict@@{\writePSdict@@}%
667 \ifx\xydriversselected@@\empty\DN@{\xysetup@@\null@xy@ps}%
668 \else \DN@{\installxyps@x}\fi \next@}

Multiple instances of \UsePSheader and \dumpPSdict are possible, only the last will determine which file is used for the current document. The command \xyPSdefaultdict reverts to the default name.

Allowing an arbitrary ⟨filename⟩ with \UsePSheader is for flexibility, to accommodate systems that may impose special requirements on the filenames of files to be used as PostScript header files. OzTEX is one such. It also caters for advanced users of XY-pic who may wish to experiment with customised PostScript to obtain new effects.

2.10.3 Hooking into XY-pic

689 \message{hooks,}

This next macro streamlines the rebinding process.

695 \gdef\xyPSalternative@#1#2{%
696 \expandafter\global\expandafter\let\csname origxy#2@\endcsname=#1%
697 \xdef#1{\noexpand\ifPSspecials@
698  \noexpand\expandafter\expandafter\noexpand\csname xyPS#2@\endcsname
699 \noexpand\else
700  \noexpand\expandafter\expandafter\noexpand\csname origxy#2@\endcsname
701 \noexpand\fi}}%

   The commands \setupxyPSlevelA@, \setupxyPSlevelB@, \setupxyPSlevelC@ and \setupxyPSlevelD@

actually perform the rebindings. Each may be called precisely once, and each requires all lower levels are also set.

710 \xydef@\setupxyPSlevelA@{\xyPStips@%
711 \xyPSalternative@{\Tip@@}{Tip}%
712 \xyPSalternative@{\Ttip@@}{Ttip}%
713 \xyPSalternative@{\Tip@@eu}{Tip@eu}%
714 \xyPSalternative@{\Ttip@@eu}{Ttip@eu}%
715 \xyPSalternative@{\hook@@}{hook}%
716 \xyPSalternative@{\ahook@@}{ahook}%
717 \xyPSalternative@{\bhook@@}{bhook}%
718 \xyPSalternative@{\aturn@@}{aturn}%
719 \xyPSalternative@{\bturn@@}{bturn}%
720 \xyPSalternative@{\squiggle@@}{squiggle}%
721 \xyPSalternative@{\stopper@@}{stopper}%
722 \xyPSalternative@{\line@@}{dash}%
723 \xyPSalternative@{\circhar@@}{circhar@}%
724 % \xywithoption{cmtip}{\xyPScmtips@}%
725 \gdef\setupxyPSlevelA@{\PSincrease@{1}}%
726 \global\let\UsePSspecials=\UsePSspecials@x \PSspecials@true}

727 %

728 \xydef@\setupxyPSlevelB@{%
729 \let\xyPSfont@=\empty \let\xyPSsemifont@=\empty
730 \xyPSalternative@{\cirrestrict@@}{cirrest}%

731 \gdef\setupxyPSlevelB@{\PSincrease@{2}}%
732 \setupxyPSlevelA@ }

733 %

734 \xydef@\setupxyPSlevelC@{%
735 \xyPSalternative@{\cirbuild@}{cirbuild}%
736 \xyPSalternative@{\CIRfull@}{CIRfull}%
737 \xyPSalternative@{\solid@}{solid}%
738 \xyPSalternative@{\point@}{point}%
739 \xywithoption{curve}{%
740 \xyPSalternative@{\splinesolid@}{splinesolid}}%
741 \gdef\setupxyPSlevelC@{\PSincrease@{3}}%
742 \setupxyPSlevelB@ }%

743 %

744 \xydef@\setupxyPSlevelD@{%
745 \xyPSalternative@{\dash@}{dashed}%
746 % \xyPSalternative@{\squiggle@}{squiggled}%
747 \xywithoption{curve}{%
748 \xyPSalternative@{\splinedashed@}{splinedashed}%
749 \xyPSalternative@{\splinedotted@}{splinedotted}}%
750 \gdef\setupxyPSlevelD@{}%\PSincrease@{4}}%
751 \setupxyPSlevelC@ }

The bindings are not performed until \setupxyPS@ is called.

2.10.4 Kernel improvements

Directionals:

These macros standardise the way a character is described in PostScript. First give the \Direction code then the operator name, which is just a simple character string. The modifiers \xyPSfont@ and \xyPSsemifont@ are empty in all but the most primitive level of PostScript usage. When non-empty they restrict to using only angles corresponding to actual font characters.

772 \xydef@\xyPSchar@#1{%
773 \PSmacro@{\the\Direction\space \xyPSfont@ #1}}
775 \xydef@\xyPSsemichar@#1{%
776 \PSmacro@{\the\Direction\space \xyPSsemifont@ #1}}

These macros provide PostScript code to round a \Direction code to that corresponding to the nearest font character code, for Directional and semi-Directional fonts respectively.

784 \xydef@\xyPSfont@{f }%{xyfont }
785 \xydef@\xyPSsemifont@{fs }%{xysdfont }

Before any binding we save the original expansions of control-sequences whose names will be subject to rebinding. We give these first for each font.

tips Arrow heads in \xyatipfont and \xybtipfont

The tips are all set as zero-sized characters…

799 \xydef@\xyPStip@{\xyPSchar@{t}}%{\xyPSchar@{tip}}
800 %\xydef@\xyPSatip@{\xyPSchar@{a}}%{\xyPSchar@{atip}}
801 %\xydef@\xyPSbtip@{\xyPSchar@{b}}%{\xyPSchar@{btip}}
802 \xydef@\xyPSTip@{\xyPSchar@{/XT tt}}%{\xyPSchar@{Tip}}

803 \xydef@\xyPSTtip@{\setboxz@h\bgroup
804 \reverseDirection@\line@ \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@
805 \kern-\L@c \boxz@ \kern\L@c \xyPSchar@{/Xt tT}}%{\xyPSchar@{Ttip}}
806 \xydef@\xyPSTip@eu@{\xyPSchar@{/ET tt}}%{\xyPSchar@{Tip}}
807 \xydef@\xyPSTtip@eu@{\setboxz@h\bgroup
808 \reverseDirection@\line@ \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@
809 \kern-\L@c \boxz@ \kern\L@c \xyPSchar@{/ET tT}}%{\xyPSchar@{Ttip}}

The mechanism to handle Computer Modern tips is a little different. Here we must rebind \xycm@ to avoid any calls to font names. When \PSspecialstrue then we expand a macro which will look at the following token to decide which type of tip is required after \tip@x.

819 %\xydef@\xyPScmtips@{\xyPSalternative@{\xycm@}{cm}}%
820 \xydef@\xyPScm@\tip@x{\xyFN@\xyPScm@@}%
821 \xydef@\xyPScm@@{%
822  \ifx\next\tip@@  \DN@\tip@@{\tip@x\xyPScmtip@}%
823 \else\ifx\next\atip@@ \DN@\atip@@{\tip@x\xyPScmatip@}%
824 \else\ifx\next\btip@@ \DN@\btip@@{\tip@x\xyPScmbtip@}%
825 \else\DN@{}%
826 \fi\fi\fi \next@}%

827 %

828 \xydef@\xyPScmtip@{\xyPSchar@{ct}}%{\xyPSchar@{cmtip}}
829 \xydef@\xyPScmatip@{\xyPSchar@{ca}}%{\xyPSchar@{cmatip}}
830 \xydef@\xyPScmbtip@{\xyPSchar@{cb}}%{\xyPSchar@{cmbtip}}

From version 3.3 the font coding has changed, for greater flexibility and consistency. In particular \xycm@ is no longer defined.

837 \xydef@\xyPStips@{%
838 \xyPSalternative@{\atip@@}{atip}%
839 \xyPSalternative@{\btip@@}{btip}%
840 \xyPSalternative@{\tip@@}{abtip}%

841 }%

843 \xydef@\xyPSatip@{\xyPSwhichatip@
844 \expandafter\xyPSchar@\expandafter{\xyPSfont@@}}%
845 \xydef@\xyPSbtip@{\xyPSwhichbtip@
846 \expandafter\xyPSchar@\expandafter{\xyPSfont@@}}%
847 \xydef@\xyPSabtip@{\xyPSwhichabtip@
848 \expandafter\xyPSchar@\expandafter{\xyPSfont@@}}%
850 \xydef@\xyPSwhichatip@{\ifx\xyatipfont\xy@@atfont
851 \expandafter\xyPSatip@i \else\def\xyPSfont@@{10 /xy A}\fi }%
852 \xydef@\xyPSwhichbtip@{\ifx\xybtipfont\xy@@btfont
853 \expandafter\xyPSbtip@i \else\def\xyPSfont@@{10 /xy B}\fi }%
854 \xydef@\xyPSwhichabtip@{\ifx\xyatipfont\xy@@atfont
855 \expandafter\xyPSabtip@i \else\def\xyPSfont@@{10 /xy AB}\fi }%
856 \xydef@\xyPSatip@i{%
857 \edef\xyPSfont@@{\tipsize@@\space/\tipfamily@@\space A}}
858 \xydef@\xyPSbtip@i{%
859 \edef\xyPSfont@@{\tipsize@@\space/\tipfamily@@\space B}}
860 \xydef@\xyPSabtip@i{%
861 \edef\xyPSfont@@{\tipsize@@\space/\tipfamily@@\space AB}}

863 \xydef@\xyPSTtips@{%
864 \let\Ttip@xy=\Ttip@
865 \let\Ttip@cm=\Ttip@
866 \let\Ttip@eu=\Ttip@ }

hooks, turns and squiggles: squiggles from: \xybsqlfont The hooks are zero-sized characters…

875 \xydef@\xyPShook@{\xyPSchar@{h}}%{\xyPSchar@{hook}}
876 \xydef@\xyPSahook@{\xyPSchar@{ha}}%{\xyPSchar@{ahook}}
877 \xydef@\xyPSbhook@{\xyPSchar@{hb}}%{\xyPSchar@{bhook}}

… so are the turns…

883 \xydef@\xyPSaturn@{\xyPSchar@{ta}}%{\xyPSchar@{aturn}}
884 \xydef@\xyPSbturn@{\xyPSchar@{tb}}%{\xyPSchar@{bturn}}

This handles squiggles as individual characters. Squiggled connections should be handled sepa-

rately, e.g. by having \xyPSsquiggle@ set the connection by something like \edef\Connect@@{\noexpand\xyPSsquiggled@ {\the\Direction}}.

893 \xydef@\xyPSsquiggle@{\xyPSchar@{g}}%{\xyPSchar@{squigl}}

To Do: define composite \xyPSsquiggled@

   To Do: define composite \xyPSdashsquiggled@

dashes and stoppers: using characters from: xydashfont

A stopper contributes zero size. However a dash gets its size from the italic correction in the

xydashfont, accessed here using \origxyline@@.

910 \xydef@\xyPSstopper@{\xyPSchar@{st}}%{\xyPSchar@{stopper}}
912 %\xydef@\xyPSfliptrue@{\DN@{\xyPSsemichar@{true dash}}}
913 \xydef@\xyPSfliptrue@{\DN@{\xyPSsemichar@{T d}}}
915 \xydef@\xyPSdash@{%
916 % \DN@{\xyPSsemichar@{false dash}}%
917 \DN@{\xyPSsemichar@{F d}}%
918 \ifnum\SemiDirectionChar=31
919 \ifdim\d@Y<\z@
920  \ifdim\d@X<\z@ \ifx\xyPSsemifont@\empty\xyPSfliptrue@\fi\fi
921 \else
922  \ifdim\z@>\d@X
923  \ifx\xyPSsemifont@\empty\else\xyPSfliptrue@\fi
924  \else\xyPSfliptrue@\fi
925 \fi\fi
926 \next@ \setboxz@h{\origxydash@}\kern\wdz@
927 \setbox\z@=\box\voidb@x }

Circles

full circles and circle segments: \xycircfont This handles the cases where a font character is called using \circhar#1.

937 \xydef@\xyPScirchar@#1{\count@=#1\edef\tmp@{\the\count@}%
938 \ifcase#1%

939 \xyPScirchar@@@{-180}{-135}{\tmp@}\dimen@=\partroottwo\R@
940 \or\xyPScirchar@@@{-135}{-90}{\tmp@}\dimen@=\halfroottwo\R@
941 \or\xyPScirchar@@@{-90}{-45}{\tmp@}\dimen@=\halfroottwo\R@
942 \or\xyPScirchar@@@{-45}0{\tmp@}\dimen@=\partroottwo\R@
943 \or\xyPScirchar@@@0{45}{\tmp@}\dimen@=\partroottwo\R@
944 \or\xyPScirchar@@@{45}{90}{\tmp@}\dimen@=\halfroottwo\R@
945 \or\xyPScirchar@@@{90}{135}{\tmp@}\dimen@=\halfroottwo\R@
946 \or\xyPScirchar@@@{135}{180}{\tmp@}\dimen@=\partroottwo\R@
947 \fi}
949 \xydef@\xyPScirrest@{\relax}%

This replaces just the font character, called using \circhar@@#1.

955 \xydef@\xyPScirchar@@#1{\relax\count@=#1\edef\tmp@{\the\count@}%
956 \expandafter\xyPScirchar@@@\ifcase#1%
957 {-180}{-135}{\tmp@}\kern\partroottwo\R@
958 \or{-135}{-90}{\tmp@}\kern\halfroottwo\R@
959 \or{-90}{-45}{\tmp@}\kern\halfroottwo\R@
960 \or{-45}0{\tmp@}\kern\partroottwo\R@
961 \or 0{45}{\tmp@}\kern\partroottwo\R@
962 \or{45}{90}{\tmp@}\kern\halfroottwo\R@
963 \or{90}{135}{\tmp@}\kern\halfroottwo\R@
964 \or{135}{180}{\tmp@}\kern\partroottwo\R@
965 \fi}
967 \xydef@\xyPScirchar@@@#1#2#3{\edef\tmp@{#1\space#2\space
968 \expandafter\removePT@\the\R@\space #3\space c}%
969 \PSmacro@{\tmp@}}

This next macro will allow for more general circle segments to be done in PostScript. The two parameters are the starting angle and finishing angle respectively, measured anti-clockwise.

977 \xydef@\xyPScirc@#1#2{\edef\tmp@{\expandafter\removePT@\the\R@}%
978 % \PSmessage{\tmp@\space #1 #2 circ}\PSmacro@{\tmp@\space #1 #2 circ}}
979 \PSmacro@{\tmp@\space #1 #2 o}}

These gives full circles and circle segments built from quarter turns.

985 \xydef@\xyPSCIRfull@{\setboxz@h{\kern\R@\xyPScirc@0{360}\kern\R@}%
986 \wd\z@=\z@ \ht\z@=\R@ \dp\z@=\R@ \boxz@}%
988 \xydef@\xyPScirbuild@{{%
989 \count@=\CIRlo@@ \count@@=\CIRhi@@
990 \multiply\count@ by45 \advance\count@-180 \relax
991 \multiply\count@@ by45 \advance\count@@-180 \relax
992 \def\tmp@{}%
993 \ifx\CIRtest@@\CIRtest@inside
994 \ifnum\count@@>\count@
995  \edef\tmp@{\noexpand\xyPScirc@{\the\count@}{\the\count@@}}\fi
996 \else\ifx\CIRtest@@\CIRtest@outside
997 \ifnum\count@>-180 \advance\count@ by360 \relax
998  \edef\tmp@{\noexpand\xyPScirc@{\the\count@@}{\the\count@}}%
999 \else
1000 \ifnum\count@@<180 \relax

266 CHAPTER 2. EXTENSIONS

1001  \edef\tmp@{\noexpand\xyPScirc@{\the\count@@}{180}}%
1002 \fi\fi
1003 \fi\fi
1004 \kern\R@\tmp@\kern\R@}}

Lines solid, dashed and dotted; without using segments.

This is based on \straight@. It is used by all three types of line, taking an appropriate macro as the parameter #1.

1014 \xydef@\xyPSstraight@#1{\setupDirection@
1015 \edef\Creset@@{\cfromthec@ \pfromthep@ \DirectionfromtheDirection@}%
1016 \DN@##1##2{\def\checkoverlap@@{%
1017 \ifdim##1\X@p>##1\X@c \let\next@=\relax \fi
1018 \ifdim##2\Y@p>##2\Y@c \let\next@=\relax \fi}}%
1019 \edef\nextii@{{\sd@X}{\sd@Y}}\expandafter\next@\nextii@
1020 \noCshavep@@
1021 \edef\Cshavep@@{\pfromthep@ \noexpand\resetDirection@}%
1022 \noCshavec@@
1023 \edef\Cshavec@@{\cfromthec@ \noexpand\resetDirection@}%
1024 \ifHidden@\else
1025 \ifdim\Y@c>\Y@max \Y@max=\Y@c \fi  \ifdim\Y@p>\Y@max \Y@max=\Y@p \fi
1026 \ifdim\Y@c<\Y@min \Y@min=\Y@c \fi  \ifdim\Y@p<\Y@min \Y@min=\Y@p \fi
1027 \ifdim\X@c>\X@max \X@max=\X@c \fi  \ifdim\X@p>\X@max \X@max=\X@p \fi
1028 \ifdim\X@c<\X@min \X@min=\X@c \fi  \ifdim\X@p<\X@min \X@min=\X@p \fi \fi
1029 \ifInvisible@\let\next@=\relax \else
1030 \DN@{\setboxz@h{\kern\X@c \raise\Y@c\hbox{#1}}%
1031 \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\xykillstyles@\Drop@@}}%

1032 \fi

1033 \checkoverlap@@
1034 \ifdim\d@X=\z@ \ifdim\d@Y=\z@ \DN@{\relax}\fi\fi \next@
1035 \def\Cslidep@@{\noCslidep@@}\def\Cslidec@@{\noCslidec@@}%
1036 \def\Calong@@{\noCalong@@}\Creset@@ }

This is not needed unless styles are used, hence xyps-s is loaded.

1042 \xylet@\xykillstyles@=\relax

Here is how solid lines are done.

1048 %\xydef@\xyPSsolid@{\ifInvisible@ \let\next@=\no@@
1049 % \else \DN@{\xyPSstraight@\xyPSsolid@@@}\fi \next@ }
1051 \xydef@\xyPSsolid@{\straight@\xyPSsolidSpread@}%
1052 \xydef@\xyPSsolidSpread@{\xyPSspread@{solid}{l}@@}%
1054 \xydef@\xyPSdottedSpread@{\xyPSspread@{dotted}{dt}@@}%
1056 \xydef@\xyPSdashed@{\line@ \def\Connect@@{\straight@\xyPSdashedSpread@}}
1057 \xydef@\xyPSdashedSpread@{\xyPSspread@{dashed}{dd}@@}%
1060 \xydef@\xyPSspread@#1#2@@#3\repeat@{\edef\tmp@{%
1061 \expandafter\removePT@\the\d@X\space\expandafter\removePT@\the\d@Y}%
1062 \setboxz@h{\kern\X@c \raise\Y@c\hbox{%

1063 \PSmessage{#1 line:}\PSmacro@{\tmp@\space #2}}}%
1064 \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ \boxz@}

This replaces the XY-pic \dash@ to give dashed lines:

1071 %\xydef@\xyPSdashed@{\line@ \def\Connect@@{\xyPSstraight@\xyPSdashed@@}}
1072 %\xydef@\xyPSdashed@@{\edef\tmp@{%
1073 %  \expandafter\removePT@\the\d@X\space\expandafter\removePT@\the\d@Y }%
1074 %  \PSmessage{dashed line: \tmp@}\PSmacro@{\tmp@\space dd}}

This replaces the XY-pic \point@ to give dotted lines. XY-pic defines \zerodot to be a small centred square with side length \xydashw@. The PostScript substitute is a round dot of this radius.

1083 \xydef@\xyPSpoint@{\xyPSzerodot@\egroup
1084 \Invisible@false \Hidden@false \def\Leftness@{.5}\def\U@pness@{.5}\ctipEdge@
1085 % \def\Drop@@{\styledboxz@}\def\Connect@@{\xyPSstraight@\xyPSdotted@}}
1086 \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@\xyPSdottedSpread@}}
1088 %\xydef@\xyPSdotted@{\edef\tmp@{%
1089 %  \expandafter\removePT@\the\d@X\space\expandafter\removePT@\the\d@Y }%
1090 %  \PSmessage{dotted line: \tmp@}\PSmacro@{\tmp@\space dt}}
1091 \xydef@\xyPSzerodot@{\PSmessage{dot:}\PSmacro@{p}}

Frames These are used for dashed frames. This may do circular frames.

Curves

1117 \xydef@\xyPScubic@#1{\readsplineparams@
1118 \PSmessage{CUBIC:}%
1119 \DN@{#1}\ifx\next@\empty\PSmacro@{mark \cubicinfo@\space bz}%
1120 \else\PSmacro@{mark \cubicinfo@\space b#1}\fi}
1122 \xydef@\xyPSsquine@#1{\readsplineparams@
1123 \PSmessage{SQUINE:}%
1124 \DN@{#1}\ifx\next@\empty\PSmacro@{mark \squineinfo@\space q#1}%
1125 \else\PSmacro@{mark \squineinfo@\space q#1}\fi}
1129 \xydef@\xyPSsplinesolid@{\ifx\splineinfo@\squineinfo@
1130 \expandafter\xyPSsquine@\else\expandafter\xyPScubic@\fi{}}
1132 \xydef@\xyPSsplinedashed@{\ifx\splineinfo@\squineinfo@
1133 \expandafter\xyPSsquine@\else\expandafter\xyPScubic@\fi{d}}
1135 \xydef@\xyPSsplinedotted@{\ifx\splineinfo@\squineinfo@
1136 \expandafter\xyPSsquine@\else\expandafter\xyPScubic@\fi{t}}

The end & Log

1144 \xyendinput
1146 % $Log: xyps.doc,v $
1147 % Revision 3.7  1999/02/16 15:12:50  krisrose
1148 % Interim release (Y&Y fonts now free).

1150 % Revision 3.4  1997/05/18 01:13:24  ross
1151 % Essential bugfixes.

1152 %

1153 % Revision 3.3  1996/12/19 03:50:08  ross
1154 % Maintenance release.

1155 %

1156 % Revision 3.3  1996/12/18  09:31:46  ross
1157 % revised interface to straight connections
1158 % revised interface for tips, handles arbitrary scaling
1159 % driver/option-loading now uses \xyrequire

1160 %

1161 % Revision 3.2  1995/09/19  18:21:41  ross
1162 % Bug fix release.

1163 %

1164 % Revision 3.1  1995/09/05  20:36:33  ross
1165 % Release!

1166 %

1167 % Revision 3.0  1995/07/07  20:13:19  ross
1168 % Major release w/new User's Guide!

1169 %

1170 % Revision 2.14  1995/07/05  22:10:30  kris
1171 % Buglets...

1172 %

1173 % Revision 2.13  1995/07/04  15:04:51  ross
1174 % Ready for release of v3.

1175 %

1176 % Revision 2.12  1994/10/25  03:01:14  ross
1177 % Final 3beta release [bug fixes & AMS-LaTeX fitting].

1178 %

1179 % Revision 2.11  1994/07/05  06:34:32  ross
1180 % fixed bug with quadratic curves
1181 % fixed minor documentation bugs

1182 %

1183 % Revision 2.10  1994/06/15  12:46:03  ross
1184 % Second release 3beta.
1185 % Colour and line style saving works; label colouring bug fixed.

1186 %

1187 % Revision 2.9  1994/06/09  14:50:54  ross
1188 % Release 3beta.
1189 % Includes support for special effects: Rotations, Scaling, Line-width, Colour.
1190 % Back-ends are separated into separate files.
1191 % More back-ends are supported, experimentally --- needs testing.

1192 %

1193 % Revision 2.8  1994/04/08  10:36:40  ross
1194 % Second 3alpha release.

1195 %

1196 % Revision 2.7  1994/03/28  10:57:02  ross
1197 % First version.

1199 % Initial version by Ross Moore based on XYps 2.6.

2.11 TPIC backend

Vers. 3.3 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This option allows the XY-pic fonts to be replaced by tpic \specials, when used with a dvi-driver capable of supporting them. Extra capabilities include smoother lines, evenly spaced dotted/dashed curves, variable line-widths, gray-scale fills of circles, ellipses and polygonal regions.

Header:

1 %% $Id: xytpic.doc,v 3.3 1996/12/18 09:50:38 ross Exp $
2 %%
3 %% Xy-pic ``tpic'' TPIC backend, for lines, curves and fills.
4 %% Copyright (c) 1995-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{tpic}{TPIC backend}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

Use of tpic \specials offers an alternative to the XY-pic fonts. However they require a dvidriver that is capable of recognizing and interpreting them. One such viewer is xdvik, Karl Berry’s modification to the xdvi viewer on unix^{3} systems running X-windows or a derivative. dvipsk, Karl Berry’s modification to dvips also handles tpic \specials, so xdvik/dvipsk is an good combination for quality screen-display and PostScript printing.

Once loaded using \xyoption{tpic}, with an appropriate ⟨driver⟩ also specified either already or subsequently, the following commands are available to turn the tpic backend off/on.

3Unix is a trademark of Bell Labs.

\NoTPICspecials turns off tpic specials.
\UseTPICspecials reinstates tpic specials.

61 \xynew@{if}\ifTPICspecials@
62 \xydef@\UseTPICspecials{\TPICspecials@true}
63 \xydef@\NoTPICspecials{\TPICspecials@false}

There is a limit to the number of points allowable in a path. For paths constructed by XY-pic, which includes spline curves, when the limit is reached the path is automatically flushed and a new path commenced. The following command can be used to customise this limit—initially set at 300 for use with xdvi—to suit alternative ⟨driver⟩s.

\maxTPICpoints{⟨num⟩} set maximum for paths

79 \xynew@{count}\xytpic@cnt
80 \xydef@\xytpic@max{300}
81 \xydef@\maxTPICpoints#1{\count@=#1 \relax
82 \ifnum\count@>\tw@ \edef\xytpic@max{\the\count@}%
83 \else\expandafter\xyTPICmaxwarning@\expandafter{\the\count@}\fi}
84 \xydef@\xyTPICmaxwarning@#1{max points must be at least 2, #1 invalid}

Each object involving tpic \specials must set the style, using \xytpic@set@ to store a macro as the expansion of \xytpic@style@@. Currently this is global, since a tpic object must be completed once it has been started — perhaps this is not necessary.

Note that \xytpic@set@ uses \xdef, but has a \noexpand in its expansion; this forces expansion of the argument, when there is one, to the control sequence passed as the first token following

\xytpic@set@.

99 \xydef@\xytpic@style@@{\xytpic@fp}
100 \xydef@\xytpic@reset@{\gdef\xytpic@style@@{\xytpic@fp}%
101 \global\xytpic@cnt=\z@ }
102 \xydef@\xytpic@set@#1{\xdef\xytpic@style@@{\noexpand#1}}

Here are the actual \specials that get placed in the dvi-file.

108 \xydef@\xytpic@pn#1{\xyTPIC@special{pn #1}}
109 \xydef@\xytpic@pa#1#2{\global\advance\xytpic@cnt\@ne\relax
110 \ifnum\xytpic@cnt=\xytpic@max\relax \xyTPIC@special{pa #1 #2}%
111 \kern-\X@c\raise-\Y@c\hbox{\xytpic@style@@}\kern\X@c
112 % \xytpic@ip
113 \global\xytpic@cnt=\@ne \relax\fi \xyTPIC@special{pa #1 #2}}
114 \xydef@\xytpic@fp{\xyTPIC@special{fp}}
115 \xydef@\xytpic@ip{\xyTPIC@special{ip}}
116 \xydef@\xytpic@da#1{\xyTPIC@special{da #1}}
117 \xydef@\xytpic@dt#1{\xyTPIC@special{dt #1}}
118 \xydef@\xytpic@sp#1{\xyTPIC@special{sp #1}}
119 \xydef@\xytpic@ar#1#2#3#4#5#6{\xyTPIC@special{ar #1 #2 #3 #4 #5 #6}}
120 \xydef@\xytpic@ia#1#2#3#4#5#6{\xyTPIC@special{ia #1 #2 #3 #4 #5 #6}}
121 \xydef@\xytpic@sh#1{\xyTPIC@special{sh #1}}
122 %\xydef@\xytpic@psb#1{\xyTPIC@special{:[begin] #1}}

123 %\xydef@\xytpic@pse#1{\xyTPIC@special{:[end]}}

124 %

125 \xydef@\xytpic@wh{\xyTPIC@special{sh 0}}  % obsolete
126 \xydef@\xytpic@bk{\xyTPIC@special{sh 1}}  % obsolete
128 \xydef@\xyTPIC@special#1{\special{#1}}
129 \xydef@\xyTPIC@noisy#1{\W@{TPIC: #1}\special{#1}}
130 \xydef@\NoisyTPIC{\let\xyTPIC@special=\xyTPIC@noisy}

Some effects may require a tpic \special to be placed both before and after the ⟨object⟩.

137 \xydef@\xyTPICsplit@#1#2{\setboxz@h{#1\boxz@#2}}%

tpic uses units of ‘milli-inches’ for coordinates, but inches for dot-separations and dash-length.

146 \xydef@\xytpic@pt#1{\dimen@=#1\divide\dimen@ by72 %
147 \multiply\dimen@ by 1000 \advance\dimen@.5\p@
148 \count@=\dimen@ \divide\count@\p@ }
149 \xydef@\xytpic@in#1{\dimen@=#1\divide\dimen@ by72 %
150 \edef\next@{\expandafter\removePT@\the\dimen@}}%

The tpic location is calculated relative to the current TEX reference point. Hence most tpic objects start at the (0, 0) location.

157 \xydef@\xytpic@dot@@{\xytpic@pa00}
158 \xydef@\xytpic@width@{\xytpic@pt{\xylinethick@}%
159 \expandafter\xytpic@pn\expandafter{\the\count@}}
160 %\xylet@\xytpic@width@=\relax
162 \xydef@\xytpic@line{%
163 \xytpic@dot@@ \xytpic@pt{-\d@X}\count@@=\count@
164 \xytpic@pt\d@Y \edef\next@{{\the\count@@}{\the\count@}}%
165 \expandafter\xytpic@pa\next@ \xytpic@style@@ \xytpic@reset@ }
167 \xydef@\xytpic@solid@@{\xytpic@set@\xytpic@fp}
168 \xydef@\xytpic@dashed@@{\xytpic@in\xydashl@ \xytpic@dad}
169 \xydef@\xytpic@dotted@@{\dimen@=.5\xydashl@ \xytpic@in\dimen@ \xytpic@dtd}
170 \xydef@\xytpic@dad{\expandafter\xytpic@set@\expandafter{%
171 \expandafter\xytpic@da\expandafter{\next@}}}
172 \xydef@\xytpic@dtd{\expandafter\xytpic@set@\expandafter{%
173 \expandafter\xytpic@dt\expandafter{\next@}}}
175 \xydef@\xytpic@polysolid@{\xytpic@set@\xytpic@fp}
176 \xydef@\xytpic@polydashed@#1{\count@=#1 \xytpic@dad}
177 \xydef@\xytpic@polydotted@#1{\count@=#1 \xytpic@dtd}
178 \xydef@\xytpic@postpoly@{\xytpic@style@@ \xytpic@reset@}

re-bindings This is similar to the mechanism used by the PostScript back-end to rebind “hooks” to incorporate a switch according to the current value of \ifTPICspecials@.

190 \xydef@\TPICalternative@#1#2{%
191 \expandafter\global\expandafter\let\csname origxy#2@\endcsname=#1%
192 \xdef#1{\noexpand\ifTPICspecials@
193  \noexpand\expandafter\expandafter\noexpand\csname xytpic@#2@\endcsname
194 \noexpand\else
195  \noexpand\expandafter\expandafter\noexpand\csname origxy#2@\endcsname

196 \noexpand\fi}}%

Allow only one instance of \setupxyTPIC@; thereafter simply do \reloadxyTPIC@ to turn on anything that has been turned off.

203 \xydef@\setupxyTPIC@{\xywarning@{using TPIC specials}%
204 \TPICalternative@{\solid@}{solid}%
205 \TPICalternative@{\dash@}{dashed}%
206 \TPICalternative@{\point@}{point}%
207 \TPICalternative@{\circhar@@}{circhar}%
208 \TPICalternative@{\splinesolid@}{splinesolid}%
209 % \TPICalternative@{\splinedashed@}{splinedashed}%
210 % \TPICalternative@{\splinedotted@}{splinedotted}%
211 \xywithoption{frame}{\xyinputorelse@{xytp-f}{}\xyuncatcodes}%
212 \let\setupxyTPIC@=\reloadxyTPIC@
213 \activateTPIC@ }
215 \xydef@\xyunloadTPIC@{\xywarning@{TPIC specials turned off}%
216 \xywithoption{curve}{\xysetup@@\uninstallTPICcurves@ }%
217 \xywithoption{line}{\xysetup@@\uninstallTPICline@ }%
218 \xywithoption{frame}{\xysetup@@\uninstallTPICframes@ }%
219 \TPICspecials@false
220 \let\setupxyTPIC@=\reloadxyTPIC@ }
222 \xydef@\activateTPIC@{%
223 \xywithoption{line}{\xysetup@@\installTPICline@}%
224 \xywithoption{curve}{\xysetup@@\installTPICcurves@}%
225 \xywithoption{frame}{\xysetup@@\installTPICframes@}%
226 \TPICspecials@true }
228 \xydef@\reloadxyTPIC@{\xywarning@{TPIC specials back on}\activateTPIC@ }

236 \xydef@\xytpic@solid@{%
237 \ifInvisible@ \let\next@=\no@@
238 \else \DN@{\xyTPICstraight@{\xytpic@solid@@ \xytpic@line}}\fi
239 \next@ }
241 \xydef@\xytpic@dashed@{\line@
242 \def\Connect@@{\xyTPICstraight@{\xytpic@dashed@@ \xytpic@line}}}
244 \xydef@\xytpic@point@{\xytpic@dot@@\xytpic@fp\egroup
245 \Invisible@false \Hidden@false \def\Leftness@{.5}\def\Upness@{.5}\ctipEdge@
246 \def\Drop@@{\styledboxz@}%
247 \def\Connect@@{\xyTPICstraight@{\xytpic@dotted@@ \xytpic@line}}}
249 \xydef@\xyTPICstraight@#1{\setupDirection@
250 \edef\Creset@@{\cfromthec@ \pfromthep@ \DirectionfromtheDirection@}%
251 \DN@##1##2{\def\checkoverlap@@{%
252 \ifdim##1\X@p>##1\X@c \let\next@=\relax \fi
253 \ifdim##2\Y@p>##2\Y@c \let\next@=\relax \fi}}%
254 \edef\nextii@{{\sd@X}{\sd@Y}}\expandafter\next@\nextii@
255 \noCshavep@@ \edef\Cshavep@@{\pfromthep@ \noexpand\resetDirection@}%
256 \noCshavec@@ \edef\Cshavec@@{\cfromthec@ \noexpand\resetDirection@}%
257 \ifHidden@\else

258 \ifdim\Y@c>\Y@max \Y@max=\Y@c \fi  \ifdim\Y@p>\Y@max \Y@max=\Y@p \fi
259 \ifdim\Y@c<\Y@min \Y@min=\Y@c \fi  \ifdim\Y@p<\Y@min \Y@min=\Y@p \fi
260 \ifdim\X@c>\X@max \X@max=\X@c \fi  \ifdim\X@p>\X@max \X@max=\X@p \fi
261 \ifdim\X@c<\X@min \X@min=\X@c \fi  \ifdim\X@p<\X@min \X@min=\X@p \fi \fi
262 \ifInvisible@\let\next@=\relax \else
263 \DN@{\setboxz@h{\kern\X@c \raise\Y@c\hbox{#1}}%
264  \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}%
265 \fi
266 \checkoverlap@@
267 \ifdim\d@X=\z@ \ifdim\d@Y=\z@ \DN@{\relax}\fi\fi \next@
268 \def\Cslidep@@{\noCslidep@@}\def\Cslidec@@{\noCslidec@@}%
269 \def\Calong@@{\noCalong@@}\Creset@@ }

straight lines

spline curves Of the curves defined in the xycurve extension, only solid spline curves are supported. This is done by treating the spline as a polygon (poly-line) with many segments. The dotted or dashed variants do not work correctly.

Implementations of tpic draw dashed polygons such that the start and finish of each segment is solid. Since these segments can be very short, the effect is simply to create a solid line. Similarly the shortness of the segments tends to give nothing at all for large portions of a dotted curve. What is needed is an implementation whereby the on/off nature of a dashed or dotted polygon is determined by the accumulated length, not the length along just the current segment.

294 \xydef@\xytpic@splinesolid@{\xyTPICspline@\xytpic@fp }
295 \xydef@\xytpic@splinedashed@{\xytpic@in\xydashl@\expandafter\xyTPICspline@
296 \expandafter{\expandafter\xytpic@da\expandafter{\next@}}}
297 \xydef@\xytpic@splinedotted@{\xytpic@in{.5\xydashl@}\expandafter\xyTPICspline@
298 \expandafter{\expandafter\xytpic@dt\expandafter{\next@}}}
300 \xydef@\xyTPICspline@#1{\setbox\splinebox@=\copy\voidb@x %\zerodot
301 \SloppyCurves %\splinetol@=\xydashl@  % \xytpic@ip
302 \global\xytpic@cnt=\@ne \xytpic@set@{#1}%
303 \def\splineextra@@{\xyTPICspline@dot}%
304 \def\xycrvdrop@{ }\def\xycrvconn@{}\splineset@@ \xytpic@style@@}
306 \xydef@\xyTPICspline@dot{\xytpic@pt{\X@c}\count@@=\count@
307 \xytpic@pt{-\Y@c}\edef\next@{{\the\count@@}{\the\count@}}%
308 \expandafter\xytpic@pa\next@ }

316 \xydef@\xyTPIClinewidth@#1{\xytpic@pt{#1}\edef\next@{\the\count@}}
318 \xydef@\installTPICline@{%
319 \let\xylinewidth@@=\xylinewidth@
320 \let\xylineSpecial@@=\xytpic@pn
321 \let\transxyline@@=\xyTPIClinewidth@ }
323 \xydef@\uninstallTPICline@{\UnloadLine@}%

line width

circles and ellipses Here we catch circles and ellipses specified using the \xycircle command from the xycurve extension. Since TPIC supports only solid circles, we catch it only when the ⟨style⟩ is 274 CHAPTER 2. EXTENSIONS either {} or {-}.

335 \xydef@\xydoTPICcircle@#1{\DN@{#1}%
336 \ifx\next@\empty\DN@{\xyTPICfullcircle@}%
337 \else\expandafter\DNii@\expandafter{\addDASH@{}}%
338 \ifx\next@\nextii@\DN@{\L@=\R@ \xyTPICfullcircle@}%
339 \else\DN@{\dosolidcircle@{#1}}\fi\fi \next@ }
341 \xydef@\xyTPICfullcircle@{\xyTPICpartcircle@{00}0\twoPi@}%
343 \xydef@\xyTPICpartcircle@#1#2#3{%
344 \xytpic@pt{\R@}\expandafter\DNii@\expandafter{\the\count@}%
345 \xytpic@pt{\L@}\edef\next@{#1{\nextii@}{\the\count@}{#2}{#3}}%
346 \expandafter\xytpic@ar\next@ }
348 \xydef@\qartPi@{0.7853981}
349 \xydef@\tartPi@{2.3561944}

This replaces just the font character, called using \circhar@@#1.

355 \xydef@\xytpic@circhar@#1{\xytpic@width@\ifcase#1%
356 \xytpic@pt{\R@}\edef\next@{{{\the\count@}0}}%
357 \expandafter\xyTPICcirchar@i\next@{\tartPi@}{\fullPi@}\kern\partroottwo\R@
358 \or
359 \xytpic@pt{\halfroottwo\R@}\edef\next@{{{\the\count@}0}}%
360 \expandafter\xyTPICcirchar@i\next@{\halfPi@}{\tartPi@}\kern\halfroottwo\R@
361 \or
362 \xytpic@pt{\z@}\edef\next@{{{\the\count@}0}}%
363 \expandafter\xyTPICcirchar@i\next@{\qartPi@}{\halfPi@}\kern\halfroottwo\R@
364 \or
365 \xytpic@pt{-\halfroottwo\R@}\edef\next@{{{\the\count@}0}}%
366 \expandafter\xyTPICcirchar@i\next@0{\qartPi@}\kern\partroottwo\R@
367 \or
368 \xytpic@pt{-\halfroottwo\R@}\edef\next@{{{\the\count@}0}}%
369 \expandafter\xyTPICcirchar@i\next@{-\qartPi@}0\kern\partroottwo\R@
370 \or
371 \xytpic@pt{\z@}\edef\next@{{{\the\count@}0}}%
372 \expandafter\xyTPICcirchar@i\next@{-\halfPi@}{-\qartPi@}\kern\halfroottwo\R@
373 \or
374 \xytpic@pt{\halfroottwo\R@}\edef\next@{{{\the\count@}0}}%
375 \expandafter\xyTPICcirchar@i\next@{-\tartPi@}{-\halfPi@}\kern\halfroottwo\R@
376 \or
377 \xytpic@pt{\R@}\edef\next@{{{\the\count@}0}}%
378 \expandafter\xyTPICcirchar@i\next@{-\fullPi@}{-\tartPi@}\kern\partroottwo\R@
379 \fi}
381 \xydef@\xyTPICcirchar@i#1#2#3{\L@=\R@ \xyTPICpartcircle@{#1}{#2}{#3}}
387 \xydef@\xyTPIC@spline@ii@{\DN@{\xy@spline@ii}%
388 \ifx\splineSTYLE@\empty\DN@{\xyTPICqspline@{0}}%
389 \else\expandafter\DNii@\expandafter{\addDASH@{}}%
390 \ifx\splineSTYLE@\nextii@\DN@{\xyTPICqspline@{0}}%
391 \else\expandafter\DNii@\expandafter{\addDOT@{}}%

392 \ifx\splineSTYLE@\nextii@\DN@{\xyTPICqspline@{-.5}}%
393 \else\expandafter\expandafter\expandafter\DNii@\expandafter\expandafter
394 \expandafter{\expandafter\addDASH@\addDASH@{}}%
395 \ifx\splineSTYLE@\nextii@\DN@{\xyTPICqspline@{}}%
396 \fi\fi\fi\fi
397 \next@ }%
399 \xydef@\xyTPIC@accumulate{\xytpic@pt\X@c \count@@=\count@
400 \xytpic@pt{-\Y@c}\edef\next@{{\the\count@@}{\the\count@}}%
401 \expandafter\xytpic@pa\next@ }
403 \xydef@\xyTPICqspline@#1{\xytpic@width@
404 \xytpic@in{#1\xydashl@}\expandafter\gdef\expandafter\xytpic@style@@
405 \expandafter{\expandafter\xytpic@sp\expandafter{\next@}}%
406 \save@ \cfromp@ \xyTPIC@accumulate
407 \edef\smapp@@{\s@bot}\smapxy@i{\xyTPIC@accumulate}%
408 \leave@ \xyTPIC@accumulate \xytpic@style@@ \xytpic@reset@
409 \enter@{}\xy@spline@x }
413 \xydef@\installTPICcurves@{%
414 \let\dosolidcircle@@=\xydoTPICcircle@
415 \let\xy@spline@ii@@=\xyTPIC@spline@ii@

416 }

417 \xydef@\uninstallTPICcurves@{%
418 \let\dosolidcircle@@=\dosolidcircle@
419 \let\xy@spline@ii@@=\xy@spline@ii }

quadratic splines

426 \xywithoption{frame}{\xyinputorelse@{xytp-f}{}}

frames Implement color fills by reading from a \TPICfillcolor. Implement pattern fills by reading from a \TPICfillpatt. Read these whenever a fill is requested.

435 \xydef@\uninstallTPICframes@{\UnloadFrames@}
441 \xyendinput
443 % $Log: xytpic.doc,v $
444 % Revision 3.3  1996/12/18  09:50:38  ross
445 % adjusted Drop@@ for styles
446 % minor improvements to file-loading commands

447 %

448 % Revision 3.2  1995/09/19  18:21:41  ross
449 % Bug fix release.

450 %

451 % Revision 3.1  1995/09/05  20:36:33  ross
452 % Release!

453 %

454 % Revision 3.0  1995/07/07  20:13:19  ross
455 % Major release w/new User's Guide!

456 %

457 % Revision 2.13  1995/07/04  15:04:51  ross

458 % Ready for release of v3.

459 %

460 % NEW for version 3.1 by Ross Moore  1995/03/18.
461 % replaces xyps-col.doc

462 %

2.12 em-TeX backend

Vers. 3.3 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

Eberhard Matte’s em-TEX implementation provides a suite of \special commands to facilitate the drawing of lines, both on-screen and with various printing devices. This ‘back-end’ extension allows the lines in XY-pic diagrams to be drawn using these methods.

Note that this extension does not have to be used with em-TEX. Better results may be obtained using the PostScript back-end and dvips ⟨driver⟩, since a version of dvips is available for em-TEX. However, in particular for screen previewing purposes, it may be convenient to use this back-end. Furthermore note that dvips is capable of supporting em-TEX\specials.

Header:

1 %% $Id: xyemtex.doc,v 3.3 1996/12/18 09:18:00 ross Exp $
2 %%
3 %% Xy-pic ``em-TeX'' back-end extension.
4 %% Copyright (c) 1995-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{emtex}{em-TeX backend}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

Once loaded using \xyoption{emtex}, with an appropriate ⟨driver⟩ also specified either already or subsequently, the following commands are available to turn the em-TEX backend off/on.

\NoEMspecials turns off em-TEX specials.
\UseEMspecials reinstates em-TEX specials.

59 \xynew@{if}\ifEMspecials@
60 \xydef@\UseEMspecials{\EMspecials@true}
61 \xydef@\NoEMspecials{\EMspecials@false}

69 \xydef@\xyemtex@lineto{\xyEM@special{lineto}}
70 \xydef@\xyemtex@moveto{\xyEM@special{moveto}}
71 \xydef@\xyemtex@line#1{\xyEM@special{line #1}}
72 \xydef@\xyemtex@point#1{\xyEM@special{point #1}}
73 \xydef@\xyemtex@pen#1{\addtostyletoks@{\xyEM@special{linewidth #1}}}

The \specials These place the actual \specials and allow tracing:

79 {\catcode`:=12 \gdef\next#1{\special{em:#1}}}
80 \xylet@\xyEM@special=\next
82 {\catcode`:=12 \gdef\next#1{%
83 \W@{EM:#1 (\the\X@p,\the\Y@p),(\the\X@c,\the\Y@c)}\special{em:#1}}}
84 \xylet@\xyEM@noisy=\next
86 \xydef@\NoisyEMTeX{\let\xyEM@special=\xyEM@noisy}

Currently these are not used by XY-pic.

92 %\xydef@\xyemtex@message#1{\xyEM@special{message #1}}
93 %\xydef@\xyemtex@graph#1{\xyEM@special{graph #1}}

re-bindings This is similar to the mechanism used by the PostScript back-end to rebind “hooks” to incorporate a switch according to the current value of \ifEMspecials@.

105 \xydef@\EMalternative@#1#2{%
106 \expandafter\global\expandafter\let\csname origxy#2@\endcsname=#1%
107 \xdef#1{\noexpand\ifEMspecials@
108  \noexpand\expandafter\expandafter\noexpand\csname xyemtex@#2@\endcsname
109 \noexpand\else
110  \noexpand\expandafter\expandafter\noexpand\csname origxy#2@\endcsname
111 \noexpand\fi}}%

Allow only one instance of \setupxyEM@; thereafter simply do \reloadxyEM@ to turn on anything that has been turned off.

118 \xydef@\setupxyEMTeX@{\xywarning@{using em-TeX specials}%
119 \EMalternative@{\solid@}{solid}%
120 % \EMalternative@{\point@}{point}%
121 \EMalternative@{\splinesolid@}{splinesolid}%
122 \let\setupxyEM@=\reloadxyEM@
123 \activateEM@ }
125 \xydef@\xyunloadEM@{\xywarning@{EM specials turned off}%

278 CHAPTER 2. EXTENSIONS

126 % \xywithoption{curve}{\xysetup@@\uninstallEMcurves@ }%
127 \xywithoption{line}{\xysetup@@\uninstallEMline@ }%
128 % \xywithoption{frame}{\xysetup@@\uninstallEMframes@ }%
129 \EMspecials@false
130 \let\setupxyEM@=\reloadxyEM@ }
132 \xydef@\activateEM@{%
133 \xywithoption{line}{\xysetup@@\installEMline@}%
134 % \xywithoption{curve}{\xysetup@@\installEMcurves@}%
135 % \xywithoption{frame}{\xysetup@@\installEMframes@}%
136 \EMspecials@true }
138 \xydef@\reloadxyEM@{\xywarning@{EM specials back on}\activateEM@ }
146 \xydef@\xyemtex@solid@{%
147 \ifInvisible@ \let\next@=\no@@
148 \else \DN@{\xyEMstraight@}\fi
149 \next@ }
151 \xydef@\xyEMstraight@{\setupDirection@
152 \edef\Creset@@{\cfromthec@ \pfromthep@ \DirectionfromtheDirection@}%
153 \DN@##1##2{\def\checkoverlap@@{%
154 \ifdim##1\X@p>##1\X@c \let\next@=\relax \fi
155 \ifdim##2\Y@p>##2\Y@c \let\next@=\relax \fi}}%
156 \edef\nextii@{{\sd@X}{\sd@Y}}\expandafter\next@\nextii@
157 \noCshavep@@ \edef\Cshavep@@{\pfromthep@ \noexpand\resetDirection@}%
158 \noCshavec@@ \edef\Cshavec@@{\cfromthec@ \noexpand\resetDirection@}%
159 \ifHidden@\else
160 \ifdim\Y@c>\Y@max \Y@max=\Y@c \fi  \ifdim\Y@p>\Y@max \Y@max=\Y@p \fi
161 \ifdim\Y@c<\Y@min \Y@min=\Y@c \fi  \ifdim\Y@p<\Y@min \Y@min=\Y@p \fi
162 \ifdim\X@c>\X@max \X@max=\X@c \fi  \ifdim\X@p>\X@max \X@max=\X@p \fi
163 \ifdim\X@c<\X@min \X@min=\X@c \fi  \ifdim\X@p<\X@min \X@min=\X@p \fi \fi
164 \ifInvisible@\let\next@=\relax \else
165 \DN@{%
166  \setboxz@h{\kern\X@p \raise\Y@p\hbox{\xyemtex@moveto}}%
167  \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ %
168  \setboxz@h{\boxz@ \kern\X@c \raise\Y@c\hbox{\xyemtex@lineto}}%
169  \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}%
170 \fi
171 \checkoverlap@@
172 \ifdim\d@X=\z@ \ifdim\d@Y=\z@ \DN@{\relax}\fi\fi \next@
173 \def\Cslidep@@{\noCslidep@@}\def\Cslidec@@{\noCslidec@@}%
174 \def\Calong@@{\noCalong@@}\Creset@@ }

straight lines spline curves Of the curves defined in the xycurve extension, only solid spline curves are supported. This is done by treating the spline as a polygon (poly-line) with many segments.

189 \xydef@\xyemtex@splinesolid@{\setbox\splinebox@=\copy\voidb@x
190 \multiply\splinetol@\thr@@
191 \gdef\splineextra@@{\xyemtex@moveto\gdef\splineextra@@{\xyemtex@lineto}}%

2.13. NECULA’S EXTENSIONS 279

192 \def\xycrvdrop@{ }\def\xycrvconn@{}\splineset@@ }
200 \xydef@\xyEMlinewidth@#1{\dimen@=#1\relax\edef\next@{\the\dimen@}}
202 \xydef@\installEMline@{%
203 \let\xylinewidth@@=\xylinewidth@
204 \let\xylineSpecial@@=\xyemtex@pen
205 \let\transxyline@@=\xyEMlinewidth@ }
207 \xydef@\uninstallEMline@{\UnloadLine@\relax}%
211 \xydef@\UseEMlinewidth{\installEMline@}%
212 \xydef@\NoEMlinewidth{\uninstallEMline@}%

line width The end & Log

219 \xyendinput
221 % $Log: xyemtex.doc,v $
222 % Revision 3.3  1996/12/18  09:18:00  ross
223 % fixed bug affecting line-widths

224 %

225 % Revision 3.1  1995/09/05  20:28:57  ross
226 % Releasing version 3.1!

227 %

228 % Revision 3.0  1995/07/07  20:13:19  ross
229 % Major release w/new User's Guide!

230 %

231 % Revision 2.13  1995/07/04  15:04:51  ross
232 % Ready for release of v3.

233 %

234 % NEW for version 3.

2.13 Necula’s extensions

Vers. 0.0 by George C. Necula ⟨necula@cs.cmu.edu⟩

Header:

1 %% $Id$
2 %%
3 %% Xy-pic ``Necula extensions'' option.
4 %% Copyright (c) 1998          George C. Necula <necula@cs.cmu.edu>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1998  Kristoffer H. Rose  <krisrose@ens-lyon.fr>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the

12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{necula}{Necula's extensions}{\stripRCS$Revision: 0.0 $}%
27 {George C. Necula}{necula@cs.cmu.edu}%
28 {School of Computer Science,
29  Carnegie Mellon University,
30  5000 Forbes Avenue,
31  Pittsburgh, PA 15213-3891, USA}

This option contains two extensions of the XY-pic kernel: A way to expand TEX macros in object ⟨modifier⟩s, and a way to specify arbitrary polygons as the ⟨shape⟩ of an object.

2.13.1 Expansion

The special syntax e|⟨macros⟩| is introduced in an object ⟨modifier⟩s and ⟨coord⟩inates. It expands the given TEX ⟨macros⟩ (with \edef) before reinterpretation as a ⟨modifier⟩ of ⟨coord⟩, respectively.

52 \def\expandbeforenext@#1{%
53  \DN@ e|##1|{\edef\tmp@{##1}\expandafter\xyFN@\expandafter#1\tmp@}%

54 }

56 \xylet@\xy@oldOBJECT@=\OBJECT@
57 \xydef@\xy@newOBJECT@{%
58 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xy@newOBJECT@}%gobble spaces
59 \else\ifx e\next
60  \expandbeforenext@\OBJECT@
61 \else
62  \DN@{\xy@oldOBJECT@}\fi\fi
63 \next@}%
64 \let\OBJECT@=\xy@newOBJECT@
66 \xylet@\xy@oldCOORD@=\COORD@
67 \xydef@\xy@newCOORD@{%
68 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xy@newCOORD@}%gobble spaces
69 \else\ifx e\next
70  \expandbeforenext@\COORD@
71 \else
72  \DN@{\xy@oldCOORD@}\fi\fi
73 \next@}%
74 \let\COORD@=\xy@newCOORD@

This code may become part of the XY-pic kernel at a certain point.

2.13.2 Polygon shapes

A polygon ⟨shape⟩ is specified as

[P:⟨pos⟩,…,⟨pos⟩]

where [P:p_{1},…,p_{n}] denotes the shape obtained by tracking the edge with each p_{i} a position relative to the object reference point. ⟨vector⟩s and ⟨corner⟩s can be used directly; otherwise use -p to get the relative position.

Note: Do not use {} or [] in the ⟨pos⟩itions.

Bug: The algorithm assumes that the reference point is always inside the polygon.

It is possible to frame polygons is also possible.

105 % Define the polygon as a stylechar so that it is deferred
106 \xydefcsname@{*stylechar@P@}#1{\Pshape@#1@}
107 \xynew@{count}\c@poly@count \c@poly@count=\z@ % Polygon identifiers
109 \xydef@\Pshape@:#1@{% Strip the mandatory :
110 \addtotoks@{%
111 %              \xy@showthe c{Before parse}\xy@showthe p{Before parse}%
112 %              \xy@showdim{Before parse}%
113  \def\poly@list{@}%
114  \poly@parse #1,\relax,%Sets the poly@list
115  \def\poly@cache{}%
116  \edef\poly@id{\the\c@poly@count}%
117  \global\advance\c@poly@count\@ne
118  \poly@setEdge
119  % Save the old values of Lc for shifting
120  \edef\poly@saveLcshape{\the\L@c}%
121  \polygonEdge@Outer% Set U,R,D,L
122  \poly@setEdge
123  % Now shift the object to keep it centered
124  \dimen@=\poly@saveLcshape\advance\dimen@-\L@c
125  \advance\R@p -\dimen@
126 %              \xy@showthe c{After parse}%

127 }}

129 % Set the edge
130 % A polygonal edge is represented as \polygonEdge x1,y1;x2,y2;...;xn,yn@id@
131 % where xi,yi define the vertices of the polygonal edge as displacement from
132 % the object reference point (xn=x1,yn=y1), and id is a numerical id used for
133 % caching the result of the last intersection operation. The cached values for
134 % polygon id are stored in the global macro poly@cache<id>.
135 \xydef@\poly@setEdge{\expandafter\poly@setEdge@\poly@list\poly@id}
136 \xydef@\poly@setEdge@#1@#2{\Edge@c={\polygonEdge#1@#2@}%
137  \expandafter\xdef\csname poly@cache#2%
138  \endcsname{\poly@cache}}
140 % Define the polygon framing operations
141 \xydefcsname@{frm[P]{-}}{\expandafter\draw@polyframe\the\Edge@c{-}}
142 \xydefcsname@{frm[P]{.}}{\expandafter\draw@polyframe\the\Edge@c{.}}

143 \xydefcsname@{frm[P]{=}}{\expandafter\draw@polyframe\the\Edge@c{=}}
146 \xydef@\draw@polyframe\polygonEdge#1@#2@#3{%
147  \def\poly@dir{#3}%
148  \def\poly@list{#1@}%
149  \def\poly@id{#2}%
150  \edef\poly@cache{\csname poly@cache\poly@id\endcsname}%
151  \draw@polygon}
153 % A polygon is maintained as a list of relative positions, as follows:
154 %    poly@list = Xdimen_0,Ydimen_0;...;Xdimen_n,Ydimen_n @
155 % The list is closed, i.e., the first and last element coincide
156 % Each polygon has an id storred in \poly@id
157 % Each polygon caches the result of the last intersection operation
158 %  as d@x,d@y,x1,y1,x2,y2 where the first two values define the slope
159 %  and the two sets of points are the two intersection points
160 %  These values are storred in \poly@cache<id>.

161 %
162 %

163 % Helper function for dealing with polygon lists
165 % Map over a polygon list. Make sure you define
166 % \let\poly@map@next=\poly@map before. Then, you can define
167 % \let\poly@map@next=\poly@map@stop if you want to stop the traversal
169 \xydef@\poly@empty{}
170 \xydef@\poly@map#1#2,#3;#4@{%
171  #1{#2}{#3}%
172  \def\tmp@{#4}%
173  \ifx \poly@empty\tmp@ \else
174  \poly@map@next#1#4@%
175  \fi

176 }

178 \xydef@\poly@map@stop#1@{}
180 \xydef@\poly@mapExpand#1#2{%
181  \edef\tmp@{\noexpand\poly@map\noexpand #1#2}%
182  \tmp@}
184 % Parse a polygon definition
186 \xydef@\poly@parse #1,{%
187 \ifx #1\relax %Done. Copy the head of the list at its end
188  \poly@close
189  \let\next@=\relax
190 \else
191  % Save everything
192  \save@
193  % Process the position using POS
194  \POS #1%
195  % Now add the new c to the list
196  \edef\tmp@{{\the\X@c}{\the\Y@c}}%
197  \expandafter\poly@append\tmp@

198  \restore
199  \let\next@=\poly@parse % continue parsing
200 \fi
201 \next@

202 }

203  % Append to the list of polygon points
204 \xydef@\poly@append#1#2{\expandafter\poly@append@\poly@list{#1,#2;}}
205 \xydef@\poly@append@#1@#2{\global\def\poly@list{#1#2@}}
207  % Close the polygon
208 \xydef@\poly@close{\expandafter\poly@close@\poly@list}
209 \xydef@\poly@close@#1,#2;#3@{\poly@append{#1}{#2}}
211 % Draw a polygon at the current location
213 \xydef@\draw@polygon{% First separate the head
214 %  \W@{Drawing polygon \poly@list}\xy@showthe c{ Centered at}%
215 \save@
216  % Set the origin to point at the reference point
217  \X@origin=\X@c \Y@origin=\Y@c
218  \poly@setp % Set p at the beginning of the polygon and set poly@rest
219  % Zero the edges
220  \U@c=\z@\R@c=\z@\D@c=\z@\L@c=\z@\U@p=\z@\R@p=\z@\D@p=\z@\L@p=\z@
221  \Edge@c={\zeroEdge}\Edge@p={\zeroEdge}%
222  \let\poly@map@next=\poly@map
223  \poly@mapExpand\poly@drawseg\poly@rest
224 \restore

225 }

227  % Set p to the first element. Requires the origin to be
228  % at the reference point
229 \xydef@\poly@setp{\expandafter\poly@setp@\poly@list}
230 \xydef@\poly@setp@#1,#2;#3@{%
231  \X@p=#1\advance\X@p\X@origin \Y@p=#2\advance\Y@p\Y@origin%
232  \global\def\poly@rest{#3@}}
234 \xydef@\poly@drawseg#1#2{%
235 \dimen@=#1\X@c=\the\dimen@\advance\X@c \X@origin
236 \dimen@=#2\Y@c=\the\dimen@\advance\Y@c \Y@origin
237 %  \W@{Next segment is at offset #1,#2 and absolute \the\X@c,\the\Y@c}%
238 \expandafter\connect@\expandafter\dir\poly@dir%
239 \X@p=\X@c\Y@p=\Y@c}
241 % Polygonal edge
242 % Requires c to be the reference point
243 \xydef@\polygonEdge#1@#2@#3{%
244 \def\poly@list{#1@}%
245 \def\poly@id{#2}%
246 \edef\poly@cache{\csname poly@cache\poly@id\endcsname}%
247 \ifcase#3\relax
248  \DN@{\polygonEdge@Inters
249 %          \ifpoly@badinters
250 %             \xyerror@{Could not find intersection for polygon}\fi

251  }%0
252 \or \DN@{\polygonEdge@Under}%1
253 \or \DN@{\polygonEdge@Dist}%2
254 \or \DN@{\rectangleProp@}%3  I do not understand Prop!
255 \or \DN@{\polygonEdge@Inner}%4
256 \or \DN@{\polygonEdge@Outer}%5
257 \else \DN@{}\fi
258 \next@}
261 \newif\ifpoly@badinters
263 \xydef@\polygonEdge@Inters{%
264 %  \W@{Edge intersection with (\the\X@c, \the\Y@c) -> (\the\X@p,\the\Y@p)}%
265 %  \W@{ for polygon: \poly@id}%
266 %  \W@{ with list: \poly@list}%
267 %  \W@{ with cache: \poly@cache}%
268 % Check the cache first
269 \ifx\poly@cache\poly@empty
270  \poly@intersdoit
271 \else
272  \expandafter\poly@intersprobecache\poly@cache @%
273 \fi
274 %  \xy@showthe c{Inters res}%

275 }
277 %

278 % Redefine poly@cachehit to poly@cachehitdisable to diable polygon caching
279 \xydef@\poly@cachehit#1#2{%
280 %    \W@{ intersection point found in cache}%
281  \X@c=#1\Y@c=#2}
283 \xydef@\poly@cachehitdisable#1#2{\poly@intersdoit}
284 %\let\poly@cachehit=\poly@cachehitdiasable% Uncomment this line to disable $
287 % Probes the cache

288 %

289 \xydef@\poly@intersprobecache#1,#2,#3,#4,#5@{%
290 \dimen@=#1\advance\dimen@-\d@X
291 \ifdim\zz@\dimen@
292  \dimen@=#2\advance\dimen@-\d@Y
293  \ifdim\zz@\dimen@
294  \poly@cachehit{#3}{#4}
295  \else
296  \poly@intersdoit
297  \fi
298  \else
299  \poly@intersdoit
300  \fi

301 }

304 % Computes the intersection between the line cp and the edge.
305 % Both intersection points are stored in the cache, the one in the

306 % direction towards p first.
307 \xydef@\poly@intersdoit{%
308 %  \W@{ intersection not in cache. Computing it}%
309 % Save A@ and B@ because we cannot change them
310 \edef\polyoldA@{\the\A@}\edef\polyoldB@{\the\B@}%
311 % Initialize the intersection points
312 \def\poly@intersneg{}\def\poly@interspos{}%
313 \save@
314  \poly@setorigin % Set origin at the beginning of the polygon and
315  % set poly@rest
316  \def\zeroDivide@{\poly@badinterstrue}% Handle the division by zero except.
317  \let\poly@map@next=\poly@map
318  \poly@mapExpand\poly@interseg\poly@rest
319  \ifx\poly@intersneg\poly@empty
320  \poly@badinterstrue
321  \else
322  \ifx\poly@interspos\poly@empty
323  \poly@badinterstrue
324  \else
325  \poly@badintersfalse
326  \fi
327  \fi
328 \restore
329 \A@=\polyoldA@\B@=\polyoldB@ % Restore A@ and B@
330 \ifpoly@badinters \else
331  \edef\tmp@{\poly@interspos,\poly@intersneg @}%
332  \expandafter\poly@intersfinish\tmp@
333 \fi

334 }

336 \xydef@\poly@intersfinish#1,#2,#3@{%
337 \X@c=#1\Y@c=#2\relax
338 \xdef\poly@cache{\the\d@X,\the\d@Y,#1,#2,#3}%
339 \poly@setEdge

340 }

343  % Set origin to the first point. Define poly@rest
344  % Requires c to be set to the reference point
345 \xydef@\poly@setorigin{\expandafter\poly@setorigin@\poly@list}
346 \xydef@\poly@setorigin@#1,#2;#3@{%
347  \X@origin=#1\advance\X@origin\X@c \Y@origin=#2\advance\Y@origin\Y@c%
348  \global\def\poly@rest{#3@}}

353 %

354 % Compute one intersection with a given edge
355 % c is set to the reference point, p is set to the end of the ray
356 % origin is set to the start of the segment
357 \xydef@\poly@interseg#1#2{%
358 % Default is no intersection
359 %  \W@{ Intersection with edge (\the\X@origin,\the\Y@origin) -> (#1,#2)}%

360 % Compute the absolute values
361 \dimen@=#1\advance\dimen@\X@c \edef\poly@saveXcinters{\the\dimen@}%
362 \dimen@=#2\advance\dimen@\Y@c \edef\poly@saveYcinters{\the\dimen@}%
363 \save@
364  \poly@badintersfalse
365  % Set R@c and U@c to the distance to end of segment
366  \R@c=\poly@saveXcinters \advance\R@c -\X@origin
367  \U@c=\poly@saveYcinters \advance\U@c -\Y@origin
368  % Now call intersect to set X@c and Y@c to the intersection point
369  \intersect@
370  \A@=\X@c \B@=\Y@c % Save result
371 \restore
372 \ifpoly@badinters
373 %      \W@{ \space failed after intersect}%
374 \else
375 %      \W@{ \space after intersect@ (\the\A@,\the\B@)}%
376  % Verify that it is on the segment from origin to (#1, #2)
378 \poly@isonseg\X@origin\Y@origin\A@\B@\poly@saveXcinters\poly@saveYcinters
379  \ifpoly@badinters
380 %          \W@{ \space failed after seg check}%
381  \else
382  % Verify that (A,B) is on the ray from c to p
383  \poly@isonray\X@c\Y@c\A@\B@\X@p\Y@p
384  \ifpoly@badinters
385  % It is on the negative ray
386 %           \W@{ \space a negative intersection}%
387  \edef\poly@intersneg{\the\A@,\the\B@}%
388  \else
389 %           \W@{ \space a positive intersection}%
390  \edef\poly@interspos{\the\A@,\the\B@}%
391  \fi
392  \fi
393 \fi
394 % Set the origin to the start of the next segment
395 \X@origin=\poly@saveXcinters\Y@origin=\poly@saveYcinters

396 }
399 %

400 % Computes the distance from reference point to the intersection

401 %

402 \xydef@\polygonEdge@Dist{\xyerror@{Dist is not yet implemented for polygons}}

404 %

405 % Checks that #1 <= #2 <= #3 or that #3 <= #2 <= #1
406 % Sets ifpoly@badinters otherwise
407 % ifpoly@closedrange decides whether the second inequality is also checked
408 % All checks are done with a precision of 100*almostz@ =~ 5000sp = 0.08pt
409 \newif\ifpoly@closedrange
410 \xydef@\poly@isinrange#1#2#3{%
411 \ifpoly@badinters \else

412  \dimen@=#1\dimen@i=#2\dimen@ii=#3\relax
413 %    \W@{check if in \ifpoly@closedrange closed\else open\fi\space
414 %                      range  1=\the\dimen@,2=\the\dimen@i,3=\the\dimen@ii}%
415  \advance\dimen@ii -\dimen@ \advance\dimen@i -\dimen@
416  \ifdim\dimen@ii<0pt\relax
417  \ifdim\dimen@i>100\almostz@
418  \poly@badinterstrue
419  \fi
420  \dimen@i=-\dimen@i \dimen@ii=-\dimen@ii
421  \else
422  \ifdim\dimen@i<-100\almostz@\relax
423  \poly@badinterstrue
424  \fi
425  \fi
426  \ifpoly@closedrange
427  \advance\dimen@ii 100\almostz@
428  \ifdim\dimen@i>\dimen@ii
429  \poly@badinterstrue
430  \fi
431  \fi
432 %    \ifpoly@badinters \W@{ failed}\else\W@{ succeeded}\fi
433 \fi}

435 %

436 % Checks that (#3,#4) is on a segment defined by (#1,#2)->(#5,#6)
437 \xydef@\poly@isonseg#1#2#3#4#5#6{%
438 % Check X first
439 \poly@closedrangetrue
440 \poly@isinrange{#1}{#3}{#5}%
441 \poly@isinrange{#2}{#4}{#6}%

443 }
445 %

446 % Checks that (#3,#4) is on a ray defined by (#1,#2)->(#5,#6)
447 \xydef@\poly@isonray#1#2#3#4#5#6{%
448 % Check X first
449 \poly@closedrangefalse
450 \poly@isinrange{#1}{#3}{#5}%
451 \poly@isinrange{#2}{#4}{#6}%

453 }
454 %

455 % Test whether (Xp,Yp) is inside the polygon (or on the edge)
456 % Sets \ifInside@ accordingly
457 \xydef@\polygonEdge@Under{%
458 %  \W@{}\W@{Edge Under with c=(\the\X@c,\the\Y@c) and p=(\the\X@p,\the\Y@p)}%
459 %  \W@{ for polygon: \poly@list}%
460 % Save A@ and B@
461 \edef\polysaveA@under{\the\A@}\edef\polysaveB@under{\the\B@}%
462 % Save X@c and Y@c
463 \edef\poly@saveXcUnder{\the\X@c}\edef\poly@saveYcUnder{\the\Y@c}%

464 % Compute the intersection
465 \polygonEdge@Inters
466 \ifpoly@badinters% p is very close to c
467  \Inside@true
468 \else
469  \A@=\X@c\B@=\Y@c
470  % Restore c
471  \X@c=\poly@saveXcUnder\Y@c=\poly@saveYcUnder
472  % Now verify that the intersection point is on the ray c->p
473  \poly@isonseg\X@c\Y@c\X@p\Y@p\A@\B@
474  \ifpoly@badinters \Inside@false \else \Inside@true\fi
475  \A@=\polysaveA@under\B@=\poly@saveB@under
476 \fi
477 %  \ifInside@\W@{->inside}\else\W@{->outside}\fi

478 }
480 %

481 % Compute the inner rectangle

482 %

483 \xydef@\polygonEdge@Inner{%
484 %  \W@{}\W@{Edge Inner with (\the\X@c, \the\Y@c) -> (\the\X@p,\the\Y@p)}%
485 %  \W@{ for polygon: \poly@list}%
486 %  \W@{ with cache: \poly@cache}%
487 % Save everything except c
488 \enter@{\basefromthebase@ \pfromthep@ \DirectionfromtheDirection@}%
489  % Save c in Lc,Dc
490  \L@c=\X@c \D@c=\Y@c
491  % Compute the two intersection points
492  \polygonEdge@Inters
493  \ifpoly@badinters
494  \czeroEdge@
495  \else
496  % Save the result in Rc,Uc and in X@c,Y@c
497  \expandafter\poly@getinterspoints\poly@cache @%
498  % Now compute the inner rectangle centered
499  \ifdim\X@c>\R@c
500  \L@c=\R@c \R@c=\X@c
501  \else
502  \L@c=\X@c
503  \fi
504  \X@c=0.5\L@c \advance\X@c 0.5\R@c \advance\R@c -\X@c \L@c=\R@c
505  \ifdim\Y@c>\U@c
506  \D@c=\U@c \U@c=\Y@c
507  \else
508  \D@c=\Y@c
509  \fi
510  \Y@c=0.5\D@c \advance\Y@c 0.5\U@c \advance\U@c -\Y@c \D@c=\U@c
511  \Edge@c={\rectangleEdge}%
512  \fi
513 \leave@

514 %  \xy@showthe c{After inner}%

515 }

517 \xydef@\poly@getinterspoints#1,#2,#3,#4,#5,#6@{%
518 \R@c=#3\U@c=#4\X@c=#5\Y@c=#6}

520 %

521 % Compute the outer rectangle (set Uc,Dc,Lc,Rc and Edgec).
522 % Does not change Xc,YC

523 %

524 \xydef@\polygonEdge@Outer{%
525 %  \W@{Computing outer for \poly@list}\xy@showthe c{Before outer}%
526 % Save everything except c
527 \enter@{\basefromthebase@ \pfromthep@ \DirectionfromtheDirection@}%
528  \czeroEdge@ % Zero out c
529  \let\poly@map@next=\poly@map
530  \poly@mapExpand\poly@findextent\poly@list
531  \Edge@c={\rectangleEdge}%
532 \leave@
533 %  \xy@showthe c{After outer}

534 }

536 \xydef@\poly@findextent#1#2{%
537 %  \xy@showthe c{Before find extent}%
538 %  \W@{ extx=#1, exty=#2}%
539 \dimen@=#1\dimen@=\the\dimen@% it fails if I remove the second assign
540 \ifdim\dimen@>\R@c \R@c=\dimen@ \fi
541 \ifdim -\dimen@>\L@c \L@c=-\dimen@ \fi
542 \dimen@=#2\dimen@=\the\dimen@% it fails if I remove the second assign
543 \ifdim\dimen@>\U@c \U@c=\dimen@ \fi
544 \ifdim -\dimen@>\D@c \D@c=-\dimen@ \fi
545 %  \xy@showthe c{ After extent}%

546 }

548 % Change to account for polynomial shapes, in addition to circular ones

549 %

550 \xydef@\Fshape@#1:{\def\whichframe@@{{#1}}\let\whichoptions@@=\empty
551 \DN@{{}}\ifx\whichframe@@\next@ \def\whichframe@@{{-}}\fi
552 \expandafter\xyFN@\expandafter\Fshape@whichframe\the\Edge@c}
554 \xydef@\Fshape@whichframe{%
555 \ifx\next\circleEdge
556  \edef\whichframe@@{[o]\whichframe@@}%
557  \DN@##1{\xyFN@\Fshape@i}%
558 \else
559 \ifx\next\polygonEdge
560  \edef\whichframe@@{[P]\whichframe@@}%
561  \DN@\polygonEdge##1@##2@{\xyFN@\Fshape@i}%
562 \else
563  \DN@##1{\xyFN@\Fshape@i}%
564 \fi\fi
565 \next@

568 \xyendinput

Bug: This code should be merged with the ‘frame’ and ‘poly’ options.

The example at the end of §?? illustrates the extensions.

581 % $Log$
582 % Received from George.

Features

This chapter describes the options that support facilities that can be obtained using the kernel and extensions yet are much easier to obtain using the provided special syntax.

3.1 All features

Vers. 3.3 by Kristoffer H. Rose ⟨krisrose@brics.dk⟩

As a special convenience, this feature loads a subset of XY-pic,^{1} namely the extensions: curve (cf. §2.1), frame (§2.2), cmtip (§2.3), line (§2.4), rotate (§2.5), color (§2.6), and the following features: matrix (§3.5), arrow (§3.3), and graph (§3.6).

1 %% $Id: xyall.doc,v 3.3 1996/12/19 03:31:56 krisrose Exp $
2 %%
3 %% Xy-pic ``All features'' option.
4 %% Copyright (c) 1993-1996 Kristoffer H. Rose <krisrose@brics.dk>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi

1The name ‘all’ hints at the fact that these were all the available options at the time ‘all’ was added.

26 \xyprovide{all}{All features}{\stripRCS$Revision: 3.3 $}%
27 {Kristoffer H.~Rose}{krisrose@brics.dk}%
28 {BRICS/Computer Science, University of Aarhus, Ny Munkegade, building 540,
29  DK--8000 Aarhus~C}

Here we go:

47 \xyrequire{curve}
48 \xyrequire{frame}
49 \xyrequire{cmtip}
50 \xyrequire{line}
51 \xyrequire{rotate}
52 \xyrequire{color}
54 \xyrequire{matrix}
55 \xyrequire{arrow}
56 \xyrequire{graph}

That is all.

62 \xyendinput
64 % $Log: xyall.doc,v $
65 % Revision 3.3  1996/12/19 03:31:56  krisrose
66 % Maintenance release

67 %

68 % Revision 3.0  1995/07/07 20:14:21  kris
69 % Major release w/new User's Guide!

70 %

71 % Revision 2.13  1995/07/04  15:11:17  kris
72 % Ready to release v3?

73 %

74 % Revision 2.12  1994/10/25  11:34:25  kris
75 % Interim release just before v3 [works with AMS-LaTeX 1.2]...

76 %

77 % Revision 2.11  1994/07/05  10:37:32  kris
78 % Third 3beta release [bug fixes].
79 % Experimental graph feature included (for ECCT-94 presentation).

80 %

81 % Revision 2.9  1994/06/09  14:59:19  kris
82 % Release 3beta.

83 %

84 % NEW file to go in version 2.9!

3.2 Dummy option

Vers. 3.3 by Kristoffer H. Rose ⟨krisrose@brics.dk⟩

This option is provided as a template for new options, it provides neither features nor extensions but it does count how many times it is requested. Even though the option does nothing it still has a standard XY-pic header:

1 %% $Id: xydummy.doc,v 3.3 1996/12/19 03:31:56 krisrose Exp $

2 %%
3 %% Xy-pic ``Dummy'' option.
4 %% Copyright (c) 1993-1996 Kristoffer H. Rose <krisrose@brics.dk>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{dummy}{Dummy option}{\stripRCS$Revision: 3.3 $}%
27 {Kristoffer H.~Rose}{krisrose@brics.dk}%
28 {BRICS/Computer Science, University of Aarhus, Ny Munkegade, building 540,
29  DK--8000 Aarhus~C}

Next follows two declarations that are used to count the number of invocations:

46 \xynew@{count}\xydummyrequires@@

This is used by the option to output a message every time it is loaded with \xyoption or

\xyrequire:

53 \xyeveryrequest{dummy}{\global\advance\xydummyrequires@@\@ne
54 \W@{The `dummy' option was used \the\xydummyrequires@@\space times!}}

(\W@ is an XY-pic primitive that outputs its argument.)

Then the option ends:

62 \xyendinput

Finally xydummy.doc is maintained using RCS and thus contains the following revision log:

69 % $Log: xydummy.doc,v $
70 % Revision 3.3  1996/12/19 03:31:56  krisrose
71 % Maintenance release

72 %

73 % Revision 3.1  1995/09/05 20:31:32  kris
74 % Releasing!

75 %

76 % Revision 3.0  1995/07/07  20:14:21  kris
77 % Major release w/new User's Guide!

78 %

79 % Revision 2.13  1995/07/04  15:11:17  kris
80 % Ready to release v3?

81 %

82 % Revision 2.7  1994/03/08  02:06:01  kris
83 % Release 3alpha.

84 %

85 % NEW file to go in version 2.7!

3.3 Arrow and Path feature

Vers. 3.5 by Kristoffer H. Rose ⟨krisrose@brics.dk⟩

This feature provides XY-pic with the arrow paradigm presented in [12].

Note: \PATH command incompatibly changed for version 3.3 (the \ar command is unaffected). The basic concept introduced is the path: a connection that starts from c (the current object), ends

at a specified object, and may be split into several segments between intermediate specified objects that can be individually labelled, change style, have breaks, etc.

§3.3.1 is about the \PATH primitive, including the syntax of paths, and §3.3.2 is about the \ar customisation of paths to draw arrows using XY-pic directional objects.

Header:

1 %% $Id: xyarrow.doc,v 3.5 1997/05/28 13:05:01 krisrose Exp $
2 %%
3 %% Xy-pic ``Arrows and Paths'' feature.
4 %% Copyright (c) 1991-1997 Kristoffer H. Rose <krisrose@brics.dk>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{arrow}{Arrow and Path feature}{\stripRCS$Revision: 3.5 $}%
27 {Kristoffer H.~Rose}{krisrose@brics.dk}%

Syntax  Action
\PATH ⟨path⟩  interpret ⟨path⟩
\afterPATH{⟨decor⟩} ⟨path⟩  interpret ⟨path⟩ and then run ⟨decor⟩
⟨path⟩  ⟶ ~ ⟨action⟩ { ⟨stuff⟩ } ⟨path⟩  set ⟨action⟩3.3a to ⟨stuff⟩
| ~ ⟨which⟩ { ⟨labels⟩ } ⟨path⟩  add ⟨labels⟩ prefix for some segments3.3b
| ~ { ⟨stuff⟩ } ⟨path⟩  set failure continuation3.3c to ⟨stuff⟩
| ' ⟨segment⟩ ⟨path⟩  make straight segment3.3d
| ` ⟨turn⟩ ⟨segment⟩ ⟨path⟩  make turning segment3.3f
| ⟨segment⟩  make last segment3.3g
⟨turn⟩  ⟶ ⟨diag⟩ ⟨turnradius⟩  1/4 turn3.3f starting in ⟨diag⟩
| ⟨cir⟩ ⟨turnradius⟩  explicit turn3.3f
⟨turnradius⟩ ⟶ ⟨empty⟩  use default turn radius
| / ⟨dimen⟩  set turnradius to ⟨dimen⟩
⟨segment⟩ ⟶ ⟨path-pos⟩ ⟨slide⟩ ⟨labels⟩  segment3.3e with ⟨slide⟩ and ⟨labels⟩
⟨slide⟩  ⟶ ⟨empty⟩ | < ⟨dimen⟩ >  optional slide3.3h: ⟨dimen⟩ in the “above” direction
⟨labels⟩  ⟶ ^⟨anchor⟩ ⟨it⟩ ⟨alias⟩ ⟨labels⟩ label with ⟨it⟩3.3i above ⟨anchor⟩
| _⟨anchor⟩ ⟨it⟩ ⟨alias⟩ ⟨labels⟩ label with ⟨it⟩3.3i below ⟨anchor⟩
| | ⟨anchor⟩ ⟨it⟩ ⟨alias⟩ ⟨labels⟩ break with ⟨it⟩3.3j at ⟨anchor⟩
| ⟨empty⟩  no more labels

⟨anchor⟩ ⟶ - ⟨anchor⟩ | ⟨place⟩ label/break placed relative to the ⟨place⟩ where -

is a synonym for <>(.5)

⟨it⟩  ⟶ ⟨digit⟩ | ⟨letter⟩ | {⟨text⟩} | ⟨cs⟩ ⟨it⟩ is a default label3.3k
| * ⟨object⟩  ⟨it⟩ is an ⟨object⟩
| @ ⟨dir⟩  ⟨it⟩ is a ⟨dir⟩ectional
| [ ⟨shape⟩ ] ⟨it⟩  use [⟨shape⟩] for ⟨it⟩
⟨alias⟩  ⟶ ⟨empty⟩ | ="⟨id⟩"  optional name for label object3.3l

Figure 3.1: ⟨path⟩s

28 {BRICS/Computer Science, University of Aarhus, Ny Munkegade, building 540,
29  DK--8000 Aarhus~C}

3.3.1 Paths

59 \message{path,}

The fundamental commands of this feature are \PATH and \afterPATH that will parse the ⟨path⟩ according to the grammar in figure 3.1 with notes below.

Parsing: \afterPATH sets up \afterPATH@ and initialise all the actions (see note 3.3a below) before invoking the actual ⟨path⟩ parser. \PATH is just a dummy interface.

183 \xydef@\PATH{\afterPATH{}}

185 \xylet@\afterPATH@=\empty
187 \xydef@\afterPATH#1{\save
188 \DN@##1{\def\afterPATH@{\restore \def\afterPATH@{##1}#1}}%
189 \expandafter\next@\expandafter{\afterPATH@}%
190 \let\PATHfail@@=\empty
191 \let\PATHbefore@@=\empty
192 \let\PATHafter@@=\empty
193 \let\PATHlabelsevery@@=\empty
194 \let\PATHlabelsnext@@=\empty
195 \let\PATHlabelslast@@=\empty
196 \xy@{\afterPATH{#1}}{\def\PATHslide@@{\z@}}%
197 \def\PATHcontinue@@{\xyFN@\PATH@}%
198 \xyFN@\PATH@}

\PATH@ is the parser for ⟨path⟩: it eats the ⟨path⟩ until it fails and then calls the ‘failure continuation’ which will eventually become \empty which ends the parsing. Hack: The ‘\ifPATHsingle@’ switch switches the ⟨segment⟩ parsing off ; this is used by the graph feature to parse stand-alone ⟨slide⟩ ⟨labels⟩ sequences.

209 \xynew@{if}\ifPATHsingle@
211 \xydef@\PATH@{%
212 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PATH@}%
213 \else\ifPATHsingle@ \let\next@=\PATH@single
214 \else \let\next@=\PATH@normal \fi\fi \next@}
216 \xydef@\PATH@normal{%
217 \ifx ~\next \DN@ ~{\xyFN@\PATHsetting@}%
218 \else \addRQ@\ifx \next \addRQ@\DN@{\xy@'{}\xyFN@\PATHstraight@}%
219 \else \addLQ@\ifx \next \addLQ@\DN@{\xy@`{}\xyFN@\PATHturn@}%
220 \else\ifx \PATHfail@@\PATH@x \DN@{\xyFN@\PATHfinal@}%
221 \else
222 \DNii@{\let\PATHfail@@=\PATH@x \xyFN@\PATH@}%
223 \DN@{\expandafter\nextii@\PATHfail@@}%
224 \fi\fi\fi\fi \next@}

\PATHsetting@ just reads an ⟨action⟩ or ⟨which⟩ determining which action stuff to set and then does it—we treat the failure continuation as an action here even though it is not, strictly speaking. The four actions are explained in the appropriate notes below.

234 \xylet@\PATHfail@@=\empty
236 \xylet@\PATHbefore@@=\empty
237 \xylet@\PATHafter@@=\empty
239 \xylet@\PATHlabelsevery@@=\empty
240 \xylet@\PATHlabelsnext@@=\empty
241 \xylet@\PATHlabelslast@@=\empty
243 \xydef@\PATHsetting@{%
244 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PATHsetting@}%
245 \else\ifx \bgroup\next
246 \DN@##1{\xy@{~{##1}}{}\def\PATHfail@@{##1}\xyFN@\PATH@}%
247 \else \addEQ@\ifx \next
248 \addEQ@\DN@##1{\xy@{~={##1}}{}\def\PATHbefore@@{##1}\xyFN@\PATH@}%

249 \else \addLT@\ifx \next
250 \addLT@\DN@##1{\xy@{~<{##1}}{}\def\PATHlabelsnext@@{##1}\xyFN@\PATH@}%
251 \else \addGT@\ifx \next
252 \addGT@\DN@##1{\xy@{~>{##1}}{}\def\PATHlabelslast@@{##1}\xyFN@\PATH@}%
253 \else \addPLUS@\ifx \next
254 \addPLUS@\DN@##1{\xy@{~+{##1}}{}\def\PATHlabelsevery@@{##1}\xyFN@\PATH@}%
255 \else \ifx /\next
256 \DN@/##1{\xy@{~/{##1}}{}\def\PATHafter@@{##1}\xyFN@\PATH@}%
257 \else \addDASH@\ifx \next
258 \xywarning@{Obsolete `-' PATH <action> translated to `='.}%
259 \addDASH@\DN@##1{\xy@{~-{##1}}{}\def\PATHbefore@@{##1}\xyFN@\PATH@}%
260 \else
261 \xyerror@{Unknown \string~ setting: \meaning\next}%
262  {See the Xy-pic arrow feature documentation for help.}%
263 \fi\fi\fi\fi\fi\fi\fi\fi \next@}

Next the setup for straight segments including the last: they set \PATHinit@@ to initialise, i.e., slide, \PATHextra@@ to do what is needed after the = action, and finally \PATHpost@@ is set to any operations to be done after the entire segment is typeset but before the next is read. \PATHcontinue@@ is used internally to distinguish the ordinary segments from the last.

274 \xylet@\PATHinit@@=\empty
276 \xylet@\PATHextra@@=\empty
277 \xylet@\PATHpost@@=\empty
278 \xylet@\PATHcontinue@@=\empty
280 \xydef@\PATHstraight@{%
281 \def\PATHinit@@{\PATHinitstraight@}%
282 \let\PATHextra@@=\empty
283 \let\PATHpost@@=\empty
284 \let\PATHlabelsextra@@=\relax
285 \xy@@\pfromc@ \PATHafterPOS{\xyFN@\PATHsegment@}}
287 \xydef@\PATHfinal@{%
288 \def\PATHinit@@{\PATHinitstraight@}%
289 \def\PATHextra@@{\let\PATHcontinue@@=\afterPATH@}%
290 \let\PATHpost@@=\empty
291 \let\PATHlabelsextra@@=\PATHlabelsextralast@
292 \xy@@\pfromc@ \PATHafterPOS{\xyFN@\PATHsegment@}}
294 \xydef@\PATHlabelsextralast@{\let\PATHlabelsextra@@=\relax
295 \expandafter\xyFN@\expandafter\PATHlabels@\PATHlabelslast@@}
297 \xydef@\PATHinitstraight@{\xy@@{\setupDirection@ \dimen@=\PATHslide@@
298  \dimen@ii=-\sinDirection\dimen@
299  \ifPATHomitslide@@\else\advance\X@p\dimen@ii\fi \advance\X@c\dimen@ii
300  \dimen@ii= \cosDirection\dimen@
301  \ifPATHomitslide@@\else\advance\Y@p\dimen@ii\fi \advance\Y@c\dimen@ii
302  \PATHomitslide@@false \resetupDirection@}}

Setup for turning segments is in note 3.3f.

A ⟨segment⟩ is interpreted as follows after p has been set to the previous end object, c to the ⟨pos⟩ given at the start of the segment, and \PATHslide@@ to the slide:

312 \xydef@\PATHslide@@{\z@}
313 \xynew@{if}\ifPATHomitslide@@
315 \xydef@\PATHsegment@{%
316 \addLT@\ifx\next
317 \addGT@{\addLT@\DN@##1}{%
318  \xy@{<##1>}{\dimen@=##1\relax \edef\PATHslide@@{\the\dimen@}}%
319  \xyFN@\PATHsegment@@}%
320 \else \let\next@=\PATHsegment@@
321 \fi \next@}

1. Expand \PATHinit@@ (for straight segments this just sets up the direction and applies the ⟨slide⟩).

2. Expand \PATHaction={⟨stuff⟩} as set using ~={⟨stuff⟩}.

3. Sets \PATHcontinue@@ to any continuation set with ~{⟨stuff⟩}).

4. Construct list of ⟨labels⟩ specified by the user through ~⟨which⟩ setup. Those applicable to the present segment are inserted before the user’s ⟨labels⟩ in the sequence <>=.

5. Store p, c as start,end of segment.

6. Interpret ⟨labels⟩ (see below), including the ones added by the ~⟨when⟩… ⟨setup⟩.

\PATHsegment@@ performs this except the last two points:

346 \xydef@\PATHsegment@@{\PATHinit@@ \addEQ@\PATHaction@\PATHbefore@@ \PATHextra@@
347 \expandafter\toks@\expandafter{\PATHlabelsnext@@}\let\PATHlabelsnext@@=\empty
348 \expandafter\addtotoks@\expandafter{\PATHlabelsevery@@}%
349 \expandafter\def\expandafter\PATHlabels@@\expandafter{\the\toks@}%
350 \toks@={}\expandafter\xyFN@\expandafter\PATHlabels@\PATHlabels@@}

\PATHlabels@ parses all ⟨labels⟩ of a ⟨segment⟩. This sets \PATHlabelit@@ to the operation building the label in question. Then some parsing stores the tokens <>(.5) for each - in the ⟨anchor⟩ and finally passes control to the kernel ⟨place⟩ parser with these tokens as the head. This then in turn calls \PATHit@ that parses ⟨it⟩ and applies the chosen operation. After the last we continue with the accumulated subsegment actions.

362 \xylet@\PATHlabelit@@=\empty
364 \xydef@\PATHlabels@{%
365 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PATHlabels@}%
366 \else \ifx ^\next
367 \DN@##1{\xy@^{}\let\PATHlabelit@@=\PATHlabelabove@@
368  \DNii@{}\xyFN@\PATHanchor@}%
369 \else \ifx _\next
370 \DN@##1{\xy@_{}\let\PATHlabelit@@=\PATHlabelbelow@@
371  \DNii@{}\xyFN@\PATHanchor@}%
372 \else \ifx |\next
373 \DN@##1{\xy@|{}\let\PATHlabelit@@=\PATHlabelbreak@
374  \DNii@{}\xyFN@\PATHanchor@}%
375 \else \let\next@=\PATHfinishsegments@ \fi\fi\fi\fi \next@}
377 \xydef@\PATHanchor@{\begingroup \toks@={}\PATHanchor@i}

379 \xydef@\PATHanchor@i{%
380 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PATHanchor@i}%
381 \else\addDASH@\ifx \next
382 \addDASH@\DN@{\expandafter\addtotoks@\expandafter{\PATHanchor@toks}%
383  \xyFN@\PATHanchor@i}%
384 \else
385 \DNii@##1{\endgroup\afterPLACE{\xyFN@\PATHit@}##1}%
386 \DN@{\expandafter\nextii@\expandafter{\the\toks@}}%
387 \fi\fi \next@}
389 {\xyuncatcodes \gdef\next{<>(.5)}}
390 \xylet@\PATHanchor@toks=\next
392 \xylet@\PATHitshapes@@=\empty
394 \xydef@\PATHit@{\let\PATHitshape@@=\empty \xyFN@\PATHit@i}
396 \xydef@\PATHit@i{%
397 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PATHit@i}%
398 \else \ifx *\next \DN@*##1##{\PATHlabelit@@{!C##1}}%
399 \else \addAT@\ifx\next \addAT@\DN@##1##{\PATHlabelit@@{\dir##1}}%
400 \else \ifx [\next \DN@[##1]{%
401 \expandafter\def\expandafter\PATHitshape@@\expandafter{\PATHitshape@@[##1]}%
402 \xyFN@\PATHit@i}%
403 \else \DN@{\PATHlabelit@@{}}%
404 \fi\fi\fi\fi \next@}

The individual operations bound to \PATHlabelit@@ are discussed as appropriate in the notes. After the last break and label we typeset the last piece of the connection.

414 \xydef@\PATHfinishsegments@{%
415 \ifx\PATHlabelsextra@@\relax \expandafter\PATHfinishsegments@i
416 \else
417 \expandafter\PATHlabelsextra@@ \fi}
419 \xydef@\PATHfinishsegments@i{%
420 \xy@@{\Clast@@}\the\toks@ \toks@={}%
421 \xy@@\setupDirection@
422 \PATHpost@@ \PATHaction@/\PATHafter@@
423 \PATHcontinue@@}

Bug: The order of the breaks determines the order of the subsegments. This is maybe a feature.

Notes

3.3a. An ⟨action⟩ can be either of the characters =/. The associated ⟨stuff⟩ is saved and used to call

\PATHaction⟨action⟩{⟨stuff⟩}

before and after each segment (including all ⟨labels⟩) for = and /, respectively.

The default \PATHaction macro just expands to “\POS ⟨stuff⟩ \relax” thus ⟨stuff⟩ should be of the form ⟨pos⟩ ⟨decor⟩. The user can redefine this—in fact the \ar command described in §3.3.2 below is little more than a special \PATHaction command and a clever defaulting mechanism.

Here is the default \PATHaction:

454 \xydef@\PATHaction@default#1#2{\xy@{PATHaction#1{#2}}{}\POS#2\relax}

455 \xylet@\PATHaction=\PATHaction@default

It is called using \PATHaction@ to expand the action control sequences back to their ⟨stuff⟩ first:

462 \xydef@\PATHaction@#1#2{\expandafter\PATHaction\expandafter#1\expandafter{#2}}

3.3b. It is possible to include a number of default ⟨labels⟩ before the ⟨labels⟩ of the actual ⟨segment⟩ are interpreted, using ~⟨which⟩{⟨labels⟩}. The specified ⟨which⟩ determines for which segments the indicated ⟨labels⟩ should be prefixed as follows:

⟨which⟩ applied to…
<  next segment only
>  last segment only
=  every segment

(when several apply to the same segment they are inserted in the sequence <>+).

This is useful to draw connections with a ‘center marker’ in particular with arrows, e.g., the ‘mapsto’ example explained below can be changed into a ‘breakto’ example: typing

\xy*+{0}\PATH
 ~={**\dir{-}}
 ~>{|>*\dir{>}}
 ~+{|*\dir{/}}
 '(10,1)*+{1} '(20,-2)*+{2} (30,0)*+{3}
\endxy

will typeset

[figure: 0; 1; 2; 3]

Note, however, that what goes into ~+{… } is ⟨labels⟩ and thus not a ⟨pos⟩ – it is not an action in the sense explained above.

3.3c. Specifying ~{⟨stuff⟩} will set the “failure continuation” to ⟨stuff⟩. This will be inserted when the last ⟨segment⟩ is expected—it can even replace it or add more ⟨segment⟩s, i.e.,

\xy *+{0} \PATH ~={**\dir{-}}
  ~{'(20,-2)*+{2} (30,0)*+{3}} '(10,1)*+{1}
\endxy

is equivalent to

\xy *+{0} \PATH ~={**\dir{-}}
  '(10,1)*+{1} '(20,-2)*+{2} (30,0)*+{3}
\endxy

typesetting

[figure: 0; 1; 2; 3]

because when \endxy is seen then the parser knows that the next symbol is neither of the characters ~'` and hence that the last ⟨segment⟩ is to be expected. Instead, however, the failure continuation is inserted and parsed, and the ⟨path⟩ is finished by the inserted material.

Failure continuations can be nested:

\xy *+{0} \PATH ~={**\dir{-}}

 ~{~{(30,0)*+{3}}
 '(20,-2)*+{2}} '(10,1)*+{1}
\endxy

will also typeset the connected digits.

3.3d. A “straight segment” is interpreted as follows:

1. First p is set to the end object of the previous segment (for the first segment this is c just before the path command) and c is set to the ⟨pos⟩ starting the ⟨segment⟩, and the current ⟨slide⟩ is applied.

2. Then the = and < segment actions are expanded (in that sequence) and the < action is cleared. The resulting p and c become the start and end object of the segment.

3. Then all ⟨labels⟩ (starting with the ones defined as described in note 3.3b below).

The code expanding the actions is part of the parsing above.

3.3e. A segment is a part of a ⟨path⟩ between a previous and a new target given as a ⟨path-pos⟩: normally this is just a ⟨pos⟩ as described in §1.3 but it can be changed to something else by changing the control sequence \PATHafterPOS to be something other than \afterPOS.

589 \xylet@\PATHafterPOS@default=\afterPOS
590 \xylet@\PATHafterPOS=\PATHafterPOS@default

3.3f. A turning segment is one that does not go all the way to the given ⟨pos⟩ but only as far as required to make a turn towards it. The c is set to the actual turn object after a turning segment such that subsequent turning or other segments will start from there, in particular the last segment (which is always straight) can be used to finish a winding line.

What the turn looks like is determined by the ⟨turn⟩ form:

⟨empty⟩ Nothing between the ` and the ⟨pos⟩ is interpreted the same as giving just the ⟨diag⟩

last used out of a turn. ⟨diag⟩ Specifying a single ⟨diag⟩ d is the same as specifying either of the ⟨cir⟩cles d^or d_,

depending on whether the specified ⟨pos⟩ has its center ‘above’ or ‘below’ the line from p in the ⟨diag⟩onal direction.

⟨cir⟩ When a full explicit ⟨cir⟩cle is available then the corresponding ⟨cir⟩cle object is placed such that its ingoing direction is a continuation of a straight connection from p and the outgoing direction points such that a following straight (or last) segment will connect it to c (with the same slide).

Here is an example using all forms of ⟨turn⟩s:

[figure: base; A; a; B; b; C; c; d; e]

was typeset by

\xy <4pc,0pc>:(0,0)
 *+\txt{base}="base"

    \PATH ~={**\dir{-}?>*\dir{>}}
          `l   (-1,-1)*{A} ^a
          `     (1,-1)*{B} ^b
          `_ul  (1, 0)*{C} ^c
          `ul^l "base"     ^d
                "base"     ^e
   \endxy

Bug: Turns are only really resonable for paths that use straight lines like the one above.

Note: Always write a valid ⟨pos⟩ after a ⟨turn⟩, otherwise any following ^or _labels can confuse the parser. So if you intend the ^r in `^r to be a label then write `,^r, using a dummy , ⟨pos⟩ition.

We need to keep track of the current in and out ⟨diag⟩ directions as well as the current radius.

661 \xydef@\PATHlastout@@{3}

The startup routine is just a selection of the two kinds of ⟨turn⟩:

667 \xydef@\PATHturn@{\afterCIRorDIAG\PATHturn@cir\PATHturn@diag}

In both cases the trick is to set up a \PATHinit@@ method that typesets the right circle segment at the right location. The simplest one is when there is a full ⟨cir⟩ available because that should just be used directly. The only complication is that we forbid 180^{∘} turns:

677 \xydef@\PATHturn@cir{\toks@={\xy@@{%
678 \count@=\CIRin@@ \ifnum\count@<4\else\advance\count@-4\fi
679 \count@@=\CIRout@@ \ifnum\count@@<4\else\advance\count@@-4\fi
680 \ifnum\count@=\count@@ \xyerror@{<turn> cannot be half or full}{%
681 You asked for a <turn>ed segment with parallel in- and out-direction.^^J%
682 This is not allowed because it is not possible to position it uniquely.}\fi}}%
683 \edef\next@{{\CIRin@@}{\expandafter\noexpand\CIRorient@@}{\CIRout@@}}%
684 \expandafter\PATHturn@i\next@}

Procedure for ⟨diag⟩ turns: Builds initial part of \PATHinit@@ that computes the missing orient and out from in and the c passed through the segment. This initial segment should set orient as follows:

[figure: •; p; ⋮; ^{...}; ^; _]

i.e., as the sign of the inner product p⃗c · în, and set out as for the ⟨cir⟩cle in orient.

704 \xydef@\PATHturn@diag{\toks@={\xy@@{%
705  \setupDirection@ \count@=\CIRin@@ \dimen@=\xydashl@ \ABfromdiag@
706  \ifdim \sinDirection\A@>\cosDirection\B@ \def\CIRorient@@{\CIRacw@}%
707  \advance\count@\ifnum\count@<6 \tw@ \else -6\fi
708  \else \def\CIRorient@@{\CIRcw@}%
709  \advance\count@\ifnum\count@>\@ne -\tw@ \else 6\fi
710  \fi
711  \edef\CIRout@@{\the\count@}}}%
712 \edef\next@{{\CIRin@@}{}{}}%
713 \expandafter\PATHturn@i\next@}

\PATHturn@i is where \PATHinit@@ is defined to do the following:

l.775 Setup the default in, orient, and out as defined by the call from the above macros. Set radius parameter to the current turnradius value. The commands in \toks@ are run to do any last-minute fixing of the defaults.

l.779 The segment will leave p in direction in and pretend to be meeting c in direction out. Thus the center of the ⟨cir⟩cle object to be used for the actual ⟨turn⟩ object is located at the intersection of the line through p+radiusv̂_{in} in direction v⃗_{in} and the line through c+radiusv̂_{out} in direction v⃗_{out}. Here we compute p + Rv̂_{in} using R = radius if this is the initial turn and R = radius ± slide if it is a continuation turn.

l.782 Save p and base for later.

l.785 Compute c + radiusv̂_{out} and use the kernel \intersect@ primitive to compute the turn circle

segment center. l.793 However, if the intersection point lies on the ‘wrong side’ of p, i.e., if p⃗c · in is negative, then we should not use the intersection point but the point as close to p as possible because the connection from p to the turn should at least have zero length—in fact we set it to have 8sp length to make sure that a sugsegment is typeset!

l.806 Modify radius to use for the actual circle segment by the slide: either positively (for orient _) or negatively (for orient ^), and drop the circle segment (bypassing \cir to use the internal settings from above).

l.809 Store in \PATHpostpos@@ the true end of the circle segment and code to prevent the appli-

cation of the slide for the start of the next ⟨segment⟩. l.815 Move c to true beginning of the circle segment. l.818 Restore saved p and base, and slide p finally.

771 \xylet@\PATHpostpos@@=\empty
773 \xydef@\PATHturn@i#1#2#3{%
774 \DN@##1{\def\PATHinit@@{\xy@@{%
775  \def\CIRin@@{#1}\def\CIRorient@@{#2}\def\CIRout@@{#3}
776  \ifnum\CIRin@@=8 \let\CIRin@@=\PATHlastout@@ \fi
777  \R@=\turnradius@
778  ##1\relax}%
779  \xy@@{\count@=\CIRin@@
780  \ifPATHomitslide@@ \dimen@=-\PATHslide@@
781  \ABfromdiag@ \advance\X@p-\B@ \advance\Y@p\A@ \fi
782  \enter@{\pfromthep@ \basefromthebase@}}
783  \xy@@{\dimen@=\expandafter\ifx\CIRorient@@\CIRcw@-\fi\R@
784  \ABfromdiag@ \advance\X@p-\B@ \advance\Y@p\A@
785  \X@origin=\X@p \Y@origin=\Y@p}
786  \xy@@{\dimen@=\xydashl@ \ABfromdiag@ \R@c=\A@ \U@c=\B@
787  \count@=\CIRout@@
788  \dimen@=\expandafter\ifx\CIRorient@@\CIRcw@-\fi\R@
789  \ABfromdiag@ \advance\X@c-\B@ \advance\Y@c\A@
790  \dimen@=\xydashl@ \X@p=\X@c \Y@p=\Y@c
791  \ABfromdiag@ \advance\X@p-\A@ \advance\Y@p-\B@
792  \intersect@
793  \count@=\CIRin@@ \dimen@=\p@ \ABfromdiag@}
794  \xy@@{\edef\next@{\expandafter\removePT@\the\A@}%

795  \edef\nextii@{\expandafter\removePT@\the\B@}%
796  \A@=\X@c \advance\A@-\X@origin \B@=\Y@c \advance\B@-\Y@origin
797  \ifdim \next@\A@<-\nextii@\B@
798  \dontleave@ \cfromp@
799  \count@=\CIRin@@ \advance\count@\ifnum\count@<4 +4\else -4\fi
800  \dimen@=\xydashl@ \Directionfromdiag@
801  \the\Edge@c\z@
802  \count@=\CIRin@@ \dimen@=\expandafter\ifx\CIRorient@@\CIRcw@-\fi\R@
803  \ABfromdiag@ \advance\X@c-\B@ \advance\Y@c\A@
804  \dimen@=5sp \ABfromdiag@ \advance\X@c\A@ \advance\Y@c\B@
805  \fi
806  \dimen@ii=\expandafter\ifx\CIRorient@@\CIRacw@-\fi\PATHslide@@
807  \advance\R@\dimen@ii
808  \drop@\literal@{\hbox\bgroup\cir@i}}%
809  \xy@@{\X@p=\X@c \Y@p=\Y@c
810  \count@=\CIRout@@
811  \dimen@=\expandafter\ifx\CIRorient@@\CIRacw@-\fi\R@c
812  \ABfromdiag@ \advance\X@p-\B@ \advance\Y@p\A@
813  \edef\PATHpostpos@@{\X@c=\the\X@p \Y@c=\the\Y@p \noexpand\czeroEdge@
814  \noexpand\PATHomitslide@@true}}%
815  \xy@@{\count@=\CIRin@@
816  \dimen@=\expandafter\ifx\CIRorient@@\CIRacw@-\fi\R@c
817  \ABfromdiag@ \advance\X@c-\B@ \advance\Y@c\A@ \czeroEdge@}%
818  \xy@@{\leave@
819  \count@=\CIRin@@ \dimen@=\PATHslide@@
820  \ABfromdiag@ \advance\X@p-\B@ \advance\Y@p\A@
821  \edef\PATHlastout@@{\CIRout@@}%
822  \count@=\CIRout@@ \dimen@=\xydashl@ \Directionfromdiag@}}}%
823 \expandafter\next@\expandafter{\the\toks@}\toks@={}%
824 \let\PATHextra@@=\empty
825 \def\PATHpost@@{\xy@@\PATHpostpos@@}%
826 \let\PATHlabelsextra@@=\relax
827 \xyFN@\PATHturn@ii}

The final macro takes care of the v2.6 format for changing turnradius: using /⟨dimen⟩ right after the ⟨turn⟩.

834 \xydef@\PATHturn@ii{%
835 \ifx /\next
836 \DN@ /{\afterassignment\nextii@\dimen@=}%
837 \DNii@{%
838  \edef\next@{\noexpand\xy@@{\edef\noexpand\turnradius@{\the\dimen@}}}\next@
839  \xy@@\pfromc@ \PATHafterPOS{\xyFN@\PATHsegment@}}%
840 \else \DN@{\xy@@\pfromc@ \PATHafterPOS{\xyFN@\PATHsegment@}}\fi
841 \next@}

This just stores a ⟨diag⟩ vector of the specified lenght in <A,B> thus acting as an optimised version

   of \Directionfromdiag@:

849 \xydef@\ABfromdiag@{\ifcase\count@\relax
850  \A@=-.7071\dimen@ \B@=-.7071\dimen@ \or \A@=\z@      \B@=-\dimen@

851 \or \A@=+.7071\dimen@ \B@=-.7071\dimen@ \or \A@=\dimen@  \B@=\z@
852 \or \A@=+.7071\dimen@ \B@=+.7071\dimen@ \or \A@=\z@      \B@=+\dimen@
853 \or \A@=-.7071\dimen@ \B@=+.7071\dimen@ \or \A@=-\dimen@ \B@=\z@
854 \else\xybug@{impossible <diag>?}\fi}

The default used for turnradius can be set by the operation

\turnradius ⟨add op⟩ {⟨dimen⟩}

that works like the kernel \objectmargin etc. commands; it defaults to 10pt.

870 \xydef@\turnradius@{10pt}
872 \xydef@\turnradius{\afterADDOP{\Addop@@\turnradius@}}

Exercise 3.1: Typeset

[figure: A]

using ⟨turn⟩s.

3.3g. The last segment is exactly as a straight one except that the > action (if any) is executed (and cleared) just after the < action.

(The code implementing this is merged with the parsing.)

3.3h. “Sliding” a segment means moving each of the p, c objects in the direction perpendicular to the current direction at each.

(The code implementing this is merged with the parsing, using the \PATHslide@@ control sequence to hold the current slide.)

3.3i. Labelling means that ⟨it⟩ is dropped relative to the current segment using a ? ⟨pos⟩ition. This thus depends on the user setting up a connection with a ** ⟨pos⟩ as one of the actions—typically the = action is used for this (see note 3.3d for the details). The only difference between ^and _is that they shift the label in the ^respectively _direction; for straight segments it is placed in the “superscript” or “subscript” position.

The operations used by \PATHlabels@ to put labels above and below (with ^and _) are trivial, taking two arguments and placing the label immediately; for convenience the \drop head are named separately such that they may be redefined:

935 \xydef@\PATHlabelabove@#1#2{\droplabel@\belowDirection@{#1}{#2}%
936 \let\afteraliases@@=\empty \xyFN@\PATHlabelalias@}
938 \xydef@\PATHlabelbelow@#1#2{\droplabel@\aboveDirection@{#1}{#2}%
939 \let\afteraliases@@=\empty \xyFN@\PATHlabelalias@}
941 \xylet@\PATHlabelabove@@=\PATHlabelabove@
942 \xylet@\PATHlabelbelow@@=\PATHlabelbelow@
944 \xydef@\droplabel@#1#2#3{\xy@@{\enter@\DirectionfromtheDirection@}%
945 \DN@{#2}\ifx\next@\empty
946 \expandafter\xy@@ix@\expandafter{\PATHitshape@@\labelbox{#3}}%
947 \else \expandafter\xy@@ix@\expandafter{\PATHitshape@@#2{#3}}\fi
948 \xy@@{\setbox\z@=\expandafter\object\the\toks9 %
949 \advance\L@c\labelmargin@ \advance\R@c\labelmargin@
950 \advance\D@c\labelmargin@ \advance\U@c\labelmargin@

951 \setboxz@h{\kern\labelmargin@\boxz@\kern\labelmargin@}%
952 \A@=\X@c \B@=\Y@c #1\xydashl@ \the\Edge@c\thr@@
953 \advance\A@-\X@c \advance\B@-\Y@c \advance\X@c 2\A@ \advance\Y@c 2\B@
954 \ht\z@=\U@c \dp\z@=\D@c \dimen@=\L@c \advance\dimen@\R@c \wd\z@=\dimen@
955 \setbox\lastobjectbox@=\hbox{\X@c=\L@c \Y@c=\z@ \Drop@@}%
956 \drop@{\box\lastobjectbox@}{}%
957 \leave@}}
959 \xydef@\PATHlabelbreak@#1#2{%
960 \DN@{#1}\ifx\next@\empty \drop\labelbox{#2}\else \drop#1{#2}\fi
961 \def\afteraliases@@{\xy@@\Cbreak@@}\xyFN@\PATHlabelalias@}

These emulate the effect of the ⟨modifier⟩s !C+<2labelmargin> ⟨perp⟩!P ⟨unperp⟩ where ⟨perp⟩,⟨unperp⟩ are ^,_for ^-labels and _,^for _-labels. The last hack using \lastobjectbox@ aims at both setting that right and setting the label as an object (such that modifiers take effect) even though its placement is peculiar.

Labels will be separated from the connection by the labelmargin that you can set with the operation

                             \labelmargin ⟨add op⟩ {⟨dimen⟩}

that works like the kernel \objectmargin command; in fact labelmargin defaults to use objectmargin if not set.

985 \xylet@\labelmargin@=\objectmargin@
987 \xydef@\labelmargin{\afterADDOP{\Addop@@\labelmargin@}}

3.3j. Breaking means to “slice a hole” in the connection and insert ⟨it⟩ there. This is realized by typesetting the connection in question in subsegments, one leading to the break and one continuing after the break as described in notes 3.3a and 3.3d.

The special control sequence \hole is provided to make it easy to make an empty break.

1003 \xydef@\hole{\hbox{\dimen@=\objectmargin@ \kern2\dimen@
1004 \vrule height\dimen@ depth\dimen@ width\z@}}

Subsegments are typeset using the ‘\Cbreak@@’ method.

3.3k. Unless ⟨it⟩ is a full-fledged ⟨object⟩ (by using the * form), it is typeset using a \labelbox object (initially similar to \objectbox of basic XY-pic but using \labelstyle for the style).

Remark: You can only omit the {}s around single letters, digits, and control sequences.

1024 \xylet@\labelstyle=\scriptstyle
1025 \xydef@\labelbox#1{\hbox{$\m@th\labelstyle{#1}$}}

3.3l. A label is an object like any other in the XY-picture. Inserting an ⟨alias⟩ ="⟨id⟩" saves the label object as "⟨id⟩" for later reference.

Exercise 3.2: Typeset

[figure: A; label]

1052 \xydef@\PATHlabelalias@{%
1053 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PATHlabelalias@}%
1054 \else \addEQ@\ifx \next
1055 \addEQ@\DN@"##1"{\savealias@{##1}\xyFN@\PATHlabelalias@}%
1056 \else \DN@{\afteraliases@@\PATHlabels@}\fi\fi \next@}
1058 \xylet@\afteraliases@@=\empty
1060 %{\xyuncatcodes \gdef\next#1{\POS!C="#1"\relax}}
1061 \xydef@\savealias@#1{\xy@@{\enter@\cfromthec@
1062  \advance\X@c-\L@c \advance\L@c\R@c \L@c=.5\L@c \R@c=\L@c \advance\X@c\L@c
1063  \advance\Y@c-\D@c \advance\D@c\U@c \D@c=.5\D@c \U@c=\D@c \advance\Y@c\D@c
1064  \idfromc@{#1}\leave@}}

3.3.2 Arrows

1183 \message{\string\ar,}

Arrows are paths with a particularly easy syntax for setting up arrows with tail, stem, and head in the style of [12]. This is provided by a single ⟨decor⟩ation the syntax of which is described in figure 3.2 (with the added convention that a raised ‘*’ means 0 or more repetitions of the preceeding nonterminal).

Parsing: The \ar command effectively translates the ⟨arrow⟩ into a \PATH command that initialises the tail, stem, and head of it as required to get the desired ⟨arrow⟩.

The translation of the ⟨arrow⟩ is saved in the following variables:

1204 \xylet@\arvariant@@=\empty
1205 \xylet@\arstemprefix@@=\empty
1206 \xylet@\artail@@=\empty
1207 \xylet@\arstem@@=\empty
1208 \xylet@\arhead@@=\empty
1209 \xylet@\armodifiers@@=\empty
1210 \xylet@\arlabels@@=\empty
1211 \xylet@\arafterPOS@@=\empty
1212 \xylet@\arinit@@=\empty
1213 \xylet@\arexit@@=\empty
1215 \xylet@\arcomponent@@=\relax
1216 \xylet@\arcomponenttype@@=\relax
1218 \xylet@\afterar@@=\relax

\ar stores the defaults; it loads an intermediate command to avoid problems when used as first command in compiled matrix entry…

1226 \xydef@\ar{\relax\arSAFE}
1228 \xydef@\arSAFE{%
1229 \let\arvariant@@=\empty
1230 \def\arstemprefix@@{\dir}%
1231 \edef\artail@@{\arvariant@@{}}%
1232 \edef\arstem@@{\arvariant@@{-}}%
1233 \edef\arhead@@{\arvariant@@{>}}%
1234 \def\armodifiers@@{}%

1235 \def\arafterPOS@@{}%
1236 \def\arlabels@@{}%
1237 \def\arinit@@{}%
1238 \def\arexit@@{}%
1239 \let\PATHlabelabove@@=\PATHlabelabove@
1240 \let\PATHlabelbelow@@=\PATHlabelbelow@
1241 \xyFN@\ar@}

\ar@ is where we parse the sequence of ⟨form⟩s and continue with typesetting the arrow afterwards.

1248 \xydef@\ar@{%
1249 \ifx \space@\next \expandafter\DN@\space{\xyFN@\ar@}%
1250 \else \addAT@\ifx\next \addAT@\DN@{\xyFN@\ar@form}%
1251 \else\ifx |\next
1252 \DN@ |{\ar@anchor|}%
1253 \else\ifx ^\next
1254 \DN@ ^{\ar@anchor^}%
1255 \else\ifx _\next
1256 \DN@ _{\ar@anchor_}%
1257 \else \let\next@=\ar@x \fi\fi\fi\fi\fi \next@}

Note: Makes use of the new compilation principle to parse a ⟨place⟩ vacuously…

1264 \xydef@\addtoarinit@#1{%
1265 \expandafter\def\expandafter\arinit@@\expandafter{\arinit@@ #1}}
1267 \xydef@\addtoarlabels@#1{%
1268 \expandafter\def\expandafter\arlabels@@\expandafter{\arlabels@@ #1}}
1270 \xydef@\ar@anchor#1{\begingroup
1271 \def\PATHlabelit@@##1##2{%
1272 \DN@{##1}\ifx\next@\empty
1273 \DN@####1{\expandafter\endgroup\expandafter\addtoarlabels@
1274  \expandafter{\the\toks@####1{##2}}\xyFN@\ar@}%
1275 \else
1276 \DN@####1{\expandafter\endgroup\expandafter\addtoarlabels@
1277  \expandafter{\the\toks@*!C####1##1{##2}}\xyFN@\ar@}\fi
1278 \expandafter\next@\expandafter{\PATHitshape@@}}%
1279 \toks@={#1}%
1280 \def\xy@##1##2{\addtotoks@{##1}}\change@oxy@\xy@ \let\xy@@ix@=\eat@
1281 \DNii@{}\xyFN@\PATHanchor@}

\ar@form handles one ⟨form⟩:

1287 \xydef@\ar@form{%
1288 \ifx \space@\next \expandafter\DN@\space{\xyFN@\ar@form}%
1289 \else\ifx ^\next \DN@ ^{\xyFN@\ar@style}\edef\arvariant@@{\string^}%
1290 \else\ifx _\next \DN@ _{\xyFN@\ar@style}\edef\arvariant@@{\string_}%
1291 \else\ifx 0\next \DN@ 0{\xyFN@\ar@style}\def\arvariant@@{0}%
1292 \else\ifx 1\next \DN@ 1{\xyFN@\ar@style}\def\arvariant@@{1}%
1293 \else\ifx 2\next \DN@ 2{\xyFN@\ar@style}\def\arvariant@@{2}%
1294 \else\ifx 3\next \DN@ 3{\xyFN@\ar@style}\def\arvariant@@{3}%
1295 \else\ifx \bgroup\next \let\next@=\ar@style
1296 \else\ifx [\next \DN@[##1]{\ar@modifiers{[##1]}}%]
1297 \else\ifx *\next \DN@ *{\ar@modifiers}%

1298 \else\addLT@\ifx\next \let\next@=\ar@slide
1299 \else\ifx /\next \let\next@=\ar@curveslash
1300 \else\ifx (\next \let\next@=\ar@curveinout %)
1301 \else\addRQ@\ifx\next \addRQ@\DN@{\ar@curve@}%
1302 \else\addLQ@\ifx\next \addLQ@\DN@{\xyFN@\ar@curve}%
1303 \else\addDASH@\ifx\next \addDASH@\DN@{\defarstem@-\xyFN@\ar@}%
1304 \else\addEQ@\ifx\next \addEQ@\DN@{\def\arvariant@@{2}\defarstem@-\xyFN@\ar@}%
1305 \else\addDOT@\ifx\next \addDOT@\DN@{\defarstem@.\xyFN@\ar@}%
1306 \else\ifx :\next \DN@:{\def\arvariant@@{2}\defarstem@.\xyFN@\ar@}%
1307 \else\ifx ~\next \DN@~{\defarstem@~\xyFN@\ar@}%
1308 \else\ifx !\next \DN@!{\dasharstem@\xyFN@\ar@}%
1309 \else\ifx ?\next \DN@?{\ar@upsidedown\xyFN@\ar@}%
1310 \else \let\next@=\ar@error
1311 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
1313 \xydef@\defarstem@#1{\edef\arstem@@{\arvariant@@{\string#1}}%
1314 \DNii@##1##{\next@}%
1315 \edef\next@##1{\def\noexpand\artail@@{\arvariant@@{##1}}}%
1316 \expandafter\nextii@\artail@@
1317 \edef\next@##1{\def\noexpand\arhead@@{\arvariant@@{##1}}}%
1318 \expandafter\nextii@\arhead@@}
1320 \xydef@\dasharstem@{%
1321 \DN@##1##{\nextii@{##1}}\DNii@##1##2{\def\arstem@@{##1{##2##2}}}%
1322 \expandafter\next@\arstem@@}
1324 \xydef@\ar@error#1{\xyerror@{Illegal <form>ation (\meaning\next)}{}%
1325 \xyFN@\ar@}

\ar@i sets the remaining defaults and then allows \ar@ii-iv to pick up any tail, stem, and head using a $ as terminator.

1332 \xydef@\ar@style{%
1333 \ifx \bgroup\next \def\artail@@{{}}%
1334 \edef\arstem@@{\arvariant@@{-}}\edef\arhead@@{\arvariant@@{>}}%
1335 \expandafter\ar@i
1336 \else \resetvariant@\artail@@ \resetvariant@\arstem@@ \resetvariant@\arhead@@
1337 \expandafter\xyFN@\expandafter\ar@ \fi}
1339 \xydef@\resetvariant@#1{%
1340 \DN@##1##{\DN@{##1}\ifx\next@\empty
1341 \DN@{\expandafter\nextii@\expandafter{\arvariant@@}}%
1342 \else \DN@{\nextii@{##1}}\fi \next@}%
1343 \DNii@##1##2{\def#1{##1{##2}}}%
1344 \expandafter\next@#1}
1346 \xydef@\ar@i#1{\DN@{#1}%
1347 \ifx\next@\empty \edef\arstem@@{\arvariant@@{}}\edef\arhead@@{\arvariant@@{}}%
1348 \DN@{\xyFN@\ar@}%
1349 \else
1350 \let\arcomponent@@=\ar@ii \let\arcomponenttype@@=\artip@
1351 \DN@{\xyFN@\arcomponent@#1$}%
1352 \fi \next@}
1354 \xydef@\ar@ii{\ifx $\next \let\next@=\ar@iv

1355 \else \expandafter\def\expandafter\artail@@\expandafter{\the\toks@}%
1356 \let\arcomponent@@=\ar@iii \let\arcomponenttype@@=\arconn@
1357 \DN@{\xyFN@\arcomponent@}\fi \next@}
1359 \xydef@\ar@iii{%
1360 \expandafter\def\expandafter\arstem@@\expandafter{\the\toks@}%
1361 \resetvariant@\artail@@
1362 \let\arcomponent@@=\ar@iv \let\arcomponenttype@@=\artip@
1363 \xyFN@\arcomponent@}
1365 \xydef@\ar@iv{%
1366 \expandafter\def\expandafter\arhead@@\expandafter{\the\toks@}%
1367 \ifx $\next \DN@ ${\xyFN@\ar@}%
1368 \else \xyerror@{illegal <arrow>: \meaning\next\space not valid}{}\fi \next@}

\ar@x is the final macro that passes control to the ⟨path⟩ interpreter. It is a bit clumsy because we must pass the right character tokens; it could definitely be more efficient by calling ⟨path⟩ internals directly…

1377 \xydef@\ar@x{%
1378 \let\arsavedPATHafterPOS@@=\PATHafterPOS \let\PATHafterPOS=\arafterPOS@
1379 \toks@={\ar@PATH}%
1380 \expandafter\addtotoks@\expandafter{\expandafter{\artail@@}}%#1
1381 \expandafter\addtotoks@\expandafter{\expandafter{\arstem@@}}%#2
1382 \expandafter\addtotoks@\expandafter{\expandafter{\arstemprefix@@}}%#3
1383 \expandafter\addtotoks@\expandafter{\expandafter{\arhead@@}}%#4
1384 \expandafter\addtotoks@\expandafter{\expandafter{\armodifiers@@}}%#5
1385 \expandafter\addtotoks@\expandafter{\expandafter{\arinit@@}}%#6
1386 \expandafter\addtotoks@\expandafter{\expandafter{\arexit@@}}%#7
1387 \expandafter\addtotoks@\expandafter{\expandafter{\arlabels@@}}%#8
1388 \addtotoks@{\afterar@@}%#9
1389 \expandafter\DNii@\expandafter{\the\toks@}\toks@={}%

1390 %

1391 %{\let\x=\expandafter \x\x\x\DNii@\x\x\x{\nextii@}\W@{RUN: \codeof\nextii@}}%

1392 %

1393 \nextii@}
1395 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{%
1396 \def\next{%
1397 \afterPATH{#9}%
1398 ~={#6\preconnect#5#3#2}%
1399 ~/{#7}%
1400 ~<{|<*h#5\dir#1}%
1401 ~>{|>*h#5\dir#4}%
1402 ~+{#8}%

1403 }%

1404 \next}}
1406 \xylet@\ar@PATH=\next
1408 \xydef@\arafterPOS@#1{%
1409 \arsavedPATHafterPOS@@{\let\PATHafterPOS=\arsavedPATHafterPOS@@
1410 \DN@{#1}\expandafter\next@\arafterPOS@@}}%
1412 \xylet@\arsavedPATHafterPOS@@=\relax

⟨tip⟩s and ⟨conn⟩ectors are interpreted by these that leave any ⟨variant⟩ in \toks@ii and the sequence of ⟨tipchar⟩s or ⟨connchar⟩s characters in \toks@:

The work is really done in \arcomponent@ that builds \toks@ with something conforming to the

\arcomponenttype@@ and then passes control to \arcomponent@@:

1424 \xydef@\arcomponent@{%
1425 \ifx ^\next      \toks@ii={^}\DN@ ^{\xyFN@\arcomponent@i}%
1426 \else\ifx _\next \toks@ii={_}\DN@ _{\xyFN@\arcomponent@i}%
1427 \else\ifx 1\next \toks@ii={1}\DN@ 1{\xyFN@\arcomponent@i}%
1428 \else\ifx 2\next \toks@ii={2}\DN@ 2{\xyFN@\arcomponent@i}%
1429 \else\ifx 3\next \toks@ii={3}\DN@ 3{\xyFN@\arcomponent@i}%
1430 \else\ifx \bgroup\next \expandafter\toks@ii\expandafter{\arvariant@@}%
1431 \let\next@=\arcomponent@i
1432 \else\ifx *\next \DN@*##1##{\arcomponent@ii{##1}}%
1433 \else \expandafter\toks@ii\expandafter{\arvariant@@}\toks@={}%
1434 \let\next@=\arcomponenttype@@
1435 \fi\fi\fi\fi\fi\fi\fi
1436 \next@}
1438 \xydef@\arcomponent@i#1{\toks@={#1}\arcomponent@x}
1440 \xydef@\arcomponent@ii#1#2{\toks@={*#1{#2}}\xyFN@\arcomponent@@}
1442 \xydef@\artip@{%
1443 \addGT@\ifx\next \addGT@\addtotoks@ \addGT@\DN@{\xyFN@\artip@}%
1444 \else\addLT@\ifx\next \addLT@\addtotoks@ \addLT@\DN@{\xyFN@\artip@}%
1445 \else\ifx (\next \addtotoks@(\DN@({\xyFN@\artip@}%
1446 \else\ifx )\next \addtotoks@)\DN@){\xyFN@\artip@}%
1447 \else\ifx |\next \addtotoks@|\DN@|{\xyFN@\artip@}%
1448 \else\addLQ@\ifx\next \addLQ@\addtotoks@ \addLQ@\DN@{\xyFN@\artip@}%
1449 \else\addRQ@\ifx\next \addRQ@\addtotoks@ \addRQ@\DN@{\xyFN@\artip@}%
1450 \else\addPLUS@\ifx \next \addPLUS@\addtotoks@ \addPLUS@\DN@{\xyFN@\artip@}%
1451 \else\ifx /\next \addtotoks@/\DN@/{\xyFN@\artip@}%
1452 \else\ifcat A\noexpand\next \DN@##1{\addtotoks@{##1}\xyFN@\artip@}%
1453 \else\ifx\space@\next \addtotoks@{ }\expandafter\DN@\space{\xyFN@\artip@}%
1454 \else \let\next@=\arcomponent@x
1455 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
1457 \xydef@\arconn@{%
1458 \addDASH@\ifx\next \addDASH@\addtotoks@ \addDASH@\DN@{\xyFN@\arconn@}%
1459 \else\addEQ@\ifx\next \addEQ@\addtotoks@ \addEQ@\DN@{\xyFN@\arconn@}%
1460 \ifx\arvariant@@\empty \def\arvariant@@{2}\fi
1461 \else\addDOT@\ifx\next \addDOT@\addtotoks@ \addDOT@\DN@{\xyFN@\arconn@}%
1462 \else\ifx :\next \addtotoks@:\DN@:{\xyFN@\arconn@}%
1463 \ifx\arvariant@@\empty \def\arvariant@@{2}\fi
1464 \else\ifx ~\next \addtotoks@~\DN@~{\xyFN@\arconn@}%
1465 \else \let\next@=\arcomponent@x
1466 \fi\fi\fi\fi\fi \next@}
1468 \xydef@\arcomponent@x{%
1469 \DN@##1{\toks@=\expandafter{\the\toks@ii{##1}}}%
1470 \expandafter\next@\expandafter{\the\toks@}%
1471 \xyFN@\arcomponent@@}

Notes

3.3m. Building an ⟨arrow⟩ is simply using the specified directionals (using \dir of §1.6.1) to build a path: the first ⟨tip⟩ becomes the arrow tail of the arrow, the ⟨conn⟩ection in the middle becomes the arrow stem, and the second ⟨tip⟩ becomes the arrow head. If a ⟨variant⟩ is given before the { then that variant \dir is used for all three. For example,

\xy\ar @^{(->} (20,7)\endxy

typesets

[figure]

Exercise 3.3: Typeset these arrows:

[figure: A; A′; A′′; A′′′; B; B′; B′′; B′′′]

The above is a flexible scheme when used in conjunction with the kernel \newdir to define all sorts of arrowheads and -tails. For example,

\newdir{|>}{!/4.5pt/\dir{|}
            *:(1,-.2)\dir^{>}
            *:(1,+.2)\dir_{>}}

defines a new arrow tip that makes

\xy (0,0)*+{A}
 \ar @{=|>} (20,3)*+{B}
\endxy

typeset

[figure: A; B]

Notice that the fact that the directional uses only ⟨tipchar⟩ characters means that it blends naturally with the existing tips.

Exercise 3.4: Often tips used as ‘tails’ have their ink on the wrong side of the point where they are placed. Fortunately space is also a ⟨tipchar⟩ so we can define \dir{ >} to generate a ‘tail’ arrow. Do this such that

\xy (0,0)*+{A}="a", (20,3)*+{B}="b"
 \ar @{>->}  "a";"b" < 2pt>
 \ar @{ >->} "a";"b" <-2pt>
\endxy

typesets

[figure: A; B]

3.3n. Specifying a ⟨dir⟩ as a ⟨tip⟩ or ⟨conn⟩ means that \dir⟨dir⟩ is used for that ⟨tip⟩ or ⟨conn⟩. For example,

\xy\ar @{<^{|}>} (20,7)\endxy

typesets

[figure]

When using this you must specify a {} dummy ⟨dir⟩ectional in order to ignore one of the tail, stem, or tip components, e.g.,

\xy\ar @{{}{+}>} (20,7)\endxy

typesets

[figure]

In particular *⟨object⟩ is a ⟨dir⟩ so any ⟨object⟩ can be used for either of the tail, stem, or head component:

\xy\ar @{*{x}*{y}*{z}} (20,7)\endxy

typesets

x\begin{aligned}& & & & & & & y \\ & & & & & & y \\ & & & & & y \\ & & & & y \\ & & & y \\ & & y \\ & y \\ y \end{aligned}z

Note: A * introduces an ⟨object⟩ whereas the directional ‘^{•}’ is typeset by the ⟨dir⟩ {*}.

Exercise 3.5: Typeset

[figure]

using only one \ar command.

3.3o. Curving the arrow using /dℓ/, where d is a ⟨direction⟩ and ℓ a ⟨dimen⟩sion, makes the stem a curve which is similar to a straight line but has had it’s center point ‘dragged’ the distance ℓ in d:

[figure: ↑; ↓; u; d]

was typeset by

\xy
 \POS (0,10)  *\cir<2pt>{} ="a"
    , (20,-10)*\cir<2pt>{} ="b"
 \POS"a" \ar @/^1ex/ "b"|\uparrow
 \POS"a" \ar @/_1ex/ "b"|\downarrow
%
 \POS (20,10) *\cir<2pt>{} ="a"
    , (40,-10)*\cir<2pt>{} ="b"
 \POS"a" \ar @/u1ex/ "b"|u
 \POS"a" \ar @/d1ex/ "b"|d
\endxy

ℓ defaults to .5pc if omitted.

This is really just a shorthand for curving using the more general form described next: @/dℓ/ is the same as @`{{**{} ?+/d 2ℓ /}} which makes the (quadratic) curve pass through the point defined by the ⟨pos⟩ **{} ?+/dℓ/.

1673 \xydef@\ar@curveslash/#1/{\expandafter\ar@curve@\ar@slashing{#1}}
1675 \xydef@\ar@slashing#1{{\xy@{**{} ?+/#1/+/#1/ @+c}{\setupDirection@
1676 \vfromslide@{#1}%
1677 \X@c=2\X@c \advance\X@c\X@p \advance\X@c.5\d@X
1678 \Y@c=2\Y@c \advance\Y@c\Y@p \advance\Y@c.5\d@Y
1679 \czeroEdge@
1680 \spushc@}}}

3.3p. Using @(d_{2},d_{2}) where d_{1}, d_{2} are simple ⟨direction⟩s (as described in note 1.4l except it is not possible to use ()s) will typeset the arrow curved such that it leaves the source in direction d_{1} and enters the target from direction d_{2}.

Exercise 3.6: Typeset

[figure: ∘; •]

1708 {\xyuncatcodes \catcode`\#=6 %
1709 \gdef\next(#1,#2){{+/#1 3pc/,p+/#2 3pc/}}}
1710 \xylet@\ar@curveinout@=\next
1712 \xydef@\ar@curveinout{\expandafter\ar@curve@load\ar@curveinout@}

To Do: implement this efficiently and properly get rid of the no-() restriction!

3.3q. The final curve form is the most general one: @`{⟨control point lists⟩} sets the control points explicitly to the ones in the ⟨control point lists⟩ (where they should be separated by ,). See the curve extension described in §2.1 for the way the control points are used; when the control points list is parsed p is the source and c the target of the arrow.

Curving simply uses \crvi instead of \dir. The only tricky bit is to put the control points on the stack right.

1736 \xydef@\ar@curve{%
1737 \ifx \space@\next \expandafter\DN@\space{\xyFN@\ar@curve}%gobble spaces
1738 \else\ifx \bgroup\next \let\next@=\ar@curve@load
1739 \else\ifx "\next \DN@"##1"{\ar@curve@{"##1"}}%
1740 \else \xyerror@{@= <form> must be followed by \string"<id>\string" or
1741  {<control point list>}}{}%
1742 \fi\fi\fi \next@}
1744 {\xyuncatcodes \gdef\next#1#2{\def#1##1{#2{;@={##1}}}}}
1745 \next\ar@curve@load\ar@curve@
1747 \xydef@\ar@curve@#1{\curve@check
1748 \setcurvearinit@{#1}\setcurvearexit@\arexit@@
1749 \def\arstemprefix@@{\crvi}\xyFN@\ar@}
1751 {\xyuncatcodes \gdef\next#1{\save @(,#1\restore}}

1752 \xylet@\setcurvearinit@i=\next
1753 \xydef@\setcurvearinit@#1{%
1754 \expandafter\addtoarinit@\expandafter{\setcurvearinit@i{#1}}}
1756 {\xyuncatcodes \gdef\next#1{\def#1{\POS @i @) }}}
1757 \xylet@\setcurvearexit@=\next
1759 \xydef@\curve@check{%
1760 \xyerror@{Forms @/.../, @(...), and @`{...}, only available when curve
1761  extension loaded}{}}
1762 \xywithoption{curve}{\let\curve@check=\relax}

To Do: The parsing is trivial and should be extended to include more exotic control point forms.

3.3r. @[…] and @*{… } formations define what object ⟨modifier⟩s should be used when building objects that are part of the arrow. This is mostly useful in conjunction with extensions that define additional [⟨shape⟩] modifiers, e.g., if a [red] ⟨modifier⟩ changes the colour of an object to red then @[red] will make the entire arrow red; similarly if it is desired to make and entire arrow invisible then @*{i} can be used.

1781 \xydef@\ar@modifiers#1{%
1782 \expandafter\def\expandafter\armodifiers@@\expandafter{\armodifiers@@#1}%
1783 \xyFN@\ar@}

3.3s. @<D> will slide (each segment of) the arrow the dimension D as explained in note 3.3h.

1794 {\xyuncatcodes \catcode`\#=6 \catcode`\@=11 %
1795 \gdef\next<#1>{\def\arafterPOS@@{<#1>}\xyFN@\ar@}}
1796 \xylet@\ar@slide=\next

3.3t. @? reverse the meaning of ‘above’ and ‘below’ for this particular arrow.

1807 \xydef@\ar@upsidedown{\let\next=\PATHlabelabove@@
1808 \let\PATHlabelabove@@=\PATHlabelbelow@@ \let\PATHlabelbelow@@=\next}

All the features of ⟨path⟩s described above are available for arrows.

End & log

1823 \xyendinput
1825 % $Log: xyarrow.doc,v $
1826 % Revision 3.5  1997/05/28 13:05:01  krisrose
1827 % Fixed missing breaks bug.

1828 %

1829 % Revision 3.4  1997/05/18 01:14:25  krisrose
1830 % Essential bugfixes.

1831 %

1832 % Revision 3.3  1996/12/19 03:31:56  krisrose
1833 % Maintenance release

1834 %

1835 % Revision 3.2  1995/09/19  18:22:27  kris
1836 % Bug fix release.

1838 % Revision 3.1  1995/09/05  20:31:32  kris
1839 % Releasing!

1840 %

1841 % Revision 3.0  1995/07/07  20:14:21  kris
1842 % Major release w/new User's Guide!

1843 %

1844 % Revision 2.13  1995/07/04  15:11:17  kris
1845 % Ready to release v3?

1846 %

1847 % Revision 2.12  1994/10/25  11:34:25  kris
1848 % Interim release just before v3 [works with AMS-LaTeX 1.2]...

1849 %

1850 % Revision 2.11  1994/07/05  10:37:32  kris
1851 % Third 3beta release [bug fixes].
1852 % Experimental graph feature included (for ECCT-94 presentation).

1853 %

1854 % Revision 2.10  1994/06/15  12:55:07  kris
1855 % Second 3beta release: bug fixes.

1856 %

1857 % Revision 2.9  1994/06/09  14:59:19  kris
1858 % Release 3beta.

1859 %

1860 % Revision 2.8  1994/04/08  04:30:00  kris
1861 % Second (bug fix) 3alpha release.

1862 %

1863 % Revision 2.7  1994/03/08  10:25:18  kris
1864 % Release 3alpha.

1865 %

1866 % Revision 2.6.9.1  1994/03/07  04:22:46  kris
1867 % Last internal 3alpha and pre-2.7 release.

1868 %

1869 % NEW for version 2.7 based of path and arrow code in xypic.doc 2.6.1.1.

3.4 Two-cell feature

Vers. 3.3 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This feature is designed to facilitate the typesetting of curved arrows, either singly or in pairs, together with labels on each part and between. The intended mathematical usage is for typesetting categorical “2-cell” morphisms and “pasting diagrams”, for which special features are provided. These features also allow attractive non-mathematical effects.

Header:

1 %% $Id: xy2cell.doc,v 3.3 1996/12/18 14:21:23 ross Exp $
2 %%
3 %% Xy-pic ``2-cell'' feature.
4 %% Copyright (c) 1993-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.

8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this macro package; if not, write to the Free Software Foundation,
22 %% Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{2cell}{Two-cell feature}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

The 2-cell feature makes use of facilities from the ‘curve’ extension which is therefore automatically loaded.

49 \xyrequire{curve}\xycatcodes

3.4.1 Typesetting 2-cells in Diagrams

Categorical “2-cell” morphisms are used in the study of tensor categories and elsewhere. The morphisms are displayed as a pair of curved arrows, symmetrically placed, together with an orientation indicated by a short broad arrow, or Arrow. Labels may be placed on all three components.

64 \message{two-cells,}

Bug: This document still uses version 2-style commmands, as described in appendix B.1.

[figure: A; f; g; B]

\diagram
A\rtwocell^f_g &B\\
\enddiagram

[figure: A; f; α; h; β; g; B]

\diagram
A\ruppertwocell^f{\alpha}

  \rlowertwocell_h{\beta}
  \rto_(.35)g & B\\
\enddiagram

These categorical diagrams frequently have a matrix-like layout, as with commutative diagrams. To facilitate this there are control sequences of the form: \rtwocell , \ultwocell , \xtwocell , … analogous to the names defined in xyv2 for use in diagrams produced using xymatrix. As this involves the definition of 21 new control sequences, many of which may never be used, these are not defined immediately upon loading xy2cell. Instead the user must first specify \UseTwocells.

As in the second example above, just the upper or lower curved arrow may be set using control se-

quences of the form \..uppertwocell and \..lowertwocell. These together with the \..compositemap

family, in which two abutting arrows are set with an empty object at the join, allow for the construction of complicated “pasting diagrams” (see figure 3.3 for an example).

The following initialise the families of control sequences for use in matrix diagrams.

            \UseTwocells  two curves
            \UseHalfTwocells  one curve

\UseCompositeMaps 2 arrows, end-to-end

            \UseAllTwocells  (all the above)

126 \xydef@\UseTwocells{\definesupermorphism{twocell}{%
127 \xy@{start of 2-cell}{\begingroup}%
128 \twocell@}}
130 \xydef@\UseHalfTwocells{%
131 \definesupermorphism{uppertwocell}{%
132 \xy@{start of 2-cell}{\begingroup}%
133 \uppertwocell@}%
134 \definesupermorphism{lowertwocell}{%
135 \xy@{start of 2-cell}{\begingroup}%
136 \lowertwocell@}}
138 \xydef@\UseCompositeMaps{\definesupermorphism{compositemap}{%
139 \xy@{start composite-map}{\begingroup}%
140 \compositemap@}}
142 \xydef@\UseAllTwocells{%
143 \UseTwocells \UseHalfTwocells \UseCompositeMaps }

The families of connections are defined using the utility macro… \definesupermorphism which defines control sequences for morphisms between neighbouring cells, and next-to-neighbouring cells.

More distant cells use \xtwocell, \xcompositemap, etc. with ⟨hop⟩s e.g. \xtwocell[1,3] and

\xtwocell[llddd].

160 \xydef@\supermorphism#1[#2]#3{\def\afterMORPHISM{[#2]#3}#1}
161 \xydef@\afterMORPHISM{}
163 \xydef@\definesupermorphism#1#2{%
164 \expandafter\def\csname x#1\endcsname{\supermorphism{#2}}%
165 \expandafter\def\csname u#1\endcsname{\supermorphism{#2}[-1,0]{}}%
166 \expandafter\def\csname d#1\endcsname{\supermorphism{#2}[1,0]{}}%
167 \expandafter\def\csname l#1\endcsname{\supermorphism{#2}[0,-1]{}}%
168 \expandafter\def\csname r#1\endcsname{\supermorphism{#2}[0,1]{}}%

169 \expandafter\def\csname uu#1\endcsname{\supermorphism{#2}[-2,0]{}}%
170 \expandafter\def\csname dd#1\endcsname{\supermorphism{#2}[2,0]{}}%
171 \expandafter\def\csname ll#1\endcsname{\supermorphism{#2}[0,-2]{}}%
172 \expandafter\def\csname rr#1\endcsname{\supermorphism{#2}[0,2]{}}%
173 \expandafter\def\csname ur#1\endcsname{\supermorphism{#2}[-1,1]{}}%
174 \expandafter\def\csname ul#1\endcsname{\supermorphism{#2}[-1,-1]{}}%
175 \expandafter\def\csname dr#1\endcsname{\supermorphism{#2}[1,1]{}}%
176 \expandafter\def\csname dl#1\endcsname{\supermorphism{#2}[1,-1]{}}%
177 \expandafter\def\csname uul#1\endcsname{\supermorphism{#2}[-2,-1]{}}%
178 \expandafter\def\csname uur#1\endcsname{\supermorphism{#2}[-2,1]{}}%
179 \expandafter\def\csname ull#1\endcsname{\supermorphism{#2}[-1,-2]{}}%
180 \expandafter\def\csname urr#1\endcsname{\supermorphism{#2}[-1,2]{}}%
181 \expandafter\def\csname ddl#1\endcsname{\supermorphism{#2}[2,-1]{}}%
182 \expandafter\def\csname ddr#1\endcsname{\supermorphism{#2}[2,1]{}}%
183 \expandafter\def\csname dll#1\endcsname{\supermorphism{#2}[1,-2]{}}%
184 \expandafter\def\csname drr#1\endcsname{\supermorphism{#2}[1,2]{}}%
185 \expandafter\def\csname uull#1\endcsname{\supermorphism{#2}[-2,-2]{}}%
186 \expandafter\def\csname uurr#1\endcsname{\supermorphism{#2}[-2,2]{}}%
187 \expandafter\def\csname ddll#1\endcsname{\supermorphism{#2}[2,-2]{}}%
188 \expandafter\def\csname ddrr#1\endcsname{\supermorphism{#2}[2,2]{}}}

Alternatively 2-cells can be set directly in XY-pictures without using the matrix feature. In this case the above commands are not needed. This is described in §3.4.6.

Furthermore a new directional \dir{=>} can be used to place an “Arrow” anywhere in a picture, after the direction has been established appropriately. It is used with all of the 2-cell types.

205 \newdir{=>}{!/5pt/\dir{=}!/2.5pt/\dir{=}*!/-5pt/\dir2{>}}
207 \xydef@\arrowobject#1{\def\Arrowobject@{#1}}
208 \xydef@\Arrowobject@{\dir{=>}}

Default positions: These set up default values for the parameters which specify the position of each component as well as the flags to indicate what type of 2-cell is to be typeset.

\toks6 position of control point, normal to line \overline{pc} at midpoint
\toks5 position of central Arrow
\toks7 position of ^label
\toks8 position of _label
\toks3 flag for number of pieces...
f    \underline{f}ull: i.e. both curved arrows

                  o    \underline{o}ne: \uppertwocell or \lowertwocell
                  t    \underline{t}wo maps: \compositemaps

@ means to calculate from the value in \toks6, see \tw@cell@@@.

267 \xydef@\twocell@{\toks6={3.5}\toks5={@}\toks7={@}\toks8={@}\toks3={f}%
268 \tw@cell@ }
269 \xydef@\uppertwocell@{\toks6={7}\toks5={@}\toks7={@}\toks8={@}\toks3={o}%
270 \tw@cell@ }
271 \xydef@\lowertwocell@{\toks6={-7}\toks5={@}\toks7={@}\toks8={@}\toks3={o}%

272 \tw@cell@ }
273 \xydef@\compositemap@{\toks6={3.5}\toks5={@}\toks7={@}\toks8={@}\toks3={t}%
274 \tw@cell@ }

This collects together all the relevant data, and resolves the default positions.

281 \xydef@\tw@cell@@@{%
282 \expandafter\ifx\the\toks6\omit\relax\toks6={}\else

283 %

284 %    default position of label on upper arrow,
285 %    relative to where it meets the perpendicular bisector

286 %

287 \expandafter\ifx\expandafter @\the\toks7\relax\expandafter\dimen@\the\toks6\p@
288 \expandafter\if\the\toks3t\relax\dimen@=\p@
289 \else\expandafter\if\the\toks3o\divide\dimen@\tw@
290  \ifdim\dimen@<\z@ \dimen@ii-\p@ \advance\dimen@ii\dimen@
291  \dimen@=\dimen@ii \else \dimen@\p@ \fi
292  \else\dimen@\p@
293 \fi\fi
294 \edef\tmp@{\expandafter\removePT@\the\dimen@}%
295 \expandafter\toks\expandafter7\expandafter{\tmp@}\fi

296 %

297 %    default position of label on lower arrow,
298 %    relative to where it meets the perpendicular bisector

299 %

300 \expandafter\ifx\expandafter @\the\toks8\relax
301 \expandafter\dimen@\the\toks6\p@
302 \expandafter\if\the\toks3t\relax\dimen@\p@
303 \else\expandafter\if\the\toks3o\divide\dimen@\tw@
304  \ifdim\dimen@<\z@ \dimen@ii-\p@ \advance\dimen@ii\dimen@
305  \dimen@=\dimen@ii \else \dimen@\p@ \fi
306  \else\dimen@\p@
307 \fi\fi
308 \edef\tmp@{\expandafter\removePT@\the\dimen@}%
309 \expandafter\toks\expandafter8\expandafter{\tmp@}\fi

310 %

311 %  default position of the Arrow, relative to midpoint

312 %

313 \expandafter\ifx\expandafter @\the\toks5\relax
314 \expandafter\dimen@\the\toks6\p@
315 \expandafter\if\the\toks3o\divide\dimen@ by-4\relax
316  \else\dimen@\z@\fi
317 \edef\tmp@{\expandafter\removePT@\the\dimen@}%
318 \expandafter\toks\expandafter5\expandafter{\tmp@}\fi
319 \fi

320 %

321 %   possible modifications for module maps

322 %

323 \twocellmod@

324 %

325 %   pass all the parameters to  |\twocell@@@@|

326 %

327 \expandafter\if\the\toks3t\relax

328 %

329 %   composed maps:   ^: first map   _: second map

330 %

331 \edef\tmp@{.[\noexpand\twocell@@@@{\the\toks6}{\the\toks5}%
332  {\the\toks7}{\the\toks8}{\the\toks3}%
333  {\the\toks2}{\the\toks1}{\the\toks@}{\the\toks4}!!!].\afterMORPHISM}%
334 \else

335 %

336 %    curved arrow(s)

337 %

338 \edef\tmp@{.[\noexpand\twocell@@@@{\the\toks6}{\the\toks5}%
339  {\the\toks7}{\the\toks8}{\the\toks3}%
340  {\the\toks1}{\the\toks2}{\the\toks@}{\the\toks4}!!!].\afterMORPHISM}%
341 \fi
342 \toks@={\endgroup}%
343 \expandafter\def\expandafter\next@\expandafter{%
344 \expandafter\def\expandafter\twocellhead@\expandafter{\twocellhead@}}%
345 \expandafter\addtotoks@\expandafter{\next@}%
346 \expandafter\def\expandafter\next@\expandafter{%
347 \expandafter\def\expandafter\twocelltail@\expandafter{\twocelltail@}}%
348 \expandafter\addtotoks@\expandafter{\next@}%
349 \expandafter\addtotoks@\expandafter{\expandafter\twocellPATH\tmp@}%
350 \the\toks@ }%

See below for the possible forms of \twocellPATH.

Labels are placed labels on the upper and lower arrows, more correctly ‘anti-clockwise’ and ‘clockwise’, using ^and _. These are entirely optional with the following token, or grouping, giving the contents of the label. When used with \..compositemap the ^and _specify labels for the first and second arrows, respectively.

365 \xydef@\twocellstyle{\scriptstyle}
367 \xydef@\droptwocelllabel@#1{\xyFN@\droptwocelllabel@@#1@!}
368 \xydef@\droptwocelllabel@@{%
369 \ifx*\next\DN@*{\droptwocelldrop@}%
370 \else\DN@##1@!{\droptwocelltext@{##1}}%
371 \fi \next@ }
373 {\xyuncatcodes \gdef\next#1{\drop+!C{\twocellstyle #1}}}
374 \xylet@\droptwocelltext@=\next
376 \xydef@\droptwocelldrop@#1@!{\bgroup \let\xy@=\oxy@
377 \let\objectstyle=\twocellstyle \drop#1{}%
378 \edef\tmp@{\egroup \X@min=\the\X@min \X@max=\the\X@max
379 \Y@min=\the\Y@min \Y@max=\the\Y@max}\tmp@ }

Normally the label is balanced text, set in TEX’s math mode, with \twocellstyle setting the style. The default definition is given by …

   \def\twocellstyle{\scriptstyle}

This can be altered using \def in versions of TEX or \redefine in L^{A}TEX. However labels are not restricted to being simply text boxes. Any effect obtainable using the XY-pic kernel language can be set within an \xybox and used as a label. Alternatively if the first character in the label is * then the label is set as an XY-pic ⟨object⟩, as if with \drop<object> or *<object> in the kernel language. The current direction is tangential to the curved arrows. Extra braces are needed to get a * as the label,

as in ^{{{*}}} or _{{}*}.

The position of a label normal to the tangential direction can also be altered by nudging (see below). Although it is possible to specify multiple labels, only the last usage of each of ^and _is actually set, previous specifications being ignored.

Similarly a label for the central Arrow must be given, after the other labels, by enclosing it within braces {...}. An empty group {} gives an empty label; this is necessary to avoid misinterpretation of subsequent tokens. As above if the first character is * then the label is set as an XY-pic ⟨object⟩, the current direction being along the Arrow.

Parsing: Open a new group so the following registers can be used locally... \toks@=\toks0, \toks1, ..., \toks8 the final parameter set is stored briefly in \tmp@ before being used.

OPTIONS:

spaces are ignored

<     <num> determines position of curves control point
<0>  uses a single solid line,
<\omit> causes only the central Arrow (with label) to be set
\omit  omits the curved arrows, but allows their labels
^place “above” label (more correctly “anti-clockwise”)
_place “below” label (more correctly “clockwise”)
~'  change the arrowhead
~`  place/change the arrowtail

Label data e.g. ^{#1} _{#1} is stored temporarily in \toks@ then passed via \tw@@cell@@ to

\tw@cell@@ for further parsing, as: \the\toks@ @
   ~' and ~` change the values of \twocellhead@ and \twocelltail@ Normally \twocelltail@ is

{}, so ~` also changes a flag to indicate that \twocelltail@ is indeed required.

When the next token is a grouping {...} then it gives the label for the central Arrow. No other label specifications may follow.

Default head and tail ornaments...

453 \xydef@\twocellhead#1{\def\twocellhead@{#1}}
454 \xydef@\twocelltail#1{\def\twocelltail@{#1}}
455 \xydef@\twocellhead@{\dir{>}}
456 \xydef@\twocelltail@{}

clear \toks.. registers for the new connection labels.

462 \xywarnifdefined\twocellmod@
463 \xydef@\tw@cell@{\begingroup
464 \toks@={{}}\toks1={{}}\toks2={{}}\toks4={{}}%
465 \def\twocellmod@{}\xyFN@\tw@@cell@}%
467 \xydef@\tw@@cell@{%
468 \ifx\space@\next\expandafter\DN@\space{\xyFN@\tw@@cell@}%
469 \else\ifx\bgroup\next \let\next@=\toks@\afterassignment\tw@@cell@@
470 \else\ifx ^\next \DN@^##1{\toks@={##1}\nudgepos@71\tw@@cell@}%
471 \else\ifx _\next \DN@_##1{\toks@={##1}\nudgepos@82\tw@@cell@}%
472 \else\addLT@\ifx \next \addGT@{\addLT@\DN@##1}{%

473 \toks6={##1}\ifx\omit##1\relax\toks3={t}\toks5={0}\fi\xyFN@\tw@@cell@}%
474 \else\ifx\omit\next \DN@\omit{\omitarrows@\xyFN@\tw@@cell@}%
475 \else\ifx~\next \DN@~{\xyFN@\whichCurveObject@}%
476 \else \DN@{\xyFN@\tw@cell@@\empty @}%
477 \fi\fi\fi\fi\fi\fi\fi%
478 \next@ }
480 \xydef@\whichCurveObject@{%
481 \ifx\space@\next\expandafter\DN@\space{\xyFN@\whichCurveObject@}%
482 \else\ifx\next^\DN@^##1{\xy@{~^{##1}}{\uppercurveobject{##1}}\xyFN@\tw@@cell@}%
483 \else\ifx\next_\DN@_##1{\xy@{~_{##1}}{\lowercurveobject{##1}}\xyFN@\tw@@cell@}%
484 \else\addRQ@\ifx\next \addRQ@\DN@##1{%
485 \xy@{~'{##1}}{\def\twocellhead@{##1}}\xyFN@\tw@@cell@}%
486 \else\addLQ@\ifx\next \addLQ@\DN@##1{%
487 \xy@{~`{##1}}{\def\twocelltail@{##1}}\xyFN@\tw@@cell@}%
488 \else\ifx!\next \DN@!{\xyFN@\checkmodmap@}%
489 \else\ifx\next\bgroup\DN@##1{\xy@{~{##1}}{\curveobject{##1}}\xyFN@\tw@@cell@}%
490 \else\DN@##1{\xy@{~##1}{\curveobject{##1}}\xyFN@\tw@@cell@}%
491 \fi\fi\fi\fi \fi\fi\fi
492 \next@ }
494 \xydef@\checkmodmap@{%
495 \ifx\space@\next\expandafter\DN@\space{\xyFN@\checkmodmap@}%
496 \else \def\twocellmod@{\modmap@}%
497 \ifx\next!\DN@!##1{%
498  \xy@{~!!{##1}}{\def\modmapobject@{##1}}\xyFN@\tw@@cell@}%
499 \else \DN@{\xyFN@\tw@@cell@}\fi
500 \fi \next@ }

With no arrows, still allow labels: default positions are at 0, +X, −X, with X =default value. These values are altered by “nudging”.

508 \xydef@\omitarrows@{\toks5={0}\toks6={}\toks7={0}\toks8={0}}

3.4.2 Standard Options

The orientation of the central Arrow may be reversed, turned into an equality, or omitted altogether. In each case a label may still be specified, so in effect the Arrow may be replaced by anything at all.

These effects are specified by the first token in the central label, which thus has the form: {⟨tok⟩⟨label⟩} where ⟨tok⟩ may be one of …

_Arrow points clockwise
^Arrow points anti-clockwise
=  no tip, denotes equality
\omit no Arrow at all.

When none of these occurs then the default of _is assumed. If the label itself starts with one of these characters then specify _explicitly, or enclose the label within a group {...}. See Extra Options 1, for more values of ⟨tok⟩. Also note that * has a special role when used as the first character; however it is considered to be part of the ⟨label⟩, see above.

OPTIONS for the central Arrow:

c l  ignore spaces
^points anti-clockwise
_points clockwise (default)
=  no \Tip, equality
\omit no Arrow at all, just squine(s) or composed arrows
'  no Arrow, opposite squine reversed
`  no Arrow, forward squine reversed
"  no Arrow, tips on both ends
!  no Arrow, no tips on squines

the position of the Arrow is determined by “nudging” (see below) e.g. {^<num>label}, where the

actual dimen is <num>\xydashl@

[figure: A; α; B; β; C; γ; D; Ψ; E]

\xymatrixcolsep{4pc}
\xymatrixrowsep{1pc}
\diagram
A \rtwocell{_\alpha} & B \rtwocell{^\beta} &
C \rtwocell{=\gamma} & D \rtwocell{\omit\Psi} & E \\
\enddiagram

691 \xydef@\tw@@cell@@{\expandafter\xyFN@\expandafter\tw@cell@@\the\toks@ @}
693 \xydef@\tw@cell@@{\ifx \space@\next\expandafter\DN@\space{\xyFN@\tw@cell@@}%
694 \else\ifx ^\next
695 \DN@^##1@{\toks@={##1}\toks4={^}\nudgepos@50\tw@cell@@@}%
696 \else\addEQ@\ifx\next
697 \addEQ@\DN@##1@{\toks@={##1}\toks4={=}\nudgepos@50\tw@cell@@@}%
698 \else\ifx _\next
699 \DN@_##1@{\toks@={##1}\toks4={_}\nudgepos@50\tw@cell@@@}%
700 \else\addLT@\ifx \next
701  \DN@##1@{\toks@={##1}\toks4={_}\nudgepos@50\tw@cell@@@}%
702 \else\ifx\omit\next \DN@\omit##1@{\toks4={@}\toks@={##1}\tw@cell@@@}%
703 \else\addRQ@\ifx\next \addRQ@\DN@##1@{\toks4={@}\toks3={/}\toks@={##1}%
704 \nudgepos@50\tw@cell@@@}%
705 \else\addLQ@\ifx\next \addLQ@\DN@##1@{\toks4={@}\toks3={b}\toks@={##1}%
706 \nudgepos@50\tw@cell@@@}%
707 \else\ifx"\next \DN@"##1@{\toks4={@}\toks3={B}\toks@={##1}%
708 \nudgepos@50\tw@cell@@@}%
709 \else\ifx!\next \DN@!##1@{\toks4={@}\toks3={@}\toks@={##1}%
710 \nudgepos@50\tw@cell@@@}%
711 \else\ifx\next\empty\DN@##1@{\toks@={{}}\toks4={_}\tw@cell@@@}%
712 \else\DN@##1@{\toks@={##1}\toks4={_}\tw@cell@@@}%
713 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@ }

Parsing of the Arrow’s label

3.4.3 Nudging

Positions of all labels may be adjusted, as can the amount of curvature for the curved arrows. The way this is done is by specifying a “nudge” factor ⟨num⟩ at the beginning of the label. Here ⟨num⟩ is a number which specifies the actual position of the label in units of \xydashl@ (the length of a single dash, normally 5pt) except with \..compositemap, see below. Movement is constrained to the perpendicular bisector of the line \overline{cp}. When nudging the label for the central Arrow it is the whole Arrow which is moved, along with its label.

Curvature of the arrows themselves is altered by a nudge of the form \..twocell⟨num⟩.... The separation of the arrows, along the bisector, is set to be ⟨num⟩\xydashl@. When ⟨num⟩ is zero, that is \..twocell<0>..., the result is a single straight arrow, its mid-point being the origin for nudging labels. A negative value for ⟨num⟩ is also acceptable; but check the orientation on the Arrow and which of ^and _correspond to which component.

The origin for nudging labels is where the arrow crosses the bisector. Positive nudges move the label outwards while negative nudges move towards \overline{pc} and possibly beyond. The default position of a label is on the outside, with edge at the origin.

The origin for nudging the Arrow is at the midpoint of \overline{pc}. A positive nudge moves in the clockwise direction. This will be the direction of the arrowhead, unless it has been reversed using ^.

Labels on a \..compositemap are placed relative to the midpoint of the component arrows. Nudges are in units of 1pt. Movement is in the usual XY-pic above and below directions, such that a positive nudge is always outside the triangle formed by the arrows and line \overline{pc}.

The special nudge value <\omit> typesets just the Arrow, omitting the curved arrows entirely. When used with labels, the nudge value <\omit> causes the following label to be ignored.

Exercise 3.7: Give code to typeset figure 3.3. Such code is relatively straight-forward, using “nudging” and \omit to help position the arrows, curves and Arrows. It also uses an excursion, as described below in the subsection Extra Options 3.

NUDGE position of labels

825 \xywarnifdefined\whichnudge
826 \xywarnifdefined\whichinfo
827 \xywarnifdefined\afternudge
828 \xydef@\nudgepos@#1#2#3{\def\whichnudge{\toks#1}\def\whichinfo{\toks#2}%
829 \def\afternudge{#3}\expandafter\xyFN@\expandafter\nudgepos@@\the\toks@ @}

#1 which token register to store nudge amount
#2 which token register to store label
#3 what to do next, after parsing

Parsing: ⟨num⟩⟨label⟩@, ⟨num⟩ = nudge amount, as multiple of \xydashl@.

845 \xydef@\nudgepos@@{\ifx \space@\next\expandafter\DN@\space{\xyFN@\nudgepos@}%
846 \else\addLT@\ifx \next
847 \addGT@{\addLT@\DN@##1}##2@{%
848  \ifx\omit##1\relax\whichnudge={0}\whichinfo={}%
849  \else\whichnudge={##1}\whichinfo={##2}\fi\xyFN@\afternudge}%
850 \else \DN@##1@{\whichinfo={##1}\xyFN@\afternudge}%
851 \fi\fi \next@ }

3.4.4 Extra Options

The following features are useful in non-mathematical applications.

1. no Arrow

This is determined by special values for ⟨tok⟩ as the first (or only) character in the central label, as in the above description of the standard switches.

' arrowheads pointing clockwise;
` arrowheads pointing anti-clockwise;
" arrow tips on both ends;
! no tips at all.

The central Arrow is omitted, leaving symmetrically placed curved connections with arrowheads at the specified ends. A label can be placed where the Arrow would have been.

If a special arrowhead is specified using ~'{..} (see Extra Options 2, below) then this will be used instead of the standard \dir{>}.

[figure: Clouds; precipitation; evaporation; H_{2}O; Oceans]

\xymatrixcolsep{5pc}
\diagram
 \relax\txt{Clouds }\rtwocell<10>
 _{\hbox{\tiny evaporation }}
 ^{\hbox{\tiny precipitation }}
{'{\mathbf{H_2 O}}}
&\relax\txt{Oceans}\\
\enddiagram

[figure: Mathematics; theory; experiment; Physics]

\xymatrixcolsep{5pc}
\diagram
\relax\txt{\llap{Math}ematics }\rtwocell
_{\hbox{\tiny experiment }}
^{\hbox{\tiny theory }}{"}
& \relax\txt{Physics} \\
\enddiagram

2. Changing Tips and Module Maps

The following commands are provided for specifying the ⟨object⟩ to be used when typesetting various parts of the twocells.

command  default

 \modmapobject{⟨object⟩}       \dir{|}
 \twocellhead{⟨object⟩}        \dir{>}
 \twocelltail{⟨object⟩}        \dir{}
 \arrowobject{⟨object⟩}       \dir{=>}

 \curveobject{⟨object⟩}

 \uppercurveobject{⟨object⟩}     {}
 \lowercurveobject{⟨object⟩}     {}

These commands set the object to be used for all subsequent 2-cells at the same level of TEX grouping. \curveobject specifies both of the upper- and lower-curve objects. For some of these there is also a way to change the object for the current 2-cell only. This requires a ~-⟨switch⟩ which is described below, except for the \..curveobject types, which are discussed in Extra Options 4.

These effects are specified by placing switches after the \..twocell control sequence, e.g. \rtwocell switches labels. … Each switch is either a single token ⟨tok⟩, or a ~⟨tok⟩ with a single argument: ~⟨tok⟩{arg}. Possibilities are listed in the following table, in which {..} denotes the need for an argument.

\omit no arrows, Arrow and label only;
!  place module-map indicator;
~'{..} change arrow-head to {..};
~`{..} place/change tail on arrow(s);
~{..} change object used to set curves;
~^{..} use object {..} to set upper curve;
~_{..} use object {..} to set lower curve;

Here we discuss the use of !, ~', ~` and \omit. The description of ~^, ~_and ~{..} is given in Extra Options 4.

The default module map indicator places a single dash crossing the arrow at right-angles, located roughly midway along the actual printed portion of the arrow, whether curved or straight. This takes into account the sizes of the objects being connected, thereby giving an aesthetic result when these sizes differ markedly. This also works with \..compositemap where an indicator is placed on each arrow. The actual object can be changed using \modmapobject.

Any of the standard XY-pic tips may be used for arrow-heads. This is done using ~'{..}, for example ~'{\dir{>>}} gives double-headed arrows. Similarly ~`{..} can be used to place an arrowtail. Normally the arrow-tail is , so is not placed; but if a non-empty tail has been specified then it will be placed, using \drop. No guarantee is offered for the desired result being obtained when an arrow-tail is mixed with the features of Extra Options 1.

[figure: P; ⊗; M; ⊗; M′; f; S]

\modmapobject{\objectbox{\otimes}}
\xymatrixcolsep{5pc}
\diagram
P\rtwocell~!~'{\dir{>>}}~`{\dir{|}}
 ^{<1.5>M}_{<1.5>M'}{=f} & S \\
\enddiagram

switch for module maps... ...places decoration called \modmapobject half way along arrows

1010 \xydef@\modmap@{%
1011 \expandafter\ifx\the\toks4@\toks4={!}%
1012 \else\expandafter\ifx\the\toks4=\toks4={H}%
1013 \else\expandafter\ifx\the\toks4^\toks4={A}%
1014 \else\expandafter\ifx\the\toks4_\toks4={V}\fi\fi\fi\fi
1015 \expandafter\DN@\expandafter{\the\toks6}%
1016 \ifx\next@\empty\relax\else\expandafter\moddefs@\fi}

also adjust curvature and label positions

1022 \xydef@\moddefs@{%
1023 \expandafter\dimen@\the\toks6\p@
1024 \ifdim\dimen@=\z@\relax
1025 \expandafter\dimen@\the\toks7\p@
1026 \ifdim\dimen@<\z@\advance\dimen@.5\p@\else\advance\dimen@-.5\p@\fi
1027 \edef\tmp@{\noexpand\toks7={\expandafter\removePT@\the\dimen@}}\tmp@
1028 \expandafter\dimen@\the\toks8\p@
1029 \ifdim\dimen@<\z@\advance\dimen@-.5\p@\else\advance\dimen@.5\p@\fi
1030 \expandafter\ifx\the\toks3t\advance\dimen@-1\p@\fi
1031 \edef\tmp@{\noexpand\toks8={\expandafter\removePT@\the\dimen@}}\tmp@
1032 \else
1033 \ifdim\dimen@<\z@\advance\dimen@-.5\p@\else\advance\dimen@.5\p@\fi
1034 \edef\tmp@{\noexpand\toks6={\expandafter\removePT@\the\dimen@}}\tmp@
1035 %  \expandafter\dimen@\the\toks5\p@
1036 %   \ifdim\dimen@<\z@\advance\dimen@-.5\p@\else\advance\dimen@.5\p@\fi
1037 %   \edef\tmp@{\noexpand\toks5={\expandafter\removePT@\the\dimen@}}\tmp@
1038 \expandafter\dimen@\the\toks7\p@
1039 \ifdim\dimen@<\z@\advance\dimen@-.5\p@\else\advance\dimen@.5\p@\fi
1040 \expandafter\ifx\the\toks3t\advance\dimen@-2\p@\fi
1041 \edef\tmp@{\noexpand\toks7={\expandafter\removePT@\the\dimen@}}\tmp@
1042 \expandafter\dimen@\the\toks8\p@
1043 \ifdim\dimen@<\z@\advance\dimen@-.5\p@\else\advance\dimen@.5\p@\fi
1044 \expandafter\ifx\the\toks3t\advance\dimen@-2\p@\fi
1045 \edef\tmp@{\noexpand\toks8={\expandafter\removePT@\the\dimen@}}\tmp@
1046 \fi }%
1048 %\def\moddefs@{}

default object is \stop, user can change this with \modmapobject#1

1054 \xydef@\modmapobject#1{\def\modmapobject@{#1}}
1055 \xydef@\modmapobject@{\dir{|}}
1056 \xydef@\@modmapobject@{{\if\@mod@\relax\expandafter\empty
1057 \else\expandafter\modmapobject@\fi}}

3. Excursions

Syntax for \xcompositemap and \x..twocell types is a little different to what might be expected from that for \xto, \xline, etc. For example,

                            \xtwocell[⟨hop⟩]{⟨displace⟩}...

connects to the ⟨pos⟩ displaced by ⟨displace⟩ from the relative cell location specified by ⟨hop⟩. The displacement can be any string of valid XY-pic commands, but they must be enclosed within a group {...}. When the cell location is the target, a null grouping {} must be given.

When used with the <\omit> nudge, such excursions allow a labelled Arrow to be placed anywhere within an XY-pic diagram; furthermore the Arrow can be oriented to point in any direction.

1087 \xydef@\curveobject#1{\def\ucurveObject@{~*#1}\def\dcurveObject@{~*#1}}
1088 \xydef@\uppercurveobject#1{\def\ucurveObject@{~*#1}}
1089 \xydef@\lowercurveobject#1{\def\dcurveObject@{~*#1}}
1090 \xydef@\ucurveObject@{}
1091 \xydef@\dcurveObject@{}

The empty object gives the default of closely spaced tiny dots, resulting in a “smooth” curve. The following macro is used in conjunction with compiling diagrams, to include the global param-

eters in the compiled file.

1103 \xydef@\savetwocellobjects{%
1104 \xy@{twocell objects}{%
1105 \expandafter\uppercurveobject\expandafter{\ucurveObject@}%
1106 \expandafter\lowercurveobject\expandafter{\dcurveObject@}%
1107 \expandafter\modmapobject\expandafter{\modmapobject@}%
1108 \expandafter\twocellhead\expandafter{\twocellhead@}%
1109 \expandafter\twocelltail\expandafter{\twocelltail@}%
1110 \expandafter\arrowobject\expandafter{Arrowobject@}%

1111 }}

4. Fancy curves

By specifying \curveobject an arbitrary object may be used to construct the curved arrows. Indeed with a \..twocell different objects can be used with the upper and lower curves by specifying

\uppercurveobject and \lowercurveobject.

These specifications apply to all 2-cells subsequently constructed at the same level of TEX grouping. Alternatively using a ~-switch, as in Extra Options 2, allows such a specification for a single 2-cell or curved part.

Objects used to construct curves can be of two types. Either a single ⟨object⟩ is set once, with copies placed along the curve. Alternatively a directional object can be aligned with the tangent along the curve. In this case use a specification takes the form:

   \curveobject{⟨spacer⟩~**⟨object⟩}.

Here ⟨spacer⟩ may be any ⟨object⟩ of non-zero size. Typically it is empty space, e.g. +⟨dimen⟩{}.

Exercise 3.8: Give code to typeset the following diagrams.

FUn^{?????????????}_{∘∘∘∘∘∘∘∘∘∘∘∘∘}_{&}  gaMES

[figure: Ground State; continuous power; pulsed emission; Ni Cd; Excited State]

3.4.5 After Parsing...

Values for \twocellPATH, depends on the mode of picture/diagram as to whether the @c and @p are known yet, or still have to be read.

1193 \xydef@\twocell@path.[#1].{%
1194 \expandafter\ifx\csname Q@@c\endcsname\relax
1195 \DN@{\enter@{\cfromthec@ \pfromthep@ \basefromthebase@}%
1196 \xy@{}{\expandafter\edef\csname Q@@\endcsname{\cfromthec@}}%
1197 \afterPOS{\xy@{}%
1198  {\expandafter\edef\csname Q@@c\endcsname{\cfromthec@}}%
1199 \xy@{}%
1200 {\cfromid@{@}\expandafter\edef\csname Q@@p\endcsname{\cfromthec@}}%
1201 \xy@{twocell #1}{#1}\leave@\aftertwoCELL};p,}%
1202 \else
1203 \DN@{\enter@{\cfromthec@ \pfromthep@ \basefromthebase@}%
1204 \xy@{twocell #1}{#1}\leave@\aftertwoCELL}%
1205 \fi \next@ }
1207 \xydef@\twocellpath.[#1].{%
1208 \expandafter\edef\csname Q@@p\endcsname{\cfromthec@}%
1209 \xy@{}{\enter@{\pfromthep@}}%
1210 \xy@{}{\enter@{\cfromthec@ \pfromthep@ \basefromthebase@}%
1211  \enter@{\pfromthec@}}%
1212 \afterPOS{\xy@{}{\leave@\setupDirection@}#1\restore\restore
1213 \xy@{end of 2-cell}\xysaveMinMax@ }}%
1215 \xydef@\xysaveMinMax@{\edef\tmp@{\endgroup
1216 \noexpand\ifdim\X@max<\the\X@max \X@max=\the\X@max\noexpand\fi
1217 \noexpand\ifdim\X@min>\the\X@min \X@min=\the\X@min\noexpand\fi
1218 \noexpand\ifdim\Y@max<\the\Y@max \Y@max=\the\Y@max\noexpand\fi
1219 \noexpand\ifdim\Y@min>\the\Y@min \Y@min=\the\Y@min\noexpand\fi
1220 }\tmp@ }
1224 \xylet@\twocellPATH=\twocellpath

1225 \xydef@\aftertwo@CELL{\let\twocellPATH=\twocellpath \def\aftertwoCELL{}}
1226 \xydef@\aftertwoCELL{}

It remains to collect everything together and place it on the queue.

1232 \xydef@\twocell@@@@#1!!!{\xy@{twocell #1}{\twocell@@#1!!!}}

3.4.6 2-cells in general XY-pictures

Two-cells can also be set directly within any XY-picture, without the matrix feature, using either \drop

or \connect.

1245 \let\xystatus=\xystatus@
1246 \xydef@\twocell{\hbox\bgroup\@twocell}
1247 \xydef@\uppertwocell{\hbox\bgroup\@uppertwocell}
1248 \xydef@\lowertwocell{\hbox\bgroup\@lowertwocell}
1249 \xydef@\compositemap{\hbox\bgroup\@compositemap}
1251 \xydef@\twocelll#1#{\hbox\bgroup\xy@\save\save@\@twocelll{#1}}
1252 \xydef@\@twocelll#1#2{%
1253 \afterPOS{\@twocelll@\xyFN@\twocell@#1{#2}}}
1255 \xydef@\uppertwocelll#1#{\hbox\bgroup\xy@\save\save@\@uppertwocelll{#1}}
1256 \xydef@\@uppertwocelll#1#2{%
1257 \afterPOS{\@twocelll@\xyFN@\uppertwocell@#1{#2}}}
1259 \xydef@\lowertwocelll#1#{\hbox\bgroup\xy@\save\save@\@lowertwocelll{#1}}
1260 \xydef@\@lowertwocelll#1#2{%
1261 \afterPOS{\@twocelll@\xyFN@\lowertwocell@#1{#2}}}
1263 \xydef@\compositemapp#1#{\hbox\bgroup\xy@\save\save@\@compositemapp{#1}}
1264 \xydef@\@compositemapp#1#2{%
1265 \afterPOS{\@twocelll@\xyFN@\compositemap@#1{#2}}}

1266 %

1267 \xydef@\@twocelll@{%
1268 % \idfromc@{@c}\swap@\idfromc@{@p}\swap@
1269 \expandafter\edef\csname Q@@c\endcsname{\cfromthec@}\swap@
1270 \expandafter\edef\csname Q@@p\endcsname{\cfromthec@}\swap@
1271 \let\twocellPATH=\twocell@path
1272 % \def\aftertwoCELL{\twocell@DONE}}
1273 \def\aftertwoCELL{\twocell@DONE \xy@\restore \leave@
1274 % \cfromid@{@c}\no@@ \xystatus@{end: }

1275 }}

1277 \xydef@\@twocell#1{\DN@{\@twocell@\twocell@}\xyFN@\next@[#1]}
1278 \xydef@\@uppertwocell#1{\DN@{\@twocell@\uppertwocell@}\xyFN@\next@[#1]}
1279 \xydef@\@lowertwocell#1{\DN@{\@twocell@\lowertwocell@}\xyFN@\next@[#1]}
1280 \xydef@\@compositemap#1{\DN@{\@twocell@\compositemap@}\xyFN@\next@[#1]}

\def\myPOS#1{\POS}\def\goVia#1{%
  \afterPOS{\connect#1\myPOS}}
\xy
 *+{A}="A",+<1cm,1.5cm>*+{B}="B",
 +<2.0cm,0pt>*+{C}="C",
 +<1cm,-1.5cm>*+{D}="D",

"A";\goVia{\uppertwocell^\alpha{}}"B"{}
;\goVia{\twocell^\zeta_\xi{\gamma}}"C"{}
;\goVia{\compositemap{}}"D"{},
"A";\goVia{\lowertwocell{}}"D"{}
\endxy

[figure: A; B; C; D; α; ζ; ξ; γ]

The code shown is a compact way to place a chain of 2-cells within a picture. It illustrates a standard technique for using \afterPOS to find a ⟨pos⟩ to be used for part of a picture, then subsequently reuse it. Also it is possible to use \drop or ⟨decor⟩s to specify the 2-cells, giving the same picture.

\xy *+{A}="A",+<1cm,1.5cm>*+{B}="B",
 +<2cm,0pt>*+{C}="C",
 +<1cm,-1.5cm>*+{D}="D",
"A";"B",{\uppertwocell^\alpha{}},
"B";"C",{\twocell^\zeta_\xi{\gamma}},
"C"; \afterPOS{\drop\compositemap{}}"D"
\POS "A";
 \afterPOS{\drop\lowertwocell{}}"D"
\endxy

The \connect variant is usually preferable as this maintains the size of the object at c, while the \drop variant leaves a rectangular object having p and c on opposite sides.

This is used outside of diagrams.

1338 \xydef@\@twocell@#1{\ifx\next[\DN@[{\toks@={#1}\xyFN@\@@twocell@}%
1339 \else\DN@{#1{}}\fi

1340 %%

1341 % \idfromc@{@c}\swap@\idfromc@{@p}\swap@
1342 \expandafter\edef\csname Q@@c\endcsname{\cfromthec@}\swap@
1343 \expandafter\edef\csname Q@@p\endcsname{\cfromthec@}\swap@
1344 \let\twocellPATH=\twocell@path
1345 \def\aftertwoCELL{\twocell@DONE}\next@}

This hack is necessary, since \DN@[##1]{#1##1} will strip braces.

1351 \xydef@\@@twocell@{\ifx\next\bgroup\DN@##1]{\the\toks@{##1}}%
1352 \else\DN@##1]{\the\toks@##1}\fi\next@}

To Do: These are supposed to allow \dir\...twocell{...} to work. At present it seems to be impossible to do this.

1362 % \expandafter\xydefcsname@\expandafter{\codeof\twocell}{\@twocell}
1363 % \expandafter\xydefcsname@\expandafter{\codeof\uppertwocell}{\@uppertwocell}
1364 % \expandafter\xydefcsname@\expandafter{\codeof\lowertwocell}{\@lowertwocell}
1365 % \expandafter\xydefcsname@\expandafter{\codeof\compositemap}{\@compositemap}

1366 %% \DN@{\twocell}%
1367 %% \expandafter\def\csname*dir@@\codeof\next@ @\endcsname{\@twocell}
1368 %% \DN@{\uppertwocell}%
1369 %% \expandafter\def\csname*dir@@\codeof\next@ @\endcsname{\@uppertwocell}
1370 %% \DN@{\lowertwocell}%
1371 %% \expandafter\def\csname*dir@@\codeof\next@ @\endcsname{\@lowertwocell}
1372 %% \DN@{\compositemap}%
1373 %% \expandafter\def\csname*dir@@\codeof\next@ @\endcsname{\@compositemap}

...since the contents of {..} is variable.

Finish off the box, set up the object size, establish the \Drop@@ and \Connect@@ methods.

1384 \xydef@\twocell@DONE{%
1385 \edef\tmp@{\egroup \X@min=\the\X@min \X@max=\the\X@max
1386 \Y@min=\the\Y@min \Y@max=\the\Y@max}\tmp@
1387 \L@c=\X@c \advance\L@c-\X@min \R@c=\X@max \advance\R@c-\X@c
1388 \D@c=\Y@c \advance\D@c-\Y@min \U@c=\Y@max \advance\U@c-\Y@c
1389 \ht\z@=\U@c \dp\z@=\D@c \dimen@=\L@c \advance\dimen@\R@c \wdz@=\dimen@
1390 \computeLeftUpness@

1391 %

1392 \setboxz@h{\kern-\X@p \raise-\Y@c\boxz@ }%
1393 \dimen@=\L@c \advance\dimen@\R@c \wdz@=\dimen@ \ht\z@=\U@c \dp\z@=\D@c

1394 %

1395 \Edge@c={\rectangleEdge}\Invisible@false \Hidden@false
1396 \edef\Drop@@{\noexpand\drop@Twocell
1397 \noexpand\def\noexpand\Leftness@{\Leftness@}%
1398 \noexpand\def\noexpand\Upness@{\Upness@}}%
1399 \edef\Connect@@{\noexpand\connect@Twocell
1400 \noexpand\ifdim\X@max<\the\X@max \X@max=\the\X@max\noexpand\fi
1401 \noexpand\ifdim\X@min>\the\X@min \X@min=\the\X@min\noexpand\fi
1402 \noexpand\ifdim\Y@max<\the\Y@max \Y@max=\the\Y@max\noexpand\fi
1403 \noexpand\ifdim\Y@min>\the\Y@min \Y@min=\the\Y@min\noexpand\fi }}%

   modified \Drop@@ and \Connect@@

1409 \xydef@\drop@Twocell{\boxz@ }
1411 \xydef@\connect@Twocell{%
1412 \setboxz@h{\kern\X@p \raise\Y@c\box\lastobjectbox@ }%
1413 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \Drop@@ }

\twocell@@ is the main switching engine, taking 9 parameters determining which pieces to set and where to position them. This includes curvature of the squines, whether to draw two squines or only one, or to use straight lines, whether to have a central Arrow and its orientation, contants of labels and their positions.

The current p and c are the extents of the connection these are stored as "@p" and "@c" for repeated use;

#1 determines location of control point "@m"
#2 location of =>, as multiple of \xydashl@ from "@m"
#3 location of _label (source arrow)
#4 location of ^label (target arrow)
#5 flag for how many squines to draw & which tips
#6 label for source arrow
#7 label for target arrow
#8 label for => (2-cell morphism)
#9 determines orientation of 2-cell

The following tokens may appear as parameters in #9: !, ^, _, =, A, V, H

1446 \xywarnifdefined\@mod@
1447 \xywarnifdefined\Arrowtok@
1449 \xydef@\twocell@@#1#2#3#4#5#6#7#8#9!!!{%
1450 \def\@mod@{@}\DN@{#9}%
1451 \ifx #9!\def\Arrowtok@{@}\else\ifx #9A\def\Arrowtok@{^}%
1452 \else\ifx #9V\def\Arrowtok@{_}\else\ifx #9H\def\Arrowtok@{=}%
1453 \else\def\@mod@{\relax}%
1454 \ifx #5/\def\Arrowtok@{@}\else\ifx #5b\def\Arrowtok@{@}%
1455 \else\ifx #5B\def\Arrowtok@{@}\else\ifx #5@\def\Arrowtok@{@}%
1456 \else\def\Arrowtok@{#9}%
1457 \fi\fi\fi\fi\fi\fi\fi\fi
1458 \addEQ@\ifx #9\def\Arrowtok@{=}\fi
1459 \DN@{\omit}\ifx\next@\Arrowtok@\def\Arrowtok@{}\else
1460 \edef\Arrowtok@{\codeof\Arrowtok@}\fi
1461 \save@ \idfromc@{@c}\swap@\idfromc@{@p}\swap@
1462 \cfromid@{@c}\no@@

1463 %

1464 \ifdim \X@c<\X@p \X@min=\X@c \X@max=\X@p \else \X@min=\X@p \X@max=\X@c \fi
1465 \ifdim \Y@c<\Y@p \Y@min=\Y@c \Y@max=\Y@p \else \Y@min=\Y@p \Y@max=\Y@c \fi

1466 %

1467 \Calong@@{.5}\idfromc@{@m}\idfromc@{@m1}\idfromc@{@m2}%

1468 %

1469 \ifx #5t\relax
1470 \enter@{\cplusthec@\pfromthep@}%
1471 \enter@\DirectionfromtheDirection@ \begingroup\aboveDirection@ \xydashl@
1472 \DN@{#1}\ifx\next@\empty\dimen@=\z@\else\dimen@=#1\p@\fi
1473 \ifdim\dimen@=\z@ \DN@{\vfromslide@i{\xydashl@}@}\relax
1474 \else\DN@{\vfromslide@i{#1\xydashl@}@}\fi \next@
1475 \czeroEdge@ \leave@ \no@@ \drop@{+}{}\idfromc@{@m1}%
1476 \DN@{#1}\ifx\next@\empty\DN@{\no@@}\else\DN@{\connect@{\dir}{-}}\fi
1477 \else
1478 \DN@{#1}\ifx\next@\empty\dimen@=\z@\else\dimen@=#1\p@\fi
1479 \ifdim\dimen@=\z@ \enter@{\cplusthec@\pfromthep@}%
1480 \enter@\DirectionfromtheDirection@ \begingroup\aboveDirection@\xydashl@
1481  \vfromslide@i{\xydashl@}@\czeroEdge@ \leave@ \idfromc@{@m1}%
1482  \cfromid@{@p}\swap@\cfromid@{@c}%

1483 \DN@{#1}\ifx\next@\empty\DN@{\no@@}\else\DN@{\connect@{\dir}{-}}\fi
1484 \else \DN@{\enter@\cplusthec@
1485 \enter@\DirectionfromtheDirection@ \begingroup\aboveDirection@ \xydashl@
1486  \vfromslide@i{#1\xydashl@}@\czeroEdge@ \leave@
1487 \idfromc@{@m1}\cfromid@{@p}\swap@\cfromid@{@c}%
1488 \edef\next@{\codeof\ucurveObject@}%
1489 \ifx\next@\empty\DN@{\connect@\crv{"@m1"}}%
1490 \else
1491  \DNii@####1{\connect@\crv{####1}}\expandafter\DN@\expandafter{%
1492  \expandafter\nextii@\expandafter{\ucurveObject@"@m1"}}%
1493 \fi \next@ }%
1494 %%   \ifx\next@\empty\def\ucurveObject@{.}\fi
1495 %%   \enter@\cfromthec@\sinit@\cfromid@{@m1}\senter@\leave@
1496 %%   \expandafter\connect@\expandafter\crvs\expandafter{\ucurveObject@}%
1497 %%   \sinit@\sleave@ }%

1498 \fi

1499 \fi \next@

1500 %

1501 \DN@{#1}\ifx\next@\empty\relax\else
1502 \if\@mod@ @\relax
1503 \enter@\pfromthep@ \Creset@@
1504 \ifx #5t\relax
1505 \PLACEedgec@ \PLACEedgep@ \def\PLACEf@{{.5}}%
1506 \else \def\next@{\crvreset@}%
1507 \ifx\next@\Creset@@
1508  \gettwocelledges@ \edef\PLACEf@{{\expandafter\removePT@\the\dimen@}}%
1509 \else \PLACEedgec@ \PLACEedgep@ \def\PLACEf@{{.5}}\fi

1510 \fi

1511 \expandafter\Calong@@\PLACEf@ \czeroEdge@ \leave@
1512 \edef\tmp@{\codeof\modmapobject@}%
1513 \ifx\tmp@\empty \DN@{\drop@{\dir}{|}}%
1514 \else \DNii@##1##{\drop@{##1}}%
1515 \DN@{\expandafter\nextii@\modmapobject@{}}%
1516 \fi \next@
1517 \fi\fi

1518 %

1519 \DN@{#6}\ifx\next@\empty\DN@{\relax}\else
1520 \DNii@{{}}\ifx\next@\nextii@\DN@{\relax}\else
1521 \ifx @#3\relax\DN@{\relax}\else
1522 \DN@{\enter@\pfromthep@ \Creset@@
1523 \Calong@@{.5}\czeroEdge@ \leave@
1524 \enter@\cplusthec@
1525 \enter@\DirectionfromtheDirection@\begingroup
1526  \DN@{#1}\ifx\next@\empty\dimen@\z@\else\dimen@=#1\p@\fi
1527  \ifdim\dimen@<\z@ \belowDirection@ \xydashl@
1528  \else \aboveDirection@ \xydashl@ \fi
1529 %     \vfromslide@i{#3\xydashl@}@\czeroEdge@ \leave@
1530 %  \droptwocelllabel@{#6}}%
1531  \dimen@=#3\p@ \if\@mod@ @\relax

1532  \advance\dimen@\ifdim\dimen@<\z@-\fi.5\p@\fi
1533  \edef\next@{\expandafter\removePT@\the\dimen@}%
1534  \expandafter\vfromslide@i\expandafter{\next@\xydashl@}@\leave@
1535  \droptwocelllabel@{#6}}%
1536 \fi\fi\fi \next@

1537 %
1538 %

1539 \DN@{#1}\ifx\next@\empty\relax\else
1540 \ifx #5b\relax         % tip at start only
1541 \enter@ {\pfromthep@ }\Creset@@ \PLACEedgep@
1542 \Calong@@{0}\czeroEdge@ \leave@
1543 \edef\next@{\codeof\twocelltail@}%
1544 \ifx\next@\empty \DN@{\dir{>}}%
1545  \ifx\next@\twocellhead@\drop@{\dir}{<}%
1546  \else
1547  \reverseDirection@ \DNii@##1##{\drop@{##1}}%
1548  \expandafter\nextii@\twocellhead@{}\reverseDirection@

1549  \fi

1550 \else
1551  \DNii@##1##{\drop@{##1}}\expandafter\nextii@\twocelltail@{}%

1552 \fi

1553 \else\ifx #5@\relax   % no tips at all
1554 \else                 % tip at end...
1555 \enter@\pfromthep@ \Creset@@ \PLACEedgec@
1556 \Calong@@{1}\czeroEdge@ \leave@
1557 \edef\next@{\codeof\twocellhead@}%
1558 \ifx\next@\empty\drop@{\dir}{>}%
1559 \else
1560  \DNii@##1##{\drop@{##1}}\expandafter\nextii@\twocellhead@{}%

1561 \fi

1562 \ifx #5B\relax        % ... and also at start.
1563 \enter@ {\pfromthep@ }\Creset@@ \PLACEedgep@
1564  \Calong@@{0}\czeroEdge@ \leave@
1565 \edef\next@{\codeof\twocelltail@}%
1566 \ifx\next@\empty \DN@{\dir{>}}%
1567  \ifx\next@\twocellhead@\drop@{\dir}{<}%
1568  \else
1569  \reverseDirection@\DNii@##1##{\drop@{##1}}%
1570  \expandafter\nextii@\twocellhead@{}\reverseDirection@

1571  \fi

1572 \else
1573  \DNii@##1##{\drop@{##1}}\expandafter\drop\twocelltail@{}%

1574 \fi

1575 \else\ifx #5/\relax
1576 \else \edef\next@{\codeof\twocelltail@}%
1577 \ifx\next@\empty\relax\else
1578  \enter@\pfromthep@ \Creset@@ \PLACEedgep@
1579  \Calong@@{0}\czeroEdge@ \leave@
1580  \DNii@##1##{\drop@{##1}}\expandafter\nextii@\twocelltail@{}%

1581 \fi\fi\fi
1582 \fi\fi\fi

1583 %

1584 \cfromid@{@p}\swap@\cfromid@{@c}\no@@ \cfromid@{@m}%
1585 \ifx #5t\relax
1586 \idfromc@{@m2}\cfromid@{@m1}\swap@ \cfromid@{@c}\no@@
1587 \DN@{#1}\ifx\next@\empty\DN@{\no@@}\else\DN@{\connect@{\dir}{-}}\fi
1588 \else\ifx #5o\relax
1589 \idfromc@{@m2}\DN@{}%
1590 \else     %  second curved arrow
1591 \DN@{#1}\ifx\next@\empty\dimen@=\z@\else\dimen@=#1\p@\fi
1592 \ifdim\dimen@=\z@
1593 \enter@{\cplusthec@\pfromthep@}%
1594 \enter@\DirectionfromtheDirection@ \begingroup \belowDirection@\xydashl@
1595  \vfromslide@i{\xydashl@}@\czeroEdge@ \leave@ \idfromc@{@m2}%
1596 \DN@{\cfromid@{@p}\swap@\cfromid@{@c}\no@@}%
1597 \else \DN@{\enter@\cplusthec@
1598 \enter@\DirectionfromtheDirection@ \begingroup \belowDirection@ \xydashl@
1599  \vfromslide@i{#1\xydashl@}@\czeroEdge@ \leave@
1600 \idfromc@{@m2}\cfromid@{@p}\swap@\cfromid@{@c}%
1601 \edef\next@{\codeof\dcurveObject@}%
1602 \ifx\next@\empty\DN@{\connect@\crv{"@m2"}}%
1603 \else
1604  \DNii@####1{\connect@\crv{####1}}\expandafter\DN@\expandafter{%
1605  \expandafter\nextii@\expandafter{\dcurveObject@"@m2"}}%
1606 \fi \next@ }\fi
1607 %%   \enter@\cfromthec@\sinit@\cfromid@{@m2}\senter@\leave@
1608 %%   \expandafter\connect@\expandafter\crvs\expandafter{\dcurveObject@}%
1609 %%   \sinit@\sleave@
1610 %%  }\fi
1611 \fi\fi \next@

1612 %

1613 \DN@{#1}\ifx\next@\empty\relax\else \ifx #5o\relax\else
1614 \if\@mod@ @\DN@{\enter@\pfromthep@ \Creset@@
1615 \ifx #5t\relax
1616 \PLACEedgec@ \PLACEedgep@ \def\PLACEf@{{.5}}%
1617 \else \def\next@{\crvreset@}%
1618 \ifx\next@\Creset@@
1619  \gettwocelledges@ \edef\PLACEf@{{\expandafter\removePT@\the\dimen@}}%
1620 \else \PLACEedgec@ \PLACEedgep@ \def\PLACEf@{{.5}}\fi

1621 \fi

1622 \expandafter\Calong@@\PLACEf@ \czeroEdge@ \leave@
1623 \edef\tmp@{\codeof\modmapobject@}\ifx\tmp@\empty\DN@{\drop@{\dir}{|}}%
1624 \else \DNii@####1####{\drop@{####1}}%
1625 \DN@{\expandafter\nextii@\modmapobject@{}}\fi
1626 \next@ }\else\DN@{\relax}\fi
1627 \next@ \fi\fi

1628 %

1629 \DN@{#7}\ifx\next@\empty\DN@{\relax}\else

1630 \DNii@{{}}\ifx\next@\nextii@\DN@{\relax}\else
1631 \ifx @#4\relax\DN@{\relax}\else
1632 \DN@{\enter@\pfromthep@ \Creset@@
1633 \Calong@@{.5}\czeroEdge@ \leave@
1634 \enter@\cplusthec@
1635 \enter@\DirectionfromtheDirection@ \begingroup
1636 \DN@{#1}\ifx\next@\empty\dimen@\z@ \else\dimen@=#1\p@\fi
1637 \ifx #5t\relax \ifdim\dimen@<\z@ \belowDirection@ \xydashl@
1638  \else \aboveDirection@ \xydashl@ \fi
1639 \else \ifdim\dimen@<\z@ \aboveDirection@ \xydashl@
1640  \else \belowDirection@ \xydashl@ \fi
1641 \fi \dimen@=#4\p@ \if\@mod@ @\relax
1642  \advance\dimen@\ifdim\dimen@<\z@-\fi.5\p@\fi
1643  \edef\next@{\expandafter\removePT@\the\dimen@}%
1644  \expandafter\vfromslide@i\expandafter{\next@\xydashl@}@\leave@
1645 \droptwocelllabel@{#7}}%
1646 \fi\fi\fi \next@

1647 %

1648 \DN@{#1}\ifx\next@\empty\relax\else
1649 \ifx #5o\relax
1650 \else\ifx #5b\relax  % tip at start only
1651 \enter@ {\pfromthep@ }\Creset@@ \PLACEedgec@
1652 \Calong@@{1}\czeroEdge@ \leave@
1653 \edef\next@{\codeof\twocelltail@}%
1654 \ifx\next@\empty \DN@{\dir{>}}%
1655 \ifx\next@\twocellhead@\drop@{\dir}{>}%
1656 \else
1657  \DNii@##1##{\drop@{##1}}\expandafter\nextii@\twocellhead@{}%

1658 \fi

1659 \else
1660 \DNii@##1##{\drop@{##1}}\expandafter\drop\twocelltail@{}%

1661 \fi

1662 \else\ifx #5/\relax
1663 \enter@{\pfromthep@}\Creset@@ \PLACEedgep@
1664 \Calong@@{0}\czeroEdge@ \leave@
1665 \edef\next@{\codeof\twocelltail@}%
1666 \ifx\next@\empty \DN@{\dir{>}}%
1667  \ifx\next@\twocellhead@\drop@{\dir}{<}%
1668  \else
1669  \reverseDirection@\DNii@##1##{\drop@{##1}}%
1670  \expandafter\nextii@\twocellhead@{}\reverseDirection@

1671  \fi

1672 \else
1673  \DNii@##1##{\drop@{##1}}\expandafter\nextii@\twocelltail@{}%

1674 \fi

1675 \else\ifx #5@\relax    % no tips at all
1676 \else                 % tip at end...
1677 \enter@\pfromthep@ \Creset@@ \PLACEedgec@
1678 \Calong@@{1}\czeroEdge@ \leave@

1679 \edef\next@{\codeof\twocellhead@}%
1680 \ifx\next@\empty\drop@{\dir}{>}%
1681 \else
1682  \DNii@##1##{\drop@{##1}}\expandafter\nextii@\twocellhead@{}%

1683 \fi

1684 \ifx #5B\relax        % ... and also at start.
1685 \enter@ {\pfromthep@ }\Creset@@ \PLACEedgep@
1686  \Calong@@{0}\czeroEdge@ \leave@
1687 \edef\next@{\codeof\twocelltail@}%
1688 \ifx\next@\empty\DN@{\dir{>}}%
1689  \ifx\next@\twocellhead@\drop@{\dir}{<}%
1690  \else
1691  \reverseDirection@\DNii@##1##{\drop@{##1}}%
1692  \expandafter\nextii@\twocellhead@{}\reverseDirection@

1693  \fi

1694 \else
1695  \DNii@##1##{\drop@{##1}}\expandafter\nextii@\twocelltail@{}%

1696 \fi

1697 \else
1698 \edef\next@{\codeof\twocelltail@}%
1699 \ifx\next@\empty\relax\else
1700  \enter@ {\pfromthep@ }\Creset@@ \PLACEedgep@
1701  \Calong@@{0}\czeroEdge@ \leave@
1702  \DNii@##1##{\drop@{##1}}\expandafter\nextii@\twocelltail@{}%
1703 \fi\fi
1704 \fi\fi\fi
1705 \fi\fi

1706 %

1707 %   the Arrow

1708 %

1709 \DN@{#1}\ifx\next@\empty\dimen@=\z@\else\dimen@=#1\p@\fi
1710 \ifdim\dimen@<\z@ \cfromid@{@m2}\swap@\cfromid@{@m1}%
1711 \else \cfromid@{@m1}\swap@\cfromid@{@m2}%
1712 \fi \no@@ \cfromid@{@m}%

1713 %

1714 \ifx\Arrowtok@\empty

1715 %

1716 \else\DN@{_}\edef\next@{\codeof\next@}\ifx\next@\Arrowtok@
1717 \enter@{\pfromthep@ \cplusthec@}\dimen@=#2\xydashl@
1718 \enter@\DirectionfromtheDirection@ \begingroup
1719  \expandafter\vfromslide@i\expandafter{\the\dimen@}@\czeroEdge@
1720 \leave@ \idfromc@{@m}%
1721 \DNii@##1##{\drop@{##1}}\expandafter\nextii@\Arrowobject@{}%
1722 % \drop@{\dir}{=>}%

1723 %

1724 \else\DN@{^}\edef\next@{\codeof\next@}\ifx\next@\Arrowtok@
1725 \DN@{_}\edef\Arrowtok@{\codeof\next@}%
1726 \enter@{\pfromthep@ \cplusthec@}\dimen@=#2\xydashl@
1727 \enter@\DirectionfromtheDirection@ \begingroup

1728  \expandafter\vfromslide@i\expandafter{\the\dimen@}@\czeroEdge@
1729 \leave@ \idfromc@{@m}\reverseDirection@
1730 \DNii@##1##{\drop@{##1}}\expandafter\nextii@\Arrowobject@{}%
1731 %  \drop@{\dir}{=>}%

1732 %

1733 \else \DN@{=}\edef\next@{\codeof\next@}\ifx\next@\Arrowtok@
1734 \enter@{\pfromthep@ \cplusthec@}%
1735 \dimen@=#2\xydashl@ \advance\dimen@\xydashl@
1736 \enter@\DirectionfromtheDirection@ \begingroup
1737  \expandafter\vfromslide@i\expandafter{\the\dimen@}@\czeroEdge@
1738 \leave@ \idfromc@{@m2}%
1739 \cfromid@{@m}%
1740 \enter@{\pfromthep@ \cplusthec@}%
1741 \dimen@=#2\xydashl@ \advance\dimen@-\xydashl@
1742 \enter@\DirectionfromtheDirection@ \begingroup
1743  \expandafter\vfromslide@i\expandafter{\the\dimen@}@\czeroEdge@
1744 \leave@ \idfromc@{@m1}%
1745 \cfromid@{@m2}\swap@\cfromid@{@m1}\connect@{\dir 2}{-}%
1746 \fi\fi\fi\fi

1747 %

1748 %   label on the Arrow

1749 %

1750 \DN@{#8}\ifx\next@\empty\DN@{}\else\DN@{%
1751 \ifx\Arrowtok@\empty
1752 \Calong@@{.5}%
1753 \else\DN@{=}\edef\next@{\codeof\next@}\ifx\next@\Arrowtok@
1754 \Calong@@{.5}%
1755 \else\DN@{_}\edef\next@{\codeof\next@}\ifx\next@\Arrowtok@
1756 \cfromid@{@m}%
1757 \fi\fi\fi
1758 \enter@\cplusthec@
1759 \enter@\DirectionfromtheDirection@ \begingroup \aboveDirection@\xydashl@
1760  \ifx\Arrowtok@\empty
1761  \def\tmp@{0pt}%
1762  \else\DN@{=}\edef\next@{\codeof\next@}\ifx\next@\Arrowtok@
1763  \def\tmp@{\xydashl@}%
1764  \else\DN@{_}\edef\next@{\codeof\next@}\ifx\next@\Arrowtok@
1765  \def\tmp@{1.2\xydashl@}%
1766  \else\def\tmp@{0pt}%
1767  \fi\fi\fi
1768  \expandafter\vfromslide@i\expandafter{\tmp@}@\czeroEdge@ \leave@
1769 \droptwocelllabel@{#8}%
1770 }\fi \next@
1771 \leave@ }%

These are used to establish the location for the module-map indicator, giving best aesthetic appeal. It finds the location whose parameter value is the average of half-way along the complete curve and the average of parameter values at the the edges.

1781 \xydef@\gettwocelledges@{%
1782 \bgroup \the\crvpts@

1783 \edef\next@{\edges@}%
1784 \expandafter\gettwocelledges@@\next@ }
1786 \xydef@\gettwocelledges@@#1;#2,#3;#4,{%
1787 \dimen@=#2\advance\dimen@-#4\relax
1788 \advance\dimen@ 2\p@ \divide\dimen@ by4 \relax
1789 \edef\next@{\egroup\dimen@=\the\dimen@ }\next@}%

The end & Log DOCMODE3

1799 \xyendinput
1801 % $Log: xy2cell.doc,v $
1802 % Revision 3.3  1996/12/18 14:21:23  ross
1803 % Ross's version

1804 %

1805 % Revision 3.3.1.1  1996/12/18  08:49:34  ross
1806 % *** empty log message ***

1807 %

1808 % Revision 3.1  1995/09/05  20:36:33  ross
1809 % Release!

1810 %

1811 % Revision 3.0  1995/07/07  20:13:19  ross
1812 % Major release w/new User's Guide!

1813 %

1814 % Revision 2.14  1995/07/05  22:11:25  kris
1815 % Buglets...

1816 %

1817 % Revision 2.13  1995/07/04  15:04:51  ross
1818 % Ready for release of v3.

1819 %

1820 % Revision 2.12  1994/10/25  03:01:14  ross
1821 % Final 3beta release [bug fixes & AMS-LaTeX fitting].

1822 %

1823 % Revision 2.10  1994/07/01  01:19:46  ross
1824 % removed undefined references

1825 %

1826 % Revision 2.9  1994/06/09  12:51:27  ross
1827 % Release 3beta.

1828 %

1829 % NEW for version 2.9 based on unreleased code for version 2.6+.

3.5 Matrix feature

Vers. 3.4 by Kristoffer H. Rose ⟨krisrose@brics.dk⟩

This option implements “XY-matrices”, i.e., matrices where it is possible to refer to the entry objects by their row/column address. We first describe the general form of XY-matrices in §3.5.1, then in §3.5.2 we summarise the new ⟨coord⟩inate forms used to refer to entries. In §3.5.3 we explain what parameters can be set to change the spacing and orientation of the matrix, and in §3.5.4 we explain how the appearance of the entries can be changed.

Header:

1 %% $Id: xymatrix.doc,v 3.4 1997/05/18 01:14:25 krisrose Exp $
2 %%
3 %% Xy-pic ``Matrix'' feature.
4 %% Copyright (c) 1991-1997  Kristoffer H. Rose  <krisrose@brics.dk>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997  Kristoffer H. Rose  <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{matrix}{Matrix feature}{\stripRCS$Revision: 3.4 $}%
27 {Kristoffer H.~Rose}{krisrose@brics.dk}%
28 {BRICS/Computer Science, University of Aarhus, Ny Munkegade, building 540,
29  DK--8000 Aarhus~C}

3.5.1 XY-matrices

The fundamental command of this feature is

\xymatrix ⟨setup⟩ {⟨rows⟩}

that reads a matrix of entries in the generic TEX row&column format, i.e., where rows are separated with \\ and contain columns separated with & (we discuss in the following sections what ⟨setup⟩ can be). Thus a matrix with maxrow rows and maxcol columns where each entry contains row,col is entered as

                      \xymatrix{

                      1,1 &       1,2 & · · · 1,maxcol \\
                      2,1 &       2,2 &       2,maxcol \\

⋮  ...
maxrow,1 & maxrow,2 & maxrow,maxcol }

(TEXnically the & character represents any ‘alignment tab’, i.e., character with category code 4). A ⟨matrix⟩ can appear either in an XY-picture (as ⟨decor⟩) or “stand-alone”. The aspects in which \xymatrix differs from ordinary matrix constructions, such as Plain TEX’s

\matrix{… } and L^{A}TEX’s array environment, are

• arbitrary XY-pic ⟨decor⟩ations may be specified in each entry and will be interpreted in a state where c is the current entry,

• the entire matrix is an object itself with reference point as the top left entry, and

• a progress message “<xymatrix rowsxcols size>” is printed for each matrix with rows × cols entries and XY-pic complexity size (the number of primitive operations performed), unless the declaration \SilentMatrices is issued.

• Entries starting with a * are special (described in §3.5.4)^{2}, so use {*} to get a *.

For example,

\xy
 \xymatrix{A&B\\C&D}
 \drop\frm{-}
 \drop\cir<8pt>{}
\endxy

will typeset

[figure: A; B; C; D]

Bug: Matrix nesting is not safe.

Matrices are often quite slow to typeset so as a convenience all matrices can be set to compile (and not) automatically with the declarations

                                 \CompileMatrices
                                 \NoCompileMatrices

Matrices can be compiled or not individually, by using the explicit commands \xymatrixcompile and \xymatrixnocompile as well as by encapsulating in the usual \xycompileto{name}{… } (see note 1.5e).

Note: Matrices will only compile correctly if all entries start with a nonexpandable token, i.e., { or \relax or some non-active character.

On the following code: The complexity of this option stems from the fact that we cannot build the actual XY-picture until after the matrix has been typeset so that we know the sizes and places of all the entries. The handling described here is thus separated into several subprocedures.

Setup: Not much—only to keep track of the rows and columns. These are not accesible to the user—should they?

159 \xynew@{count}\Row
160 \xynew@{count}\Col

2In general it is recommended that entries start with a non-expanding token, i.e., an ordinary (non-active) character, {, or \relax, for compilation to work.

162 \xydef@\maxrow@{0}              % highest row number used
163 \xydef@\maxcol@{0}              % highest column number used
164 \xydef@\maxcolrow@{0}           % a row with maximal number of columns

There are some user-defined parameters summarised later.

The following is an experimental set of ‘optimal’ queueing macros using two queues and two counters to keep track of the progress.

173 \xynew@{toks}\queue@
174 \xynew@{toks}\queue@@
176 \xynew@{count}\qcount@
177 \xynew@{count}\qcount@@
179 \xydef@\clearq@{%
180 \global\queue@={}\global\qcount@=\@ne
181 \global\queue@@={}\global\qcount@@=\z@}
183 \xydef@\addq@#1{\global\advance\matrixsize@\@ne
184 \ifnum\qcount@@<\qcount@ \let\addq@@=\addq@i
185 \else \let\addq@@=\addq@ii \fi
186 \expandafter\addq@@\the\queue@@\addq@@{#1}}
188 \xylet@\addq@@=\relax
190 \xydef@\addq@i#1\addq@@#2{%
191 \global\advance\qcount@@\@ne \global\queue@@={#1#2}}
193 \xydef@\addq@ii#1\addq@@#2{%
194 \global\advance\qcount@\@ne \global\qcount@@=\z@
195 \global\queue@=\expandafter{\the\queue@#1#2}\global\queue@@={}}
197 \xydef@\finishq@{\expandafter\addq@ii\the\queue@@\addq@@{}}

Hack: intended to make the addition of tokens to the token list faster: we first add to the ‘small’ \queue@@ as many times as we have added to the ‘big’ \queue@ before that. So we know we should always expand \queue@@: this is done first (last in the macro text). Then we call \addq@@ that will either add to the small one or add the small one to the big one and then clear the small one!

Usage: Call \clearq@ first. Then use \addq@ as many times as desired. To get the queue in \queue@ call \finishq@ and use it. Finally clear \queue@ (globally) or continue.

Main procedure: Here is the main code which is concerned with initialisations and output of messages explaining how far the matrix construction has progressed.

218 \xynew@{count}\matrixsize@
219 \xynew@{if}\ifnoisymatrices@ \noisymatrices@true
221 \xydef@\SilentMatrices{\noisymatrices@false}
222 \xydef@\NoisyMatrices{\noisymatrices@true}
224 \xydef@\xymatrixnocompile{\global\matrixsize@=\z@
225 \ifnoisymatrices@\message{<xymatrix}\fi
226 \if\inxy@
227 \DN@{\nter@{}\xy@\xymatrix{\enter@{%
228  \def\noexpand\xy@minX@@{\xy@minX@@}\def\noexpand\xy@maxX@@{\xy@maxX@@}%
229  \def\noexpand\xy@minY@@{\xy@minY@@}\def\noexpand\xy@maxY@@{\xy@maxY@@}%
230  \edef\noexpand\xymatrixprefix@@{\codeof\xymatrixprefix@@}}}}%
231 \else \DN@{\xy \nter@\endxy \xy@\xymatrix{\nter@{}}}\fi \next@

232 \xy@@{\save@ \edef\matrixorigin@{\X@c=\the\X@c \Y@c=\the\Y@c}%
233 \edef\xy@minX@@{\the\X@c}\edef\xy@maxX@@{\the\X@c}%
234 \edef\xy@minY@@{\the\Y@c}\edef\xy@maxY@@{\the\Y@c}}%
235 \xdef\maxrow@{0}\xdef\maxcol@{0}\xdef\maxcolrow@{0}%
236 \mkHWdefaults@ \xymatrix@prefix""}
238 \xylet@\xymatrix=\xymatrixnocompile
240 \xydef@\xymatrixprefix@@{}
242 \xydef@\xymatrix@prefix"#1"{\DN@{#1}\edef\xymatrixprefix@@{\codeof\next@}%
243 \DNii@##1{\xy@{"#1"}{\edef\xymatrixprefix@@{##1}}}%
244 \expandafter\nextii@\expandafter{\xymatrixprefix@@}%
245 \xyFN@\xymatrix@setup}
247 \xydef@\xymatrix@setup{%
248 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xymatrix@setup}%gobble spaces
249 \else\ifx \bgroup\next \let\next@=\xymatrix@ii
250 \else\addAT@\ifx\next \addAT@\DN@{\xy@{@}{}\xyFN@\xymatrix@at}%
251 \else\ifx "\next \let\next@=\xymatrix@prefix
252 \else \DN@{\xyerror@{\string\xymatrix<setup>{<rows>} expected}{}}%
253 \fi\fi\fi\fi \next@}
255 \xydef@\xymatrix@ii#1{%

256 %

257 %\W@{ H@max=\meaning\H@max}%
258 %\W@{ W@max=\meaning\W@max}%
259 %\W@{ HW@max=\meaning\HW@max}%
260 %\W@{ mkHrow@={\meaning\mkHrow@}}%
261 %\W@{ mkWcol@={\meaning\mkWcol@}}%
262 %\W@{ mkHmax@={\meaning\mkHmax@}}%
263 %\W@{ mkWmax@={\meaning\mkWmax@}}%
264 %\W@{ mkHWmax@={\meaning\mkHWmax@}}%

265 %

266 \xymatrix@pretypeset{#1}%
267 %  \ifnum\maxcol@=\z@ \mkWcol@ \mkWmax@ %\mkHrow@ \mkHmax@
268 \ifnum\maxcol@=\z@ \mkWcol@ \mkWmax@ \mkHrow@ \mkHmax@
269  \xdef\maxcol@{\the\Col}\xdef\maxcolrow@{\the\Row}\fi
270 \ifnoisymatrices@\message{\maxcol@ x\maxrow@}\fi
271 \xymatrix@measureit@@ \the\queue@ \global\queue@={}%
272 \xymatrix@typeset{#1}\restore\xymatrix@insert
273 \xy@@\leave@ \leave@
274 \ifnoisymatrices@\message{\the\matrixsize@>}\fi \ignorespaces}

Here is where compilation of matrices is turned on/off.

280 \xydef@\xymatrixcompile#1#{\xymatrixcompile@{#1}}
281 \xydef@\xymatrixcompile@#1#2{\xycompile{\xymatrixnocompile#1{#2}}}
283 \xydef@\CompileMatrices{\let\xymatrix=\xymatrixcompile}
284 \xydef@\NoCompileMatrices{\let\xymatrix=\xymatrixnocompile}

To Do: Proper nesting that ensures that the matrix state is reestablished after the current one has been typeset.

Each subprocedure is explained below.

Set row-rotation: This sets the general direction of the rows as the current direction indicates. This direction is not known until XY-time so it gets put into the row/column definitions.

299 \xydef@\xy@cossign@@{+}
300 \xydef@\xy@sinsign@@{+}
301 \xydef@\xy@cosabs@@{1}
302 \xydef@\xy@sinabs@@{0}
303 \xydef@\xy@tanabs@@{0}
304 \xydef@\xy@cotabs@@{100}
306 \xydef@\xymatrix@rotation{
307 \xy@@{%
308 \edef\xy@cossign@@{\ifdim\cosDirection\p@<\z@-\else+\fi}%
309 \edef\xy@sinsign@@{\ifdim\sinDirection\p@<\z@-\else+\fi}%
310 \edef\xy@cosabs@@{%
311  \if\xy@cossign@@\cosDirection\else\xy@cossign@@\cosDirection\fi}%
312 \edef\xy@sinabs@@{%
313  \if\xy@sinsign@@\sinDirection\else\xy@sinsign@@\sinDirection\fi}%
314 \dimen@=\xy@cosabs@@\p@ \dimen@ii=\xy@sinabs@@\p@
315 \ifdim\dimen@ii<.01\p@ \def\xy@cotabs@@{100}%
316 \else \quotient@\xy@cotabs@@\dimen@\dimen@ii \fi
317 \dimen@=\xy@cosabs@@\p@ \dimen@ii=\xy@sinabs@@\p@
318 \ifdim\dimen@<.01\p@ \def\xy@tanabs@@{100}%
319 \else \quotient@\xy@tanabs@@\dimen@ii\dimen@ \fi}}

Pretypeset: The purpose of this is to

• set box8 to an halign with all the entries properly typeset to be measured in the next step, and

• store in a queue the operations that will define each entry as an object once the measurement is done and the distances between rows and columns is known.

This is achieved as follows: Row/column counters, maxima, and queues are reset. The tab- and interlineskip is removed to make taking the constructed box apart easier. And the halign template is used to apply an appropriate action for each entry that updates the counters and queue.

The special \xymatrixsavedCOORD@ is used to store the original \COORD@ except when diagrams are nested.

346 \xylet@\xymatrixsavedCOORD@=\relax
348 \xydef@\xymatrix@pretypeset#1{%
349 \global\Row=\z@ \xdef\maxcol@{0}\clearq@
350 \setbox8=\vtop{%
351 \ifx\xymatrixsavedCOORD@\relax \let\xymatrixsavedCOORD@=\COORD@ \fi
352 \let\COORD@=\xymatrixCOORD@
353 \everycr{}\let\\=\cr \tabskip=\z@ \offinterlineskip
354 \halign{\prentry@ ##!@&&\xyFN@\prentry@@##!@\cr#1\crcr}%
355 \prentry@@@}%
356 \xdef\maxrow@{\the\Row}%
357 \finishq@}

The first entry in each row is special; in particular it moves the entries from the columns of the previous row (if any) into the second-level queue:

365 \xydef@\prentry@{\relax
366 \ifnum\Row>\z@
367 \ifnum\maxcol@<\Col\xdef\maxcol@{\the\Col}\xdef\maxcolrow@{\the\Row}\fi
368 \expandafter\xdef\csname maxcol@\the\Row\endcsname{\the\Col}\fi
369 \global\advance\Row\@ne \global\Col=\z@ \xyFN@\prentry@@}

The common part should first typeset the object. Then the resulting ⟨setup⟩ commands should be emitted as described below.

While typesetting the entry, XY-commands are disabled by redefining \xy@ to just ‘eat’ its arguments, so they don’t interfere…

380 \xylet@\lastprentry@@=\relax
382 \xydef@\xyeatall@{\let\xy@=\xyeat@ \change@oxy@\xyeat@ \let\xy@@ix@=\eat@}
384 \xydef@\prentry@@{\global\advance\Col\@ne
385 \let\next@=\prentry@@norm
386 \ifoldxymatrix@\else \ifx *\next \DN@*{\xyFN@\prentry@@star}\fi \fi
387 \next@}
389 \xydef@\prentry@@star{\ifx *\next \DN@*{\xyFN@\prentry@@star@ii}%
390 \else \DN@##1##{\prentry@@star@i{##1}}\fi \next@}
392 \xydef@\prentry@@star@i#1#2#3!@{\gdef\lastprentry@@{*#1{#2}#3}%
393 \setbox\lastobjectbox@=\object#1{#2}%
394 \prentry@@x}
396 \xydef@\prentry@@star@ii{%
397 \ifx [\next
398 \DN@[##1]{\DN@####1{\def\entrymodifiers@{[##1]####1}}%
399  \expandafter\next@\expandafter{\entrymodifiers@}\prentry@@norm}%]
400 \else
401 \DN@##1{\DN@####1{\def\entrymodifiers@{##1####1}}%
402  \expandafter\next@\expandafter{\entrymodifiers@}\prentry@@norm}%
403 \fi \next@}
405 \xydef@\prentry@@norm#1!@{\gdef\lastprentry@@{#1}%
406 \DN@{\setbox\lastobjectbox@=\object}%
407 \expandafter\next@\entrymodifiers@{\xyeatall@ \everyentry@ #1}%
408 \prentry@@x}
410 \xydef@\prentry@@x{%
411 \edef\next@{{\noexpand\pre@emit{\the\Row}{\Upness@}{\the\Col}{\Leftness@}%
412 {\the\L@c}{\the\R@c}{\the\D@c}{\the\U@c}{\expandafter\noexpand\the\Edge@c}}}%
413 \expandafter\addq@\next@ \box\lastobjectbox@}

Finally the following ensures that the last row in the diagram is treated correctly: if the last entry was an empty row then we ignore the row entirely if the \ifoldxymatrix@ switch is set just as we ignore *-entries above.

422 \xynew@{if}\ifoldxymatrix@ \oldxymatrix@false
424 \xydef@\prentry@@@{\relax \let\next@=\prentry@@@i
425 \ifoldxymatrix@ \ifnum\Col=\@ne \ifx\lastprentry@@\empty
426  \global\advance\Row\m@ne \let\next@=\relax \fi\fi\fi
427 \global\let\lastprentry@@=\relax \next@}
429 \xydef@\prentry@@@i{%

430 \ifnum\maxcol@<\Col \xdef\maxcol@{\the\Col}\xdef\maxcolrow@{\the\Row}\fi
431 \expandafter\xdef\csname maxcol@\the\Row\endcsname{\the\Col}}

Furthermore the code (l.464) sets the edge and extents of the object and (l.465) adds the object to the size of the matrix. Bug: Currently ignores upness and leftness parameters.

439 \xydef@\xy@minX@@{\z@}
440 \xydef@\xy@maxX@@{\z@}
441 \xydef@\xy@minY@@{\z@}
442 \xydef@\xy@maxY@@{\z@}
444 \xydef@\pre@emit#1#2#3#4#5#6#7#8#9{%
445 % #1=R,#2=Upn,#3=C,#4=Leftn,#5=L,#6=R,#7=D,#8=U,#9=Edge.
446 \global\Row=#1\global\Col=#3\relax
447 \ifnum#3=\@ne
448 \ifnum#1=\@ne \xy@@{\matrixorigin@}
449 \else \count@@=#1\advance\count@@\m@ne
450  \edef\next@{\noexpand\xy@@{\noexpand\cfromid@
451  {\xymatrixprefix@@\the\count@@,1}}}\next@
452  \pre@emit@ \W@maxout\Hrow@c@@\W@maxin\Hrow@in\xy@tanabs@@
453  \X@c\xy@sinsign@@\xy@sinabs@@\xymatrixrowsep@
454  \pre@emit@ \Hrow@c@@\W@maxout\Hrow@in\W@maxin\xy@cotabs@@
455  \Y@c{-\xy@cossign@@}\xy@cosabs@@\xymatrixrowsep@
456 \fi
457 \else \count@@=#3\advance\count@@\m@ne
458  \pre@emit@ \Wcol@c@@\H@maxout\Wcol@in\H@maxin\xy@cotabs@@
459  \X@c\xy@cossign@@\xy@cosabs@@\xymatrixcolsep@
460  \pre@emit@ \H@maxout\Wcol@c@@\H@maxin\Wcol@in\xy@tanabs@@
461  \Y@c\xy@sinsign@@\xy@sinabs@@\xymatrixcolsep@
462 \fi
463 \DN@##1{\xy@@{\L@c=#5\R@c=#6\D@c=#7\U@c=#8\Edge@c={#9}\idfromc@{##1#1,#3}}}%
464 \expandafter\next@\expandafter{\xymatrixprefix@@}
465 \xy@@{
466 \dimen@=\X@c \advance\dimen@-\L@c
467  \ifdim\dimen@<\xy@minX@@ \edef\xy@minX@@{\the\dimen@}\fi
468 \dimen@=\X@c \advance\dimen@+\R@c
469  \ifdim\dimen@>\xy@maxX@@ \edef\xy@maxX@@{\the\dimen@}\fi
470 \dimen@=\Y@c \advance\dimen@-\D@c
471  \ifdim\dimen@<\xy@minY@@ \edef\xy@minY@@{\the\dimen@}\fi
472 \dimen@=\Y@c \advance\dimen@+\U@c
473  \ifdim\dimen@>\xy@maxY@@ \edef\xy@maxY@@{\the\dimen@}\fi}}

The following procedure represents the similarity of the four lines for the coordinates in the computation above… To Do: describe this properly…

481 \xydef@\pre@emit@#1#2#3#4{#1\A@ #2\B@ #3\R@ #4\dimen@
482 \edef\next@{{\the\A@}{\the\B@}{\the\R@}{\the\dimen@}}%
483 \expandafter\pre@emit@i\next@}
485 \xydef@\pre@emit@i#1#2#3#4#5{\xy@@{%
486 % Emit R := min(#1,#5#2) + min(#3,#5#4)
487 \dimen@=#2\R@=#5\dimen@ \dimen@=#1\relax \ifdim\R@>\dimen@ \R@=\dimen@ \fi
488 \dimen@=#4\B@=#5\dimen@ \dimen@=#3\relax \ifdim\B@>\dimen@ \B@=\dimen@ \fi

489 \advance\R@\B@}%
490 \pre@emit@ii}
492 \xydef@\pre@emit@ii#1#2#3#4{\xy@@{%
493 % Emit #1 := #1 + #2*[ R + #3#4 ]
494 \dimen@=#4\dimen@=#3\dimen@ \advance\R@\dimen@ \advance#1#2\R@}}
496 \xydef@\Wcol@in#1{#1=\csname Wcol@\the\Col\endcsname #1=.5#1}
497 \xydef@\Wcol@out#1{#1=\csname Wcol@\the\Col\endcsname #1=.5#1}
498 \xydef@\Wcol@c@@#1{#1=\csname Wcol@\the\count@@\endcsname #1=.5#1}
499 \xydef@\W@maxin#1{#1=\W@max #1=.5#1}
500 \xydef@\W@maxout#1{#1=\W@max #1=.5#1}
502 \xydef@\Hrow@in#1{#1=\csname Hrow@\the\Row\endcsname #1=.5#1}
503 \xydef@\Hrow@out#1{#1=\csname Hrow@\the\Row\endcsname #1=.5#1}
504 \xydef@\Hrow@c@@#1{#1=\csname Hrow@\the\count@@\endcsname #1=.5#1}
505 \xydef@\H@maxin#1{#1=\H@max #1=.5#1}
506 \xydef@\H@maxout#1{#1=\H@max #1=.5#1}

Bug: It should be possible to change te adjustment more profoundly for individual entries, rows, and columns.

Measure: Take the created box8 apart to define the macros \Wcol@col and \Hrow@row containing the width and height of the bounding box of the entries in the row/column. Finally the commands collected in the queue are executed (hopefully they’ll invoke \pre@emit a number of times). This is a hook because some special cases won’t need it…

521 \xydef@\H@max{\z@}
522 \xydef@\W@max{\z@}
523 \xydef@\HW@max{\z@}
525 \xydef@\mkHrow@{}
526 \xydef@\mkWcol@{}
527 \xydef@\mkHmax@{}
528 \xydef@\mkWmax@{}
529 \xydef@\mkHWmax@{}
531 \xydef@\mkHWdefaults@{\let\xymatrix@measureit@@=\xymatrix@measureit
532 \let\mkHrow@=\Hrow@R \let\mkWcol@=\Wcol@C
533 \def\mkHmax@{\ifdim\dimen@>\H@max\relax \xdef\H@max{\the\dimen@}\fi}%
534 \def\mkWmax@{\ifdim\dimen@>\W@max\relax \xdef\W@max{\the\dimen@}\fi}%
535 \let\mkHWmax@=\HWmax@max}
537 \xydef@\Hrow@R{\expandafter\xdef\csname Hrow@\the\Row\endcsname{\the\dimen@}}
538 \xydef@\Wcol@C{\expandafter\xdef\csname Wcol@\the\Col\endcsname{\the\dimen@}}
540 \xydef@\Hrow@max{\expandafter\gdef\csname Hrow@\the\Row\endcsname{\H@max}}
541 \xydef@\Wcol@max{\expandafter\gdef\csname Wcol@\the\Col\endcsname{\W@max}}
543 \xydef@\Hrow@HWmax{\expandafter\gdef\csname Hrow@\the\Row\endcsname{\HW@max}}
544 \xydef@\Wcol@HWmax{\expandafter\gdef\csname Wcol@\the\Col\endcsname{\HW@max}}
546 \xydef@\HWmax@max{%
547 \ifdim\H@max>\W@max\global\let\HW@max=\H@max\else\global\let\HW@max=\W@max\fi}
549 \xydef@\HWmax@set#1{\gdef\HW@max{#1}%
550 \global\let\H@max=\HW@max \global\let\W@max=\HW@max}

552 \xydef@\xymatrix@measureit{%
553 \xdef\H@max{\z@}\xdef\W@max{\z@}%
554 \setbox6=\vbox{\unvbox8 \global\Row=\maxrow@
555 \loop@ \dimen@ii=\lastskip\unskip \ifnum\z@<\Row
556  \setbox4=\lastbox \dimen@=\dp4 \advance\dimen@\ht4 \mkHrow@ \mkHmax@
557  \ifnum\Row=\maxcolrow@
558  \setbox2=\hbox{\unhbox4 %
559  \global\Col=\maxcol@
560  \loop@ \dimen@ii=\lastskip\unskip \ifnum\z@<\Col
561  \setbox\z@=\lastbox \dimen@=\wdz@ \mkWcol@ \mkWmax@
562  \global\advance\Col\m@ne
563  \repeat@}\fi
564  \global\advance\Row\m@ne
565  \repeat@}%
566 \mkHWmax@}
568 \xylet@\xymatrix@measureit@@=\relax

To Do: Allow non-default spacing between particular rows/columns as well as different justification of the entire matrix…

Typeset: Retypeset the entire diagram using a hacked halign: its template typesets each entry as

\POS"row,col"* object \relaxXY-commands\relax

where object is the contents of the entry translated into XY-pic ⟨object⟩ form and XY-commands entails the commands used in this particular entry.

586 \xydef@\xymatrix@typeset#1{%
587 \clearq@
588 \hbox{\vtop{\xyqall@
589  \xy@@{\ifx\xymatrixsavedCOORD@\relax
590  \enter@{\noexpand\let\noexpand\COORD@\noexpand\xymatrixsavedCOORD@}%
591  \let\xymatrixsavedCOORD@=\COORD@ \let\COORD@=\xymatrixCOORD@
592  \else \enter@{}\fi}%
593  \ifx\xymatrixsavedCOORD@\relax \let\xymatrixsavedCOORD@=\COORD@ \fi
594  \let\COORD@=\xymatrixCOORD@
595  \kern\z@ \global\Row=\z@
596  \everycr{}\let\\=\cr \tabskip=\z@ \offinterlineskip
597  \halign{\entry@##!@&&\entry@@##!@\cr#1\crcr}%
598  \xy@@{\leave@}}}%
599 \finishq@ \expandafter\xy@@\expandafter{\the\queue@}\global\queue@={}}

Here are the template execution macros: We reset the \queue@ for each entry, \drop it the usual way except first all XY-commands are ‘redirected’ to the queue, and then typeset them.

607 \xydef@\entry@{\relax \global\advance\Row\@ne \global\Col=\z@ \entry@@}

Again some parsing determines whether this is a *-object or a normal object:

614 \xydef@\entry@@{\global\advance\Col\@ne
615 \DN@##1,##2,##3@{\xy@{ENTRY "##3##1,##2"}{\Row=##1 \Col=##2\relax
616  \cfromid@{##3##1,##2}\pfromc@}}%
617 \edef\nextii@{\the\Row,\the\Col,\xymatrixprefix@@ @}%
618 \expandafter\next@\nextii@

619 \xyFN@\entry@@i}
621 \xydef@\entry@@i{\let\next@=\entry@@norm
622 \ifoldxymatrix@\else \ifx *\next \DN@*{\xyFN@\entry@@star}\fi \fi
623 \next@}
625 \xydef@\entry@@star{\ifx *\next \DN@*{\xyFN@\entry@@star@ii}%
626 \else \DN@##1##{\entry@@star@i{##1}}\fi \next@}
628 \xydef@\entry@@star@i#1#2#3!@{%
629 \xy@@ix@{{#1}{#2}}\xy@@{\expandafter\dropentry@\the\toks9}%
630 \setboxz@h{\xyqall@
631 \ifx\xymatrixsavedCOORD@\relax \let\xymatrixsavedCOORD@=\COORD@ \fi
632 \let\COORD@=\xymatrixCOORD@ \everyentry@ #3}%
633 \setbox\z@=\copy\voidb@x}
635 \xydef@\entry@@star@ii{%
636 \ifx [\next
637 \DN@[##1]{\DN@####1{\def\entrymodifiers@{[##1]####1}}%
638  \expandafter\next@\expandafter{\entrymodifiers@}\entry@@norm}%]
639 \else
640 \DN@##1{\DN@####1{\def\entrymodifiers@{##1####1}}%
641  \expandafter\next@\expandafter{\entrymodifiers@}\entry@@norm}%
642 \fi \next@}
644 \xydef@\entry@@norm#1!@{%
645 \DN@##1{\expandafter\xy@@ix@
646 \expandafter{\expandafter{\entrymodifiers@}{##1}}}%
647 \expandafter\next@\expandafter{\everyentry@#1}%
648 \xy@@{\expandafter\dropentry@\the\toks9}%
649 \setbox\z@=\expandafter\object\entrymodifiers@{\xyqall@
650 \ifx\xymatrixsavedCOORD@\relax \let\xymatrixsavedCOORD@=\COORD@ \fi
651 \let\COORD@=\xymatrixCOORD@ \everyentry@ #1}%
652 \setbox\z@=\copy\voidb@x}

Dropping the entry is just retypesetting it at the right location again ignoring the XY-stuff:

659 \xydef@\dropentry@#1#2{\drop@{#1}{\xyeatall@
660 \ifx\xymatrixsavedCOORD@\relax \let\xymatrixsavedCOORD@=\COORD@ \fi
661 \let\COORD@=\xymatrixCOORD@ #2}}

The macros used for queuing are these; only the toks9 replacement is tricky; furthermore queueing is not done if we are saving because the effect will give the same result without risk of extremely long lines in the compiled file!

670 \xydef@\xyqall@{%
671 \ifxysaving@ \let\xy@=\xyqs@ \let\xy@@ix@=\xysave@@toksix@
672 \else \let\xy@=\xyq@ \let\xy@@ix@=\xyq@@toksix@ \fi
673 \change@oxy@\xy@}
675 \xydef@\xyq@#1#2{\addq@{#2}}
677 \xydef@\xyq@@toksix@{\begingroup
678 \xyuncatcodes \afterassignment\xyq@@toksix@i \global\toks9=}
680 \xydef@\xyq@@toksix@i{%
681 \DN@##1{\endgroup \xy@@{\global\toks9={##1}}}%

682 \expandafter\next@\expandafter{\the\toks9}}
684 \xydef@\xyqs@{\global\advance\matrixsize@\@ne \xysave@}

Insert: Finally we insert the matrix in the XY-picture logically by ensuring that it has the right size

693 \xydef@\xymatrix@insert{%
694 \xy@@{\edef\nextii@{{\xy@minX@@}{\xy@maxX@@}{\xy@minY@@}{\xy@maxY@@}}%
695 \expandafter\xymatrix@insert@\nextii@}}
697 \xydef@\xymatrix@insert@#1#2#3#4{\matrixorigin@
698 \L@c=+\X@c \advance\L@c-#1\relax
699 \R@c=-\X@c \advance\R@c+#2\relax
700 \D@c=+\Y@c \advance\D@c-#3\relax
701 \U@c=-\Y@c \advance\U@c+#4\relax
702 \Edge@c={\rectangleEdge}}

To Do: Should handle other forms than reference point at center of "1,1" as hardcoded here. In particular reference point at baseline of "1,1" would be useful…

3.5.2 New coordinate formats

It is possible within entries to refer to all the entries of the XY-matrix using the following special ⟨coord⟩inate forms:

"r,c" Position and extents of entry in row r, column c

(top left is "1,1")

[Δr,Δc]  Δr rows below, Δc columns right of current entry

[ ⟨hop⟩* ] entry reached by ⟨hop⟩s; each ⟨hop⟩ is one of dulr

describing one ‘move’ to a neighbor entry

[ ⟨hop⟩^{+} ⟨place⟩ ] ⟨place⟩ on straight line to non-empty [⟨hop⟩*]

So the current entry has the synonyms [0,0], [], [rl], [ud], [dudu], etc., as well as its ‘absolute’ name "r,c".

These forms are useful for defining diagrams where the entries are related, e.g.,

[figure: A; B; C]

was typeset by

$$\xy
\xymatrix{
 A \POS[];[d]**\dir{~},
       [];[dr]**\dir{-}    \\
 B & C \POS[];[l]**\dir{.} }
\endxy$$

If an entry outside the XY-matrix is referenced then an error is reported.

In case several matrices are used in the same diagram, and they refer to each other, then it is useful to give the matrices different "⟨prefix⟩" ⟨setup⟩ such that they can refer to each other using the following special coordinate forms that all have the same meaning except the target entry is picked from a particular matrix:

"⟨prefix⟩r,c"

["⟨prefix⟩"Δr,Δc] ["⟨prefix⟩" ⟨hop⟩* ] ["⟨prefix⟩" ⟨hop⟩^{+} ⟨place⟩ ]

In fact absolute references must always be given using "⟨prefix⟩⟨row⟩,⟨col⟩", even inside the matrix itself .

Here is an example using this:

[figure: A; B; C; D; A′; B′; C′; D′]

was typeset (using the ‘frame’ extension and ‘arrow’ feature) by

\xy
  \xymatrix"*"{%
   A & B \\
   C & D }%
  \POS*\frm{--}
  \POS-(10,3)
  \xymatrix{%
   A' \ar@{.}["*"] & B' \ar@{.}["*"] \\
   C' \ar@{.}["*"] & D' \ar@{.}["*"] }%
  \POS*\frm{--}
\endxy

These handle the parsing and interpretation of bracketed ⟨coord⟩inates; the number is computed already at parse time:

804 \xylet@\thematrixCOORD@@=\relax
805 \xylet@\thematrixprefix@@=\relax
807 \xydef@\xymatrixCOORD@{%
808 \ifx [\next %]
809 \DN@[##1]{\xy@{[##1]}{\def\thematrixCOORD@@{[##1]}}%
810  \xyFN@\xymatrixCOORD@i##1]}%
811 \else \let\next@=\xymatrixsavedCOORD@ \fi \next@}
813 \xydef@\xymatrixCOORD@i{\count@=\Row \count@@=\Col
814 \let\thematrixprefix@@=\xymatrixprefix@@
815 \ifcat A\noexpand\next
816 \DN@##1{\expandafter\notrelaxorelse@\csname xymatrixCOORD@i@##1\endcsname
817  \xymatrixCOORD@other}%[[
818 \else\ifx ]\next \DN@]{\xymatrixCOORD@x}%
819 \else\ifx "\next \DN@"##1"{\DN@{##1}\edef\thematrixprefix@@{\codeof\next@}%
820  \xyFN@\xymatrixCOORD@ii}%
821 \else \let\next@=\xymatrixCOORD@other \fi\fi\fi \next@}
823 \xydef@\xymatrixCOORD@i@u{\advance\count@ \m@ne\xyFN@\xymatrixCOORD@ii}
824 \xydef@\xymatrixCOORD@i@d{\advance\count@ \@ne \xyFN@\xymatrixCOORD@ii}

825 \xydef@\xymatrixCOORD@i@l{\advance\count@@\m@ne\xyFN@\xymatrixCOORD@ii}
826 \xydef@\xymatrixCOORD@i@r{\advance\count@@\@ne \xyFN@\xymatrixCOORD@ii}
828 \xydef@\xymatrixCOORD@ii{%
829 \ifcat A\noexpand\next
830 \DN@##1{\expandafter\notrelaxorelse@\csname xymatrixCOORD@i@##1\endcsname
831  \xymatrixCOORD@error}%
832 \else\ifx ]\next \DN@]{\xymatrixCOORD@x}%
833 \else \let\next@=\xymatrixCOORD@xx \fi\fi \next@}
835 \xydef@\xymatrixCOORD@error#1{\DN@{#1}%
836 \xyerror@{illegal <coord> (\codeof\next@): illegal [...] target form}{}%
837 \xyFN@\xymatrixCOORD@ii}
839 \xydef@\xymatrixCOORD@other#1,#2]{%
840 \advance\count@#1\advance\count@@#2\xymatrixCOORD@x}

The next does the actual lookup at XY-time where we can still print an error message using the saved original form.

847 \xydef@\xymatrixCOORD@x{%
848 \DN@##1{\xy@@{%
849  \expandafter\let\expandafter\next@\csname Q@##1\endcsname
850  \ifx\next@\relax \xyerror@RC{##1}\else \next@ \fi}%
851 \afterCOORD@}%
852 \edef\nextii@{{\thematrixprefix@@\the\count@,\the\count@@}}%
853 \expandafter\next@\nextii@}
855 \xydef@\xymatrixCOORD@xx{%
856 \DN@##1{\xy@@{%
857  \expandafter\let\expandafter\next@\csname Q@##1\endcsname
858  \ifx\next@\relax \xyerror@RC{##1}\else \next@\no@@ \fi}%
859 \afterPLACE\xymatrixCOORD@after}%
860 \edef\nextii@{{\thematrixprefix@@\the\count@,\the\count@@}}%
861 \expandafter\next@\nextii@}
863 \xydef@\xymatrixCOORD@after{%
864 \ifx ]\next \DN@]{\afterCOORD@}%
865 \else \let\next@=\xymatrixCOORD@error \fi \next@}
867 \xydef@\xyerror@RC#1{\xyerror@{in entry \string"\the\Row,\the\Col\string":
868  No \codeof\thematrixCOORD@@\space(is \string"#1\string") from here}{}}

3.5.3 Spacing and rotation

Any matrix can have its spacing and orientation changed by adding ⟨setup⟩ ‘switches’ between \xymatrix and the opening {.

The default spacing between entries of matrix is changed with the switches

@R⟨add op⟩ ⟨dimen⟩ @C⟨add op⟩ ⟨dimen⟩ @ ⟨add op⟩ ⟨dimen⟩

that change row spacing, column spacing, and both, respectively, as indicated by the ⟨add op⟩ and ⟨dimen⟩, where the ⟨dimen⟩ may be omitted and can be given as one of R and C to indicate the current value of the parameter in question. Note: there is no default.

In addition, XY-pic can be instructed to use a ‘fixed grid’ for the matrix with the switches

                                         @!R
                                         @!C
                                         @!

that ensure that the row spacing, column spacing, and both, respectively, pretending that all entries have the size of the largest entry (without modifying the real size of the entries, of course, only the spacing – to get the entries to really have the same size use a @*… ⟨setup⟩ described in §3.5.4 below). The special variants

                                     @!0

@!=⟨dimen⟩

pretend that entries have zero or ⟨dimen⟩ height and width for computing row and column spacing; as above inserting R or C just after the ! makes this affect only the row or column spacing, e.g., @!R0 means that the row spacing only is between the centers of the rows.

Finally, the spacing of things that are typeset can be adjusted separately:

@M⟨add op⟩ ⟨dimen⟩ @W⟨add op⟩ ⟨dimen⟩ @H⟨add op⟩ ⟨dimen⟩ @L⟨add op⟩ ⟨dimen⟩

will adjust the entry margin, entry width, entry height, and label separation used (the latter is actually passed to the arrow feature).

942 \xylet@\xymatrix@addop@@=\relax
944 \xydef@\xymatrix@at{\def\xymatrix@addop@@{\xymatrix@R\xymatrix@C}%
945 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xymatrix@at}%gobble spaces
946 \else\ifx !\next \DN@!{\xyFN@\xymatrix@fix}%
947 \else\addPLUS@\ifx \next \let\next@=\xymatrix@addop
948 \else\addDASH@\ifx \next \let\next@=\xymatrix@addop
949 \else\addEQ@\ifx \next \let\next@=\xymatrix@addop
950 \else\ifx 1\next \DN@1{\def\everyentry@{\vphantom(}%)
951 \let\objectmargin@=\p@ \xyFN@\xymatrix@setup}%
952 \else\ifx R\next \def\xymatrix@addop@@{\xymatrix@R}\DN@ R{\xymatrix@addop}%
953 \else\ifx C\next \def\xymatrix@addop@@{\xymatrix@C}\DN@ C{\xymatrix@addop}%
954 \else\ifx M\next \def\xymatrix@addop@@{\xymatrix@M}\DN@ M{\xymatrix@addop}%
955 \else\ifx L\next \def\xymatrix@addop@@{\xymatrix@L}\DN@ L{\xymatrix@addop}%
956 \else\ifx H\next \def\xymatrix@addop@@{\xymatrix@H}\DN@ H{\xymatrix@addop}%
957 \else\ifx W\next \def\xymatrix@addop@@{\xymatrix@W}\DN@ W{\xymatrix@addop}%
958 \else\ifx *\next \DN@*{\xyFN@\xymatrix@mods}%
959 \else \DN@{\afterDIRECTIONorEMPTY
960  {\xymatrix@rotation \xyFN@\xymatrix@setup}{%
961  \xyerror@{<addop> or <direction> or one of RCMLHW*! expected}{}%
962  \xyFN@\xymatrix@setup}}%
963 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
965 \xydef@\xymatrix@fix{%
966 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xymatrix@fix}%gobble spaces

967 \else\ifx R\next \let\mkHrow@=\Hrow@max \DN@ R{\xyFN@\xymatrix@fix@}%
968 \else\ifx C\next \let\mkWcol@=\Wcol@max \DN@ C{\xyFN@\xymatrix@fix@}%
969 \else \let\mkHrow@=\Hrow@HWmax \let\mkWcol@=\Wcol@HWmax
970 \let\next@=\xymatrix@fix@
971 \fi\fi\fi \next@}
973 \xydef@\xymatrix@fix@{%
974 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xymatrix@fix@}%gobble spaces
975 \else\ifx 0\next \def\mkHWmax@{\HWmax@set\z@}\DN@ 0{\xyFN@\xymatrix@setup}%
976 \else\addEQ@\ifx\next \addEQ@\DN@{\afterassignment\xymatrix@fix@x\dimen@ii=}%
977 \else \let\mkHWmax@=\HWmax@max \let\next@=\xymatrix@setup \fi\fi\fi \next@}
979 \xydef@\xymatrix@fix@x{%
980 \edef\mkHWmax@{\noexpand\HWmax@set{\the\dimen@ii}}\xyFN@\xymatrix@setup}
982 \xydef@\xymatrix@addop{\afterADDOP{\xyFN@\xymatrix@addop@}}
983 \xydef@\xymatrix@addop@{%
984 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xymatrix@addop@}%gobble spaces
985 \else\ifx R\next \DN@ R{\xy@{R}{}\dimen@ii=\xymatrixrowsep@\xymatrix@addop@x}%
986 \else\ifx C\next \DN@ C{\xy@{C}{}\dimen@ii=\xymatrixcolsep@\xymatrix@addop@x}%
987 \else \DN@{\afterassignment\xymatrix@addop@x\dimen@ii=}\fi\fi\fi \next@}
989 \xydef@\xymatrix@addop@x{\expandafter\xy@\expandafter{\the\dimen@ii}{}%
990 \xymatrix@addop@@ \xyFN@\xymatrix@setup}
992 \xydef@\xymatrix@R{\Addop@@\xymatrixrowsep@\dimen@ii}
993 \xydef@\xymatrix@C{\Addop@@\xymatrixcolsep@\dimen@ii}
995 \xydef@\xymatrix@M{\Addop@@\objectmargin@\dimen@ii}
996 \xydef@\xymatrix@L{\Addop@@\labelmargin@\dimen@ii}
998 \xydef@\xymatrix@H{\Addop@@\objectheight@\dimen@ii}
999 \xydef@\xymatrix@W{\Addop@@\objectwidth@\dimen@ii}

The spacing can also be changed for en entire TEX group by the declarations

                          \xymatrixrowsep ⟨add op⟩ {⟨dimen⟩}
                          \xymatrixcolsep ⟨add op⟩ {⟨dimen⟩}

The default spacing for both is 2pc.

1014 \xydef@\xymatrixrowsep@{2pc}
1015 \xydef@\xymatrixcolsep@{2pc}
1017 \xydef@\xymatrixrowsep{\afterADDOP{\Addop@@\xymatrixrowsep@}}
1018 \xydef@\xymatrixcolsep{\afterADDOP{\Addop@@\xymatrixcolsep@}}

To Do: optimize processing of matrices with constant grid.

An entire matrix can be rotated by adding a rotation ⟨setup⟩ of the form

@⟨direction⟩

This will set the orientation of the rows to ⟨direction⟩ (the default corresponds to r, i.e., rows are oriented left to right).

The code is the first procedure of the main matrix code above (l.306); factors are used by \pre@emit.

3.5.4 Entries

The appearance of a single entry can be modified by entering it as

* ⟨object⟩ ⟨pos⟩ ⟨decor⟩

This makes the particular entry ignore the entry modifiers and typeset as a kernel object with the same reference point as the (center of) the default object would have had.

Additional object ⟨modifier⟩s may be added to an otherwise ordinary entry by using the forms

**[⟨shape⟩] ⟨entry⟩ **{⟨modifier⟩*} ⟨entry⟩

The first sets the default ⟨shape⟩ for objects (cf. note 1.4j), the second a default size (change, cf. note 1.4g), and the last makes it possible to add any ⟨object⟩ modifier of §1.4, e.g., for recentering entries after the default entry form which is equivalent to ‘!C +<2 × objectmargin>’ (with the effect of centering the object and add the objectmargin) to all sides.

Exercise 3.9: Typeset the following diagram:

[figure: A × B; /A; /B; B; ×A; A; B×; B × A]

It is also possible to use these @⟨setup⟩s (as usual between \xymatrix and the leading {):

@*[⟨shape⟩]

@* ⟨add op⟩ ⟨size⟩

which are equivalent to changing all entries to behave as if they had started with the similar **-form. To Do: Allow **⟨add op⟩⟨size⟩ ⟨entry⟩ for entries.

If the default set of entry modifiers should be changed then the following declaration must be issued before the \xymatrix command; this is the only way to actually switch the initial default centering and spacing off:

                            \entrymodifiers={ ⟨modifier⟩* }

Exercise 3.10: How did the author typeset the following matrix?

[figure: A; B; C; D]

Bug: The four constructions @*[…], **[…], @* ⟨add op⟩ ⟨size⟩, and, **{… }, accumulate in reverse order. Only entries starting with a single * completely override the modifiers ⟨setup⟩ with a @*-construction.

1143 \xydef@\xymatrix@mods{%
1144 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xymatrix@mods}%gobble spaces
1145 \else\ifx [\next
1146 \DN@ [##1]{\xy@{[##1]}{}\DN@####1{\def\entrymodifiers@{[##1]####1}}%
1147  \expandafter\next@\expandafter{\entrymodifiers@}\xyFN@\xymatrix@setup}%]
1148 \else\addPLUS@\ifx \next \DN@##1{\DNii@{##1}\xyFN@\xymatrix@change}%
1149 \else\addDASH@\ifx \next \DN@##1{\DNii@{##1}\xyFN@\xymatrix@change}%
1150 \else\addEQ@\ifx \next \DN@##1{\DNii@{##1}\xymatrix@set}%
1151 \else \let\next@=\xymatrix@mods@error \fi\fi\fi\fi\fi \next@}
1153 \xydef@\xymatrix@set{%
1154 \begingroup \plainxy@
1155 \afterVECTORorEMPTY\xymatrix@mods@x\xymatrix@mods@error}
1157 \xydef@\xymatrix@change{%
1158 \addEQ@\ifx\next \DN@##1{\expandafter\DNii@\expandafter{\nextii@##1}%
1159 \expandafter\xy@\expandafter{\nextii@}{}\begingroup \plainxy@
1160 \afterVECTORorEMPTY\xymatrix@mods@x\xymatrix@mods@xx}%
1161 \else \DN@{\expandafter\xy@\expandafter{\nextii@}{}\begingroup \plainxy@
1162 \afterVECTORorEMPTY\xymatrix@mods@x\xymatrix@mods@xx}\fi
1163 \next@}
1165 \xydef@\xymatrix@mods@x{\expandafter\xy@\expandafter{\nextii@}{}%
1166 \def\next@##1##2##3{\def\nextii@####1{##1##2####1##3}}%
1167 \addGT@{\addLT@{\expandafter\next@\expandafter{\nextii@}}}%
1168 \DN@##1{\gdef\tmp@@@{{##1}}}%
1169 \edef\nextiii@{{\the\X@c,\the\Y@c}}%
1170 \expandafter\expandafter\expandafter\next@
1171 \expandafter\expandafter\expandafter{\expandafter\nextii@\nextiii@}%
1172 \endgroup
1173 \DN@##1{\xy@{##1}{}\DN@####1{\def\entrymodifiers@{##1####1}}%
1174 \expandafter\next@\expandafter{\entrymodifiers@}\xyFN@\xymatrix@setup}%
1175 \expandafter\next@\tmp@@@}
1177 \xydef@\xymatrix@mods@xx{\expandafter\xy@\expandafter{\nextii@}{}%
1178 \expandafter\gdef\expandafter\tmp@@@\expandafter{\expandafter{\nextii@}}%
1179 \endgroup
1180 \DN@##1{\xy@{##1}{}\DN@####1{\def\entrymodifiers@{##1####1}}%
1181 \expandafter\next@\expandafter{\entrymodifiers@}\xyFN@\xymatrix@setup}%
1182 \expandafter\next@\tmp@@@}
1184 \xydef@\xymatrix@mods@error{\endgroup
1185 \xyerror@{Impossible @*<addop><size> <setup>.}{}\xyFN@\xymatrix@setup}
1187 \xywarnifdefined\entrymodifiers
1188 \expandafter\def\addEQ@\entrymodifiers#1{\def\entrymodifiers@{#1}\ignorespaces}
1190 \xydef@\entrymodifiers@{\entrybox}
1192 \xydef@\entrybox#1{\hbox{\setbox\z@=\objectbox{#1}%
1193 \L@p=\wdz@ \D@p=\ht\z@ \advance\D@p\dp\z@
1194 \dimen@=\objectwidth@ \advance\dimen@-\L@p
1195 \ifdim\dimen@>\z@ \advance\L@p\dimen@ \R@p=.5\dimen@ \else \R@p=\z@ \fi
1196 \dimen@=\objectheight@ \advance\dimen@-\D@p
1197 \ifdim\dimen@>\z@ \advance\D@p\dimen@ \fi

1198 \dimen@=\objectmargin@ \advance\L@p2\dimen@ \advance\D@p2\dimen@
1199 \U@p=-.5\ht\z@ \advance\U@p.5\dp\z@ \advance\R@p\objectmargin@
1200 \setboxz@h{\kern\R@p \raise\U@p\boxz@}%
1201 \wdz@=\L@p \ht\z@=.5\D@p \dp\z@=.5\D@p \boxz@}}

Finally, the following is specially suited for ‘one-line’ matrices included in text:

                                         @1

will insert a ‘math strut’ (\vphantom() into each entry to make its centering appropriate for text.

This is just an abbreviation using the following declaration which will setup ⟨decor⟩ that should be inserted before everything else in each entry. Initially it is empty but

                               \everyentry={ ⟨decor⟩ }

will insert ⟨decor⟩ first in each entry; inside the counter registers \Row and \Col are set to the current entry’s row and column, respectively. For example,

\everyentry={{\the\Row,\the\Col}}
\xymatrix @*[F]@*[o] {
 {} \POS[];[r]**\dir{..} & \\
 {} \POS[];[ur]**\dir{--}
}

will typeset

[figure: 1, 1; 1, 2; 2, 1]

1243 \xywarnifdefined\everyentry
1244 \expandafter\def\addEQ@\everyentry#1{\def\everyentry@{#1}\ignorespaces}
1246 \xylet@\everyentry@=\empty

Note: When using compilation, changes to \everyentry and \entrymodifiers will not result in recompilation even when the constructed matrix changes – you may have to remove the .xyc file manually.

Exercise 3.11: How did the author typeset the following diagram?

[figure: :; root; •; •; 1]

Hints: The arrow feature was used to make the bending arrows and the frame extension for the frames around each cell.

End & log

1291 \xyendinput
1293 % $Log: xymatrix.doc,v $
1294 % Revision 3.4  1997/05/18 01:14:25  krisrose
1295 % Essential bugfixes.

1296 %

1297 % Revision 3.3  1996/12/19 03:31:56  krisrose
1298 % Maintenance release

1299 %

1300 % Revision 3.1  1995/09/05  20:31:32  kris
1301 % Releasing!

1302 %

1303 % Revision 3.0  1995/07/07  20:14:21  kris
1304 % Major release w/new User's Guide!

1305 %

1306 % Revision 2.14  1995/07/06  02:56:02  kris
1307 % Buglets...

1308 %

1309 % Revision 2.13  1995/07/04  15:11:17  kris
1310 % Ready to release v3?

1311 %

1312 % Revision 2.12  1994/10/25  11:34:25  kris
1313 % Interim release just before v3 [works with AMS-LaTeX 1.2]...

1314 %

1315 % Revision 2.11  1994/07/05  10:37:32  kris
1316 % Third 3beta release [bug fixes].
1317 % Experimental graph feature included (for ECCT-94 presentation).

1318 %

1319 % Revision 2.9  1994/06/09  15:02:49  kris
1320 % Release 3beta.

1321 %

1322 % Revision 2.8  1994/04/08  04:30:00  kris
1323 % Second (bug fix) 3alpha release.

1324 %

1325 % Revision 2.7  1994/03/08  02:06:01  kris
1326 % Release 3alpha.

1327 %

1328 % Revision 2.6.9.1  1994/03/07  04:22:46  kris
1329 % Last internal 3alpha and pre-2.7 release.

1330 %

1331 % NEW for version 2.7 extracted from diagram code in xypic.doc 2.6.1.1.

3.6 Graph feature

Vers. 3.7 by Kristoffer H. Rose ⟨krisrose@brics.dk⟩

This option implements ‘XY-graph’, a special combinatoric drawing language suitable for diagrams like flow charts, directed graphs, and various forms of trees. The base of the language is reminiscent of the PIC [5] language because it uses a notion of the ‘current location’ and is based on ‘moves’. But the central construction is a ‘map’ combinator that is borrowed from functional programming.

Header:

1 %% $Id: xygraph.doc,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %%
3 %% Xy-pic ``Graph Combinator feature'' option.
4 %% Copyright (c) 1994-1997 Kristoffer H. Rose <krisrose@brics.dk>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{graph}{Graph feature}{\stripRCS$Revision: 3.7 $}%
27 {Kristoffer H.~Rose}{krisrose@brics.dk}%
28 {BRICS/Computer Science, University of Aarhus, Ny Munkegade, building 540,
29  DK--8000 Aarhus~C}

XY-graph makes use of facilities of the ‘arrow’ feature option of §3.3, which is therefore required.

50 \xyrequire{arrow}\xycatcodes

Figure 3.5 summarises the syntax of a ⟨graph⟩ with notes below. A ⟨graph⟩ can appear either in an XY-picture (as ⟨decor⟩) or “stand-alone”.^{3} Note: If you use \xygraph{… } inside constructions where & is significant (like plain TEX’s \halign or L^{A}TEX’s array environment) then make sure to add an extra level of braces around it.

Parsing: The parser does almost everything that this feature does because it is all implemented directly on top of other constructions, notably the kernel stack and the ⟨arrow⟩ construction.

The graph state always has the current value of ? both as the stacktop and in the special ⟨id⟩

"?NODE".

162 \xydef@\xygraph#1{\relax\graph#1\endgraph}
164 \xydef@\graph{\if\inxy@ \DN@{\xy@@{\nter@{}}}%

3In fact L^{A}TEX users can use a graph environment.

165 \else \DN@{\xy \xy@\xy{\nter@\endxy}}\fi \next@
166 \xy@\xygraph{\senter@ \idfromc@{?NODE}\spushc@
167 \expandafter\let\expandafter\next@\csname Q@graphbase\endcsname
168 \ifx\next@\relax \setbase@\z@\z@{3pc}\z@
169 \else \expandafter\next@ \fi}%
170 \GRAPH[]}
172 \xydef@\endgraph{\ignorespaces}
174 \xydef@\GRAPH{\xyFN@\GRAPH@}
176 \xydef@\GRAPH@{%

177 %

178 %\W@{GRAPH: next=\meaning\next}%

179 %

180 \ifx \space@\next \expandafter\DN@\space{\xyFN@\GRAPH@}%
181 \else\ifx :\next \DN@:{\xy@:{}\expandafter\GRAPHar@\GRAPHeveryarrow@@}%
182 \else\addDASH@\ifx\next
183 \addDASH@\DN@{\xy@-{}\expandafter\GRAPHar@\GRAPHeveryline@@}%
184 \else\ifx (\next
185 \DN@({\xy@({\spushid@{?NODE}\idfromc@{?NODE}}\xyFN@\GRAPH@}%
186 \else\ifx ,\next
187 \DN@,{\xy@,{\cfromid@{?NODE}}\xyFN@\GRAPH@}%
188 \else\ifx )\next
189 \DN@){\xy@){\cfromid@{?NODE}%
190  \tests@\z@{\idfroms@{?NODE}\z@ \spop@}{\xyerror@{) without (}{}}}%
191  \xyFN@\GRAPH@}%
192 % HACK: ONLY POP WHEN NONEMPTY...WHY EVER NONEMPTY?
193 \else\ifx \endgraph\next \DN@{\xy@@{\tests@\z@\spop@\sleave@\leave@}}%
194 \else\ifx \end\next \DN@{\xy@@{\tests@\z@\spop@\sleave@\leave@}}%
195 \else\ifx ~\next
196 \DN@~{\xy@@{\enter@\cfromthec@}\afterNODE{\leave@ \xyFN@\GRAPH@}!}%
197 \else \DN@{\afterNODE{\xyFN@\GRAPH@}}%
198 \fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
200 \xylet@\GRAPHsaved@PATHafterPOS=\PATHafterPOS
201 \xylet@\GRAPHsaved@afterar@@=\afterar@@
203 \xydef@\GRAPHar@{%
204 \let\PATHafterPOS=\afterNODE \let\afterar@@=\GRAPHafterar@ \ar}
206 \xydef@\GRAPHafterar@{%
207 \let\PATHafterPOS=\GRAPHsaved@PATHafterPOS
208 \let\afterar@@=\GRAPHsaved@afterar@@
209 \xy@@{\cfromid@{}}\xyFN@\GRAPH@}
211 \xylet@\afterNODE@@=\empty
213 \xydef@\afterNODE#1{\xy@@{\enter@\pfromthep@}%
214 \DN@##1{\def\afterNODE@@{\xy@@\leave@ \def\afterNODE@@{##1}#1}}%
215 \expandafter\next@\expandafter{\afterNODE@@}%
216 \xyFN@\NODE@}
218 \xylet@\theMOVE@@=\relax
220 \xydef@\NODE@{%

221 \ifx \space@\next \expandafter\DN@\space{\xyFN@\NODE@}%
222 \else\ifx [\next \DN@[##1]{\xy@{[##1]}{}%
223  \def\theMOVE@@{[##1]}\xyFN@\MOVE@##1]}%
224 \else\ifx "\next \DN@ "##1"{%
225  \xy@{"##1"}{\cfromid@{##1}}\def\theMOVE@@{"##1"}\xyFN@\NODE@i}%
226 \else\ifx ?\next \DN@ ?{%
227  \xy@?{\cfromid@{?NODE}}\def\theMOVE@@{?}\xyFN@\NODE@i}%
228 \else\ifx !\next \def\theMOVE@@{[]}\let\next@=\NODE@i
229 \else \testAND@\iffalse
230 \DN@##1{\xy@{}{\pfromc@ \advance\X@c\X@xbase \advance\Y@c\Y@xbase
231  \czeroEdge@}\jumpMOVE@ \xyFN@\NODE@i}%
232 \else\ifx \\\next
233 \DN@\\{\xy@\\{\pfromc@ \advance\X@c\X@xbase \advance\Y@c\Y@xbase
234  \R@c=\X@ybase \U@c=\Y@ybase \intersect@
235  \advance\X@c-\X@ybase \advance\Y@c-\Y@ybase
236  \czeroEdge@}\def\theMOVE@@{\\}\xyFN@\NODE@i}%
237 \else \xyerror@{Illegal <node>: \string`\meaning\next\string' unexpected}{}%
238 \fi\fi\fi\fi\fi\fi\fi \next@}
240 \xydef@\jumpMOVE@@{&}
241 \xydef@\jumpMOVE@{\let\theMOVE@@=\jumpMOVE@@}
243 \xydef@\MOVE@{\xy@@{\count@=\z@ \count@@=\z@}%
244 \ifx \space@\next \expandafter\DN@\space{\xyFN@\MOVE@}%
245 \else\ifcat A\noexpand\next \let\next@=\MOVE@letter
246 \else \let\next@=\MOVE@x \fi\fi \next@}
248 \xydef@\MOVE@letter{%
249 \ifx \space@\next \expandafter\DN@\space{\xyFN@\MOVE@letter}%
250 \else\ifx u\next \DN@ u{\xy@@{\advance\count@\@ne}\xyFN@\MOVE@letter}%
251 \else\ifx d\next \DN@ d{\xy@@{\advance\count@\m@ne}\xyFN@\MOVE@letter}%
252 \else\ifx l\next \DN@ l{\xy@@{\advance\count@@\m@ne}\xyFN@\MOVE@letter}%
253 \else\ifx r\next \DN@ r{\xy@@{\advance\count@@\@ne}\xyFN@\MOVE@letter}%
254 \else \let\next@=\MOVE@x \fi\fi\fi\fi\fi \next@}
256 \xydef@\MOVE@x{%[[
257 \ifx ]\next \DN@ ]{\MOVE@hop \xyFN@\NODE@i}%
258 \else\ifx (\next \DN@{\MOVE@hop \xyFN@\MOVE@place}%)
259 \else\ifx !\next \DN@{\MOVE@hop \xyFN@\MOVE@place}%
260 \else\ifx /\next \DN@{\MOVE@hop \xyFN@\MOVE@place}%
261 \else\addLT@\ifx\next \DN@{\MOVE@hop \xyFN@\MOVE@place}%
262 \else\addGT@\ifx\next \DN@{\MOVE@hop \xyFN@\MOVE@place}%
263 \else\addDASH@\ifx\next \addDASH@\DN@{\xyerror@{- not implemented yet}{}}%
264 \else \xyerror@{illegal <move>: \codeof\theMOVE@@}{}\let\next@=\NODE@i
265 \fi\fi\fi\fi\fi\fi\fi \next@}
267 \xydef@\MOVE@hop{\xy@@{\pfromc@ \czeroEdge@
268 \edef\next@{\the\count@@,\the\count@ @}\expandafter\vfromcartesian@@\next@
269 \advance\X@c-\X@origin \advance\Y@c-\Y@origin
270 \advance\X@c\X@p \advance\Y@c\Y@p}}
272 \xydef@\MOVE@place{\xy@@\no@@ \afterPLACE{\xyFN@\MOVE@}}
274 \xydef@\NODE@i{\let\next@=\NODE@x

364 CHAPTER 3. FEATURES

275 %

276 %\W@{NODE@i: next=\meaning\next}%

277 %

278 \ifx \space@\next \expandafter\DN@\space{\xyFN@\NODE@i}%
279 \else\addEQ@\ifx \next
280 \addEQ@\DN@"##1"{\xy@{="##1"}{\idfromc@{##1}}\xyFN@\NODE@i}%
281 \else\ifx !\next \DN@!{\xyFN@\NODE@escape}%
282 \else\ifx :\next
283 \else\addDASH@\ifx\next
284 \else\ifx (\next
285 \else\ifx ,\next
286 \else\ifx )\next
287 \else\ifx ~\next
288 \else\ifx [\next
289 \else\ifx "\next
290 \else\ifx ?\next

291 %

292 \else\ifx ^\next
293 \else\ifx _\next
294 \else\ifx |\next
295 \else\addLQ@\ifx\next
296 \else\addRQ@\ifx\next

297 %

298 \else \testAND@ \iffalse
299 \else\ifx \\\next

300 %

301 \else\ifx \endgraph\next
302 \else\ifx \end\next

303 %

304 \else \let\next@=\NODE@it
305 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
307 \xydef@\NODE@x{\xy@@{\idfromc@{}}\afterNODE@@}
309 \xydef@\NODE@it{\let\PATHlabelit@@=\NODEit@ \PATHit@}
311 {\xyuncatcodes \gdef\next{+}}
312 \xylet@\GRAPHnodemodifiers@@=\next
314 \xydef@\NODEit@#1{%
315 \DN@{#1}\ifx\next@\empty
316 \DN@{\expandafter\NODEit@i\expandafter{\GRAPHnodemodifiers@@}}%
317 \else \DN@{\NODEit@i{#1}}\fi \next@}
319 \def\NODEit@i#1#2{\xy@{*#1{#2}}{\drop@{#1}{#2}}%
320 \DN@{\addEQ@\ifx\next\else \xy@@{\idfromc@{#2}}\fi \NODE@i}%
321 \xyFN@\next@}

Notes 3.6a. A move is to establish a new current node. 3.6b. To draw something is simply to draw a line or the specified ⟨arrow⟩ from the current node to the specified target node. The target then becomes the current node. All the features of arrows as described in §3.3 can be used, in particular arrows can be labelled and segmented, but with the change that ⟨path-pos⟩ means ⟨node⟩ as explained in note §3.3e.

3.6c. To map over a list is simply to save the current node and then interpret the ⟨list⟩ with the following convention:

• Start each element of the list with the current node as saved and p as the previous list element, and

• let the ? ⟨node⟩ refer to the saved current node explicitly.

3.6d. The & and \\ special moves are included to make it simple to enter ‘matrix-like’ things as graphs – note that they will not be automatically aligned, however, for that you should use the !M escape.

& is the same as [r] and \\ is the same as [r]!{y+(0,-1)-(0,0)} which uses a kernel escape to moves to the first column in the next row (where the first column is on the y-axis of the current coordinate system).

Note: If you use the form *{… } for nodes then you don’t have to change them if you decide to use an XY-matrix.

3.6e. Typeset ⟨it⟩ and make it the current node. Also saves ⟨it⟩ for later reference using "⟨id⟩": if ⟨it⟩ is a simple letter, or digit, then just as "⟨it⟩"; if ⟨it⟩ is of the form {text} or *… {text} then as "text".

With the = addition it is possible to save explicitly in case several nodes have the same text or a node has a text that it is impractical to use for reference. In fact using the form ⟨it⟩="⟨id⟩" will only save the node as "⟨id⟩" and not as "⟨it⟩"! As a special convenience "" (thus the empty ⟨id⟩) always refers to the last completed node, so adding ="" after a node merely means it should not be saved under its proper name.

Exercise 3.12: How did the author typeset this?

[figure: A; A; A]

3.6f. Moving by a series of hops is simply moving in a grid as the sequence of dulr (for down/up/left/right) indicates. The grid is a standard cartesian coordinate system with 3pc unit unless the current base is redefined using []!{… } with an appropriate ⟨pos⟩ition containing : and :: as described in note 1.3d.

To Do: Describe the use of ⟨move⟩s with ⟨place⟩s in detail … in particular (1) ‘until perpendicular to … ’ and (2) ‘until intercepts with … ’ can be coded…

3.6g. This ‘escapes’ into the XY-pic kernel language and interprets the ⟨pos⟩ ⟨decor⟩. The current node is then set to the resulting c object and the grid from the resulting base.

The effect of the ⟨pos⟩ ⟨decor⟩ can be completely hidden from XY-graph by entering it as {\save ⟨pos⟩ ⟨decor⟩ \restore}.

430 \xydef@\NODE@escape{%
431 \ifx \space@\next \expandafter\DN@\space{\xyFN@\NODE@escape}%
432 \else\ifcat A\noexpand\next \DN@##1{\rungraphescape@{##1}}%
433 \else\ifcat !\noexpand\next \DN@##1{\rungraphescape@{##1}}%

434 \else\ifx \bgroup\next \DN@##1{\xy@{!{##1}}{}\POS##1\relax \xyFN@\NODE@i}%
435 \else\ifx ~\next \let\next@=\graphsetup@
436 \else \DN@{\xyerror@{Unknown graph <escape>}{}\xyFN@\NODE@i}%
437 \fi\fi\fi\fi\fi \next@}

3.6h. It is possible to insert a ⟨matrix⟩ in a graph provided the ‘matrix’ option described in §3.5 has been loaded: it overwrites the node with the result of \xymatrix⟨matrix⟩. Afterwards the graph grid is set as the top left ‘square’ of the matrix, i.e., with [d] and [r] adjusted as they work in the top left entry.

Bug: [dr] immediately after the matrix will work as expected, e.g., make the center of "2,2" the current node, but others might not, e.g., [rr] will not necessarily place the current node on top

   of "1,3".

455 \xydefcsname@{graph !M}#1#{\NODE@matrix{#1}}
457 \xydef@\NODE@matrix#1#2{\xyerror@{matrix feature not loaded}{}\xyFN@\GRAPH@}
459 \xydef@\NODE@matrix@#1#2{\xy@{!M#1{#2}}{}%
460 \def\everyentry@{\GRAPHeveryentry}%
461 \xymatrix#1{#2}%
462 \let\everyentry@=\empty \insertmatrixingraph@ \xyFN@\NODE@i}
464 \xydef@\GRAPHeveryentry{\def\:{\ar}\def\="##1"{\xy@@{\idfromc@{##1}}}}
466 \xywithoption{matrix}{\let\NODE@matrix=\NODE@matrix@}
468 \xydef@\insertmatrixingraph@{%
469 \xy@@{\enter@{\cfromthec@ \pfromthep@}%
470 \expandafter\let\expandafter\next@\csname Q@1,1\endcsname
471 \ifx\next@\relax\else
472 \next@ \swap@
473 \expandafter\let\expandafter\next@\csname Q@1,2\endcsname
474 \ifx\next@\relax\else \next@ \setbase@\X@p\Y@p\X@c\Y@c
475  \expandafter\let\expandafter\next@\csname Q@2,1\endcsname
476  \ifx\next@\relax\else
477  \next@ \setbase@@{-\X@c}{-\Y@c}\fi\fi\fi
478 \leave@}}

3.6i. It is possible to insert a ⟨polygon⟩ or an ⟨ellipse⟩ in a graph provided the poly option described in §3.7 or the arc option described in §3.9 has been loaded, respectively: it will have c as the current node, p as the previous one, and the the current base has the ⟨hop⟩s [r] and [u] as base vectors.

Note: lattices, knots, etc., can also be used but no special syntax is useful since the !{… } syntax is adequate.

495 \xydefcsname@{graph !P}#1#{\NODE@poly{#1}}
496 \xydef@\NODE@poly#1#2{\xyerror@{poly(gon) feature not loaded}{}\xyFN@\GRAPH@}
497 \xydef@\NODE@poly@#1#2{\xy@{!P#1{#2}}{}\xypoly@#1{#2}\xyFN@\NODE@i}
498 \xywithoption{poly}{\let\NODE@poly=\NODE@poly@}
500 \xydefcsname@{graph !E}#1#{\NODE@arc{#1}!}
501 \xydef@\NODE@arc#1#2{\xyerror@{(ellipse+)arc feature not loaded}{}%
502 \xyFN@\GRAPH@}
503 \xydef@\NODE@arc@#1#2{\xy@{!E#1{#2}}{}\ellipse#1{#2}\xyFN@\NODE@i}

504 \xywithoption{arc}{\let\NODE@arc=\NODE@arc@}

3.6j. This allows setting of some parameters of the graph: !~⟨setup⟩ should be one of the following:

!~:{ ⟨arrow⟩ }  include with every : arrow
!~-{ ⟨arrow⟩ }  include with every - line
!~*{ ⟨modifiers⟩ } include with every non-* node
!~⟨letter⟩{ ⟨graph⟩ } define new graph escape !⟨letter⟩

These are destructive: the previous value is lost; the default is established by the sequence !~:{} !~-{@{-}} !~*{+} making : create simple arrows, - plain lines, and formatting default nodes in math mode with the default objectmargin.

530 \xylet@\GRAPHeveryarrow@@=\empty
532 {\xyuncatcodes \gdef\next{@{-}}}
533 \xylet@\GRAPHeveryline@@=\next
535 \xydef@\graphsetup@~{\xyFN@\graphsetup@i}
537 \xydef@\graphsetup@i{%
538 \ifx :\next \DN@:##1{\def\GRAPHeveryarrow@@{##1}\xyFN@\NODE@i}%
539 \else\addDASH@\ifx\next
540 \addDASH@\DN@##1{\def\GRAPHeveryline@@{##1}\xyFN@\NODE@i}%
541 \else\ifx *\next \DN@*##1{\def\GRAPHnodemodifiers@@{##1}\xyFN@\NODE@i}%
542 \else\ifcat A\next \DN@##1##2{\newgraphescape{##1}{##2}\xyFN@\NODE@i}%
543 \else \DN@{\xyerror@{illegal graph setup \codeof\next@}{}\xyFN@\NODE@i}%
544 \fi\fi\fi\fi \next@}

The last possibility is also available as a command

                            \newgraphescape{⟨letter⟩}{⟨graph⟩}

that makes the specified escape generate the ⟨graph⟩ as a macro; with it it is possible to pass arguments to the ⟨graph⟩ using the standard TEX \def method: The declaration code

   \newgraphescape{i}#1#2{
    []!{+0="o#2"*=<10pt>{};p!#1**{},"o#2"
     -/4pt/*!E\cir<2pt>{}
     +0;p-/:a(-30)24pt/**\dir{-}="X2"
     ;p-/:a(-60)24pt/="X1"**\dir{-}
     ;?(.5),="i#2",
     p-/:a(-60)24pt/**\dir{-},
     "o#2"."i#2"."X1"."X2"}}

is (rather complicated kernel code) that makes the node escape !idn typeset an ‘inverter’ oriented with the d corner as the output with input named "in" and output named "on" such that the graph

   \xygraph{ []!iR1 ("i1"[l]x - "i1") - [r]z }

will typeset

[figure: x; z]

The \newgraphescape⟨letter⟩ declaration defines a macro with name \graph !⟨letter⟩. It is slightly complicated by the fact that we accept L^{A}TEX-style [n] arguments (when using L^{A}TEX, 368 CHAPTER 3. FEATURES

that is ◯_{¨⌣}). Thus an internal macro named \G!⟨letter⟩ is defined using the appropriate command definition primitve; this is in turn invoked by \graph !⟨letter⟩ after activating the ⟨graph⟩ parser.

598 \xydef@\newgraphescape#1{%
599 \expandafter\let\expandafter\next\csname graph !#1\endcsname
600 \ifx\next\relax\else \expandafter\let\csname G!#1\endcsname=\undefined
601 \xywarning@{Redefining graph <escape> !#1}\fi
602 \expandafter\gdef\csname graph !#1\endcsname{%
603 \expandafter\let\expandafter\next\csname G!#1\endcsname
604 \expandafter\xyFN@\expandafter\NODE@\next}%
605 \DN@{\newgraphescape@{#1}}\xyFN@\next@}
607 \xydef@\newgraphescape@#1{%
608 \ifx [\next %]
609 \ifx\newcommand\undefined \xyerror@{[n] only with LaTeX}%
610 \else
611  \def\nextiv@{\expandafter\newcommand\expandafter{\csname G!#1\endcsname}}\fi
612 \else \def\nextiv@{\expandafter\gdef\csname G!#1\endcsname}\fi \nextiv@}
614 \xydef@\rungraphescape@#1{%
615 \expandafter\let\expandafter\next\csname graph !#1\endcsname
616 \ifx\next\relax \xyerror@{Undefined graph <escape> !#1}\fi \next}

The final exercise illustrates much of the above. Exercise 3.13: Typeset

[figure: w; x_{1}; z; y; x_{2}]

End & log

662 \xyendinput
664 % $Log: xygraph.doc,v $
665 % Revision 3.7  1999/02/16 15:12:50  krisrose
666 % Interim release (Y&Y fonts now free).

667 %

668 % Revision 3.6  1998/03/06 01:28:05  krisrose
669 % Releasing (with Y&Y fonts).

670 %

671 % Revision 3.4  1997/05/18 01:14:25  krisrose
672 % Essential bugfixes.

673 %

674 % Revision 3.3  1996/12/19 03:31:56  krisrose
675 % Maintenance release

676 %

677 % Revision 3.2  1995/09/19  18:22:27  kris
678 % Bug fix release.

679 %

680 % Revision 3.1  1995/09/05  20:31:32  kris
681 % Releasing!

682 %

683 % Revision 3.0  1995/07/07  20:14:21  kris
684 % Major release w/new User's Guide!

685 %

686 % Revision 2.13  1995/07/04  15:11:17  kris
687 % Ready to release v3?

688 %

689 % Revision 2.12  1994/10/25  11:34:25  kris
690 % Interim release just before v3 [works with AMS-LaTeX 1.2]...

691 %

692 % Revision 2.11  1994/07/05  10:37:32  kris
693 % Third 3beta release [bug fixes].
694 % Experimental graph feature included (for ECCT-94 presentation).

695 %

696 % New for v3...

3.7 Polygon feature

Vers. 3.7 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This feature provides a means for specifying the locations of vertices for regular polygons, with any number (≥ 3) of sides. Polygons can be easily drawn and/or the vertex positions used to constuct complex graphics within an XY-picture. Many non-regular polygons can be specified by setting a non-square basis.

Header:

1 %% $Id: xypoly.doc,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %%
3 %% Xy-pic ``Polygon'' feature.
4 %% Copyright (c) 1994-1997 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this macro package; if not, write to the Free Software Foundation,

22 %% Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{poly}{Polygon feature}{\stripRCS$Revision: 3.7 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

Some of the effects use \ar so make sure the ‘arrow’ feature is loaded.

45 \xyrequire{arrow}\xycatcodes
51 \message{polygons,}

A polygon is most easily specified using …

\xypolygon⟨number⟩{} with ⟨number⟩ sides;
\xypolygon⟨number⟩{⟨tok⟩} ⟨tok⟩ at vertices;

\xypolygon⟨number⟩{⟨object⟩} with a general ⟨object⟩ at each vertex;

Here ⟨number⟩ is a sequence of digits, giving the number of sides. If used within an \xy… \endxy environment then the polygon will be centred on c, the current ⟨pos⟩. However an \xypolygon can be used outside such an environment, as “stand-alone” polygon; the whole picture must be specified within the \xypolygon command.

In either case the shape is obtained by spacing vertices equally around the “unit circle” with respect to the current basis. If this basis is non-square then the vertices will lie on an ellipse. Normally the polygon, with at most 12 vertices, is oriented so as to have a flat base when specified using a standard square basis. With more than 12 vertices the orientation is such that the line from the centre to the first vertex is horizontal, pointing to the right. Any other desired orientation can be obtained, with any number of vertices, by using the ~={… } as described below.

The general form for \xypolygon is …

\xypolygon⟨number⟩"⟨prefix⟩"{⟨switches⟩… }

where the "⟨prefix⟩" and ⟨switches⟩ are optional. Their uses will be described shortly.

A \xypolygon establishes positions for the vertices of a polygon. At the same time various things may be typeset, according to the specified ⟨switches⟩. An ⟨object⟩ may be dropped at each vertex, “spokes” drawn to the centre and successive vertices may be connected as the polygon’s “sides”. Labels and breaks can be specified along the spokes and sides.

Each vertex is automatically named: "1", "2", …, "⟨number⟩" with "0" as centre. When a ⟨prefix⟩ has been given, names "⟨prefix⟩0", …, "⟨prefix⟩⟨number⟩" are used instead. While the polygon is being constructed the macro \xypolynum expands to the number of sides, while \xypolynode expands to the number of each vertex, spoke and side at the time it is processed. This occurs in the following order: vertex 1, spoke 1, vertex 2, spoke 2, side 1, vertex 3, spoke 3, side 2, …, vertex n, spoke n, side n − 1, side n where the final side joins the last vertex to the first.

The macro \xypolyname holds the name of the polygon, which is ⟨prefix⟩ if supplied. In this case the value of \xypolynum is also stored as \⟨prefix⟩NUMSIDES, accessible outside the polygon.

As stated above, a polygon with up to 12 vertices is oriented so as to have a flat base, when drawn using a standard square basis. Its vertices are numbered in anti-clockwise order, commencing with the one at horizontal-right of centre, or the smallest angle above this (see example below). With more than 12 vertices then vertex "1" is located on the horizontal, extending to the right from centre (assuming a standard square basis). By providing a switch of the form ~={⟨angle⟩} then the vertex "1" will be located on the unit circle at ⟨angle⟩^{∘} anti-clockwise from “horizontal” — more correctly, from the X-direction in the basis to be used when setting the polygon, which may be established using a ~:{… } switch.

[figure: •; •; •; 1; 2; 3; 0; 1; 2; 3; 4; 5; 6; 0; 1; 2; 3; 4; 5; 6; 7; 8; 9]

Exercise 3.14: Give code to typeset these.

One important use of ⟨prefix⟩ is to allow the vertices of more than one polygon to be accessed subsequently within the same picture. Here are some examples of this, incorporating the ~:{… } switch to perform simple rescalings. Firstly the edges of a dodecahedron as a planar graph:

[figure]

\xy /l1.5pc/:,{\xypolygon5"A"{}},
{\xypolygon5"B"{~:{(1.875,0):}~>{}}},
{\xypolygon5"C"{~:{(-2.95,0):}~>{}}},
{\xypolygon5"D"{~:{(-3.75,0):}}},
{"A1"\PATH~={**@{-}}'"B1"'"C4"'"B2"},
{"A2"\PATH~={**@{-}}'"B2"'"C5"'"B3"},
{"A3"\PATH~={**@{-}}'"B3"'"C1"'"B4"},
{"A4"\PATH~={**@{-}}'"B4"'"C2"'"B5"},
{"A5"\PATH~={**@{-}}'"B5"'"C3"'"B1"},
"C1";"D1"**@{-},"C2";"D2"**@{-},
"C3";"D3"**@{-},"C4";"D4"**@{-},
"C5";"D5"**@{-} \endxy

Next a hexagonal pyramid, a rectangular box and an octahedral crystal specified as a triangular antiprism. Notice how the ~:{… } switch is used to create non-square bases, allowing the illusion of 3D-perspective in the resulting diagrams:

[figure]

\xy/r2pc/: ="A", +(.2,1.5)="B","A",
{\xypolygon6{~:{(1,-.1):(0,.33)::}

 ~<>{;"B"**@{-}}}}\endxy
\quad \xy /r2pc/:
{\xypolygon4"A"{~:{(0,.7)::}}},+(.7,1.1),
{\xypolygon4"B"{~:{(.8,0):(0,.75)::}}},
"A1";"B1"**@{.},"A2";"B2"**@{.},
"A3";"B3"**@{.},"A4";"B4"**@{.}
\endxy\quad \xy /r2pc/:
{\xypolygon3"A"{~:{(0,.7)::}}},+(.7,1.1),
{\xypolygon3"B"{~:{(-.85,0):(-.15,.8)::}}}
,"A1"\PATH~={**@{.}}'"B2"'"A3"'"B1"
'"A2"'"B3"'"A1" \endxy

\xypolynode simply reads the value of a counter called \xypolynode@. It is set initially at -1, to indicate no polygon yet. This is used to establish the default naming in case polygons are nested.

211 \xynew@{count}\xypolynode@\xypolynode@=\m@ne
212 \xydef@\xypolynode{\the\xypolynode@}
214 \xydef@\xypolyNUMSIDES@{}
215 \xydef@\xypolynum{\xypolyNUMSIDES@}

To allow recursion the values of \xypolyNUMSIDES@ and \xypolynode@ are saved upon entering an \xypolygon, to be restored at the end.

222 \xydef@\xypolygon{\xypoly@}%
224 \xydef@\xypoly@{%
225 \if\inxy@
226 \if\inxypoly@
227  \edef\next@{\noexpand\xy@@{\noexpand\nter@{\xypolynode@=\the\xypolynode@
228  \noexpand\def\noexpand\xypolyNUMSIDES@{\xypolyNUMSIDES@}}}}%
229 \else
230  \DN@{\xy@@{\def\inxypoly@{TT}%
231  \nter@{\def\inxypoly@{TF}\xypolynode@=\m@ne}}}%
232 \fi
233 \else
234 \if\inxypoly@
235  \edef\next@{\noexpand\xy
236  \noexpand\xy@@{\noexpand\nter@{\xypolyside=\the\xypolyside
237  \noexpand\def\noexpand\xypolyNUMSIDES@{\xypolyNUMSIDES@}\endxy}}}%
238 \else
239  \DN@{\xy \xy@@{\def\inxypoly@{TT}%
240  \nter@{\def\inxypoly@{TF}\xypolynode@=\m@ne \endxy}}}%
241 \fi
242 \fi
243 \next@ \count@=\z@ \xyFN@\xypoly@n}
245 \xydef@\inxypoly@{TF}%
246 \xydef@\xypoly@x{\xy@@{\leave@\leave@}}

Read the number of vertices by parsing digits.

252 \xydef@\xypoly@n{%
253 \DN@##1{\multiply\count@10\relax \advance\count@##1\relax \xyFN@\xypoly@n}%
254 \ifx \space@\next

255 \ifnum\count@>\z@ \expandafter\DN@\space@{\xyFN@\xypoly@i}%
256 \else \expandafter\DN@\space@{\xyFN@\xypoly@n}\fi
257 \else\ifx 0\next \else\ifx 1\next \else\ifx 2\next \else\ifx 3\next
258 \else\ifx 4\next \else\ifx 5\next \else\ifx 6\next \else\ifx 7\next
259 \else\ifx 8\next \else\ifx 9\next
260 \else \let\next@=\xypoly@i \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
262 \xydef@\xypoly@i{\edef\xypolyNUMSIDES@{\the\count@}\xyFN@\xygetpolyprefix@}

Next we check whether a prefix has been supplied for creating the vertex names. If so it is stored as \xypolyPREFIX@, which otherwise expands to empty. The number of sides is also stored using the prefix.

270 \xydef@\xypolyPREFIX@{}%
271 \xydef@\xypolyPREFIX@@{}%
272 \xydef@\xypolyname{\xypolyPREFIX@}%
274 \xydef@\xygetpolyprefix@{%
275 \ifx\next"\DN@"##1"{\def\xypolyPREFIX@@{##1}\expandafter
276 \edef\csname\xypolyPREFIX@@ NUMSIDES\endcsname{\xypolyNUMSIDES@}%
277 \xypolyprefix@@ }%
278 \else
279 \ifnum\xypolynode@<\z@\def\xypolyPREFIX@@{}%
280 \else
281  \edef\xypolyPREFIX@@{\xypolyPREFIX@\the\xypolynode@,}%
282 \fi \DN@{\xypolyprefix@@}%
283 \fi \next@ }
285 \xydef@\xypolyprefix@@{%
286 \expandafter\toks@\expandafter{\addEQ@\POS"}%
287 \expandafter\addtotoks@\expandafter{\xypolyPREFIX@@0"\relax}%
288 \the\toks@
289 \ifnum\xypolynode@<\z@
290 \expandafter\def\expandafter\xypolyPREFIX@\expandafter{\xypolyPREFIX@@}%
291 \xy@@{\enter@{\xypolynode@=\the\xypolynode@
292  \noexpand\def\noexpand\xypolyPREFIX@{\xypolyPREFIX@}}\xypolynode@=\z@ }%
293 \else
294 \xy@@{\enter@{\xypolynode@=\the\xypolynode@
295  \noexpand\def\noexpand\xypolyPREFIX@{\xypolyPREFIX@}}\xypolynode@=\z@ }%
296 \expandafter\def\expandafter\xypolyPREFIX@\expandafter{\xypolyPREFIX@@}%
297 \fi
298 \xypoly@@i }

Currently any tokens remaining before the opening brace are discarded, with an accompanying message.

305 \xydef@\xypoly@@i#1#{\begingroup
306 \DN@{#1}\ifx\next@\empty\else
307 \xywarning@{discarding unused tokens: #1}\fi \xypoly@@ }

Next it is time to analyse the braced information, e.g. to set switches and/or adjust the scale. If this information is empty {} then the default values are used.

316 \xydef@\xypoly@@#1{\xypolydefaults@
317 \DN@{#1}\ifx\next@\empty\DN@{\xypoly@@@}%

318 \else \DN@{\xyFN@\xypolyparams@#1~!}\fi \next@}
320 \xydef@\xypolydefaults@{\def\xypolySCALE@{}%
321 \def\xypolySPOKES@{{}}\def\xypostSPOKES@{}\let\xypreSPOKES@\relax
322 \def\xypolySIDES@{{-}}\def\xypostSIDES@{}\let\xypreSIDES@\relax
323 \def\xypolyVERTEX@{}\def\xypolyALIGN@{}}

Vertex object: Unless the first character is ~, signifying a “switch”, then the whole of the braced material is taken as specifying the ⟨object⟩ for each vertex. It will be typeset with a circular edge using \drop[o]..., except when there is just a single token ⟨tok⟩. In this case it is dropped as \drop=0{⟨tok⟩}, having zero size. An object can also be dropped at each vertex using the switch ~*{… }, in which case it will be circular, with the current objectmargin applied.

The next example illustrates three different ways of specifying a \circ at the vertices.

[figure: ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘; ∘]

\xy/r2pc/: {\xypolygon12{\circ}},
+/r5pc/,{\xypolygon10{~<{-}~>{}{\circ}}},
+/r5pc/,{\xypolygon8{~*{\circ}~<=}}\endxy

352 {\xyuncatcodes \gdef\next{*=0}}
353 \xylet@\xypolynullvertex@=\next
355 {\xyuncatcodes \gdef\next{*[o]}}
356 \xylet@\xypolyvertex@=\next
358 {\xyuncatcodes \gdef\next{*+[o]}}
359 \xylet@\xypolywidevertex@=\next
361 \xydef@\xypolyparams@{%
362 \ifx\space@\next \expandafter\DN@\space{\xyFN@\xypolyparams@}%
363 \else\ifx\next~\DN@~{\xyFN@\xypolywhich@}%
364 \else\ifx\next\bgroup\DN@##1~!{%
365 %  \ifx\empty\xypolyVERTEX@\def\xypolyVERTEX@{*[o]{##1}}%
366 \ifx\empty\xypolyVERTEX@\expandafter
367  \def\expandafter\xypolyVERTEX@\expandafter{\xypolyvertex@{##1}}%
368 \else\xypolyVERTEXerror@{##1}\fi \xypoly@@@}%
369 \else\DN@##1~!{\DN@{##1}\ifx\next@\empty\else
370  \ifx\empty\xypolyVERTEX@\def\xypolyVERTEX@{*##1}%
371 %    \checkpolytok@\xypolyVERTEX@{*=0}##1@@!\relax
372  \expandafter\checkpolytok@\expandafter\xypolyVERTEX@
373  \expandafter{\xypolynullvertex@}##1@@!\relax
374  \else\xypolyVERTEXerror@{##1}\fi\fi \xypoly@@@}%
375 \fi\fi\fi \next@ }
377 \xydef@\xypolyVERTEXerror@#1{\xywarning@{%
378 vertex already specified, discarding unused tokens:#1}}

Switches The allowable switches are given in the following table:

~:{… }  useful for rescaling.
~*{⟨object⟩} ⟨object⟩ at each vertex.
~={⟨angle⟩} align first vertex.
~<{… }  directional for “spokes”;
~<<{⟨arrow⟩} use ⟨arrow⟩ for spokes;
~<>{… }  labels & breaks on spokes.
~>{… }  directional for “sides”;
~><{⟨arrow⟩} use ⟨arrow⟩ for sides;
~>>{… }  labels & breaks on sides.

Using ~<<{⟨arrow⟩} or ~><{⟨arrow⟩} is most appropriate when arrowheads are required on the sides or spokes, or when labels/breaks are required. Here ⟨arrow⟩ is as in figure 3.2, so it can be used simply to specify the style of directional to be used. Thus ~<<{} sets each spoke as a default arrow, pointing outwards from the centre; ~<<{@{-}} suppresses the arrowhead, while ~><{@{}} uses an empty arrow along the sides. Labels and breaks are specified with ~<>{… } and ~>>{… }, where the {… } use the notation for a ⟨label⟩, as in figure 3.1.

When no tips or breaks are required then the switches ~<{… } and ~>{… } are somewhat faster, since less processing is needed. Labels can still be specified with ~<>{… } and ~>>{… }, but now using the kernel’s ⟨place⟩ notation of figure 1.1. In fact any kernel code can be included using these switches. With ~<> the current p and c are the centre and vertex respectively, while for ~>> they are the current vertex and the previous vertex. (The connection from vertex "⟨number⟩" to vertex "1" is done last.) The pyramid above is an example of how this can be used. Both ~<{… } and ~<<{⟨arrow⟩} can be specified together, but only the last will actually be used; similarly for ~>{… } and ~><{⟨arrow⟩}.

[figure: A; B; α_{1}; C; α_{2}; D; α_{3}; E; α_{4}; F; α_{5}; G; α_{6}; α_{7}]

\def\alphanum{\ifcase\xypolynode\or A
\or B\or C\or D\or E\or F\or G\or H\fi}
\xy/r3pc/: {\xypolygon3{~={40}}},
{\xypolygon4{~={40}~>{{--}}}},
{\xypolygon5{~={40}}},
{\xypolygon6{~={40}~>{{--}}}},
{\xypolygon11{~={40}}},
{\xypolygon50{~={40}~>.}}, +/r8pc/,
{\xypolygon7{~<<{@{-}}~><{}
 ~<>{|*@{x}}~*{\alphanum}
 ~>>{_{\alpha_\xypolynode^{}}}}}
\endxy

Use of the ~={… } switch was described earlier. When using the ~:{… } more can be done than just setting the base. In fact any kernel code can be supplied here. It is processed prior to any other part of the polygon. The graphics state has c at the centre of the polygon, p at the origin of coordinates within the picture and has basis unchanged from what has previously been established. The current point c will be reset to the centre following any code interpreted using this switch.

Note that ~! was appended by \xypoly@@, in order to indicate the end of the braced tokens. The

macro \xypolywhich@ is the main parser, with \xypoly@SPOKES@ and \xypoly@SIDES@ handling the

subcases for ~< and ~>.

463 \xydef@\xypolywhich@{%
464  \ifx\next!\DN@!{\xypoly@@@}%
465 \else \addLT@\ifx\next \addLT@\DN@{\xyFN@\xypoly@SPOKES@}%
466 \else \addGT@\ifx\next \addGT@\DN@{\xyFN@\xypoly@SIDES@}%
467 \else \addEQ@\ifx\next \addEQ@\DN@##1{%
468 \def\xypolyALIGN@{##1}\xyFN@\xypolyparams@ }%
469 \else \ifx :\next \DN@:##1{%
470 \def\xypolySCALE@{##1}\xyFN@\xypolyparams@ }%
471 % \else\ifx\next*\DN@*##1{\def\xypolyVERTEX@{*+[o]{##1}}\xyFN@\xypolyparams@}%
472 \else\ifx\next*\DN@*##1{\expandafter
473  \def\expandafter\xypolyVERTEX@\expandafter{\xypolywidevertex@{##1}}%
474 \xyFN@\xypolyparams@}%
475 \fi\fi\fi\fi\fi\fi \next@ }
477 \xydef@\xypoly@SPOKES@{%
478  \addLT@\ifx\next \addLT@\DN@##1{%
479 \def\xypreSPOKES@{##1}\def\xypolySPOKES@{}\xyFN@\xypolyparams@ }%
480 \else \addGT@\ifx\next \addGT@\DN@##1{%
481 \def\xypostSPOKES@{##1}\xyFN@\xypolyparams@ }%
482 \else \ifx\next\bgroup \DN@##1{%
483 \def\xypolySPOKES@{##1}\let\xypreSPOKES@\relax
484 \checkpolytok@\xypolySPOKES@{}##1@@!{\xyFN@\xypolyparams@}}%
485 \else \DN@##1{%
486 \let\xypreSPOKES@\relax \def\xypolySPOKES@{{##1}}\xyFN@\xypolyparams@}%
487 \fi\fi\fi \next@ }
489 \xydef@\xypoly@SIDES@{%
490  \addLT@\ifx\next \addLT@\DN@##1{%
491 \def\xypreSIDES@{##1}\def\xypolySIDES@{}\xyFN@\xypolyparams@ }%
492 \else \addGT@\ifx\next \addGT@\DN@ ##1{%
493 \def\xypostSIDES@{##1}\xyFN@\xypolyparams@ }%
494 \else \ifx\next\bgroup \DN@##1{%
495 \def\xypolySIDES@{##1}\let\xypreSIDES@\relax
496 \checkpolytok@\xypolySIDES@{}##1@@!{\xyFN@\xypolyparams@}}%
497 \else \DN@##1{%
498 \let\xypreSIDES@\relax \def\xypolySIDES@{{##1}}\xyFN@\xypolyparams@}%
499 \fi\fi\fi \next@ }

A further simplification exists for sides and spokes without ⟨arrow⟩s. If ⟨tok⟩ is a single character then ~>⟨tok⟩, ~>{⟨tok⟩}, ~>{{⟨tok⟩}} all specify the directional \dir{⟨tok⟩}; similarly with the ~< switch. On the other hand, compound directionals require all the braces, e.g. ~>{{--}} and ~>{2{.}}.

This is achieved with the macro \checkpolytok@#1#2#3#4@!#5 which handles the bare ⟨tok⟩ case by adding braces around ⟨tok⟩ which has been passed as #3, preceeding it with #2. This is then \def’d to the control-sequence name passed as #1. Finally continue with the command passed as #5.

519 \xydef@\checkpolytok@#1#2#3#4@!#5{\DNii@{#1}\DN@{#4}%
520 \ifx\next@\empty\expandafter\def\nextii@{{}}%

521 \else\ifx#4@\expandafter\def\nextii@{#2{#3}}\fi\fi #5}

After all switches have been processed, remaining tokens are used to specify the ⟨object⟩ for each vertex. Such tokens will be used directly after a \drop, so can include object ⟨modifier⟩s as in figure 1.5. If an ⟨object⟩ has already been specified, using the ~* switch, then the following message will be written to the TEX log:

        Xy-pic Warning:  vertex already specified, discarding unused tokens:

with tokens at the end indicating what remains unprocessed. Similarly extra tokens before the {… } generate a message:

                     Xy-pic Warning: discarding unused tokens:

Nested Polygons When \xypolygon is specified within either a ~<>{… } or ~>>{… } switch for another polygon, then the inner polygon inherits a name which incorporates also the number of the part on which it occurs, as given by \xypolynode. This name is accessed using \xypolyname. In the following example the inner polygon is placed using ~<> in order to easily adjust its orientation to the outward direction of the spokes.

[figure: 1; 1, 1; 1, 2; 1, 3; 1, 4; 2; 2, 1; 2, 2; 2, 3; 2, 4; 3; 3, 1; 3, 2; 3, 3; 3, 4; 4; 4, 1; 4, 2; 4, 3; 4, 4]

\xypolygon4{~:{/r5pc/:}
 ~<>{*\frm<8pt>{o}\xypolygon4{~:{/-2pc/:}
   ~*{\xypolyname\xypolynode}}}
 [o]=<5pc>{\xypolynode}}

Notice how nested polygons inherit names "1,1", "1,2", …, "4,1", …, "4,4" for their vertices. If a ⟨prefix⟩ is supplied at the outermost level then the names become: "⟨prefix⟩i, j". Specifying a ⟨prefix⟩ for the inner polygon overrides this naming scheme. The same names may then be repeated for each of the inner polygons, allowing access afterwards only to the last—possibly useful as a memory saving feature when the vertices are not required subsequently.

Four levels of nesting gives a quite acceptable “Sierpinski gasket”. The innermost triangle is provided by \blacktriangle from the AMS symbol font msam5, at 5-point size. Further levels can be achieved using the PostScript backend, otherwise line segments become too small to be rendered using XY-fonts.

[figure: ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲; ▲]

\font\msamv=msam5 at 5pt
\def\blacktriangle{{\msamv\char'116}}
\def\objectstyle{\scriptscriptstyle}
\xypolygon3{~:{/r5.2pc/:}
 ~>{}~<>{?\xypolygon3"a"{~:{(.5,0):}
 ~>{}~<>{?\xypolygon3"b"{~:{(.5,0):}
 ~>{}~<>{?\xypolygon3"c"{~:{(.5,0):}
 ~>{}~<>{?\xypolygon3"d"{~:{(.5,0):}
~<>{?*!/d.5pt/=0\hbox{\blacktriangle}}
}} }} }} }} }

Note the use of naming in this example; when processing this manual it saves 13,000+ words of main memory and 10,000+ string characters as well as 122 strings and 319 multi-letter control sequences.

661 \xydef@\xytrigerror@#1#2{\string#1 only works from 0 to 12}
663 \xydef@\cosPIon#1{\ifcase#1 1\or-1\or0\or.5\or\halfroottwo\or
664 .809017\or\halfrootthree\or.900969\or.92388\or.939693\or.951057\or
665 .959493\or.965926\else1\xytrigerror@\cosPIon{#1}\fi}
666 \xydef@\sinPIon#1{\ifcase#1 0\or0\or1\or\halfrootthree\or\halfroottwo\or
667 .587785\or.5\or.433884\or.382683\or.34202\or.309017\or
668 .281733\or.258819\else0\xytrigerror@\sinPIon{#1}\fi}
670 \xydef@\cosTwoPIon#1{\ifcase#1 1\or1\or-1\or-\cosPIon3\or\cosPIon2\or
671 \sinPIon{10}\or\cosPIon3\or.62349\or\cosPIon4\or
672 .766044\or\cosPIon5\or.841254\or\cosPIon6%
673 \else1\xytrigerror@\cosTwoPIon{#1}\fi}
674 \xydef@\sinTwoPIon#1{\ifcase#1 0\or0\or0\or-\sinPIon3\or\sinPIon2\or
675 \cosPIon{10}\or\sinPIon3\or.781831\or\sinPIon4\or
676 .642788\or\sinPIon5\or.540641\or\sinPIon6%
677 \else0\xytrigerror@\sinTwoPIon{#1}\fi}
679 \xydef@\cosThreePIon#1{\ifcase#1 1\or-1\or0\or-1\or-\cosPIon4\or
680 -\cosPIon5\or\cosPIon2\or.222521\or\sinPIon8\or\cosPIon3\or
681 \sinTwoPIon5\or.654861\or\cosPIon4%
682 \else1\xytrigerror@\cosThreePIon{#1}\fi}
683 \xydef@\sinThreePIon#1{\ifcase#1 0\or0\or1\or0\or\sinPIon4\or
684 \sinTwoPIon5\or\sinPIon2\or.974928\or\cosPIon8\or\sinPIon3\or
685 \cosTwoPIon5\or.75575\or\sinPIon4%
686 \else0\xytrigerror@\sinThreePIon{#1}\fi}
688 \xydef@\cosFourPIon#1{\ifcase#1 1\or1\or1\or-\cosPIon3\or-1\or-\cosPIon5\or
689 \cosTwoPIon3\or-\cosThreePIon7\or0\or.173648\or\cosTwoPIon5\or
690 .415415\or\cosPIon3%
691 \else1\xytrigerror@\cosFourPIon{#1}\fi}

692 \xydef@\sinFourPIon#1{\ifcase#1 0\or0\or0\or-\sinPIon3\or0\or\sinPIon5\or
693 \sinTwoPIon3\or\sinThreePIon7\or1\or.984808\or\sinTwoPIon5\or
694 .909632\or\sinPIon3%
695 \else0\xytrigerror@\sinFourPIon{#1}\fi}
697 \xydef@\cosFivePIon#1{\ifcase#1 1\or-1\or0\or\cosPIon3\or-\cosPIon4\or
698 -1\or-\cosPIon6\or-\cosTwoPIon7\or-\cosThreePIon8\or-\cosFourPIon9\or
699 0\or.142315\or\sinPIon{12}%
700 \else1\xytrigerror@\cosFivePIon{#1}\fi}
701 \xydef@\sinFivePIon#1{\ifcase#1 0\or0\or1\or-\sinPIon3\or-\sinPIon4\or
702 0\or\sinPIon6\or\sinTwoPIon7\or\sinThreePIon8\or\sinFourPIon9\or1\or
703 .989821\or\cosPIon{12}%
704 \else0\xytrigerror@\sinFivePIon{#1}\fi}

Coordinates for the vertices are read from trigonometry tables using control sequences

             \cosPIonn  \sinPIonn
             \cosTwoPIonn \sinTwoPIonn
             \cosThreePIonn \sinThreePIonn
             \cosFourPIonn \sinFourPIonn
             \cosFivePIonn \sinFivePIonn

which expand to the values of cos \frac{π}{n}, sin \frac{π}{n}, cos \frac{2π}{n}, …, sin \frac{5π}{n} and are also available for other uses. The parameter n must be a non-negative integer up to 12. The complete table is in figure 3.6.

Specific Polygons: All the information from the switches is passed as 8 separate parameters to a macro appropriate to the number of sides. The parameters have the following uses, and are set as shown:

#1 pre-arrow: set by ~<<{...} else ;
#2 vertex ⟨object⟩, set by ~*{...}
#3 prefix for naming
#4 post-vertex: empty with \ars else **@{...}

                        where {...} is set by ~<{...}

#5 post-arrow/vertex: set by ~<>{...}
#6 pre-edge/arrow, set by ~><{...}
#7 post-edge: empty with \ars else **@{...}

                        where {...} is set by ~>{...}

#8 post-arrow/edge, set by ~>>{...}

The organisation of this information is done by \xyPolygon@@@#1 which takes as a single parameter a macro appropriate to the number of sides, supplied by \xypoly@@@.

751 \xydef@\xypoly@@@{\count@=\xypolyNUMSIDES@\relax
752 \ifx\xypolyALIGN@\empty
753 \ifnum\count@<\thr@@\relax\DN@{\xypolytoosmall@{\the\count@}}%
754 \else \advance\count@-\thr@@
755  \ifcase\count@ \DN@{\xyPolygon@@@\xytriangle@@}%
756  \or \DN@{\xyPolygon@@@\xysquare@@}%
757  \or \DN@{\xyPolygon@@@\xypentagon@@}%
758  \or \DN@{\xyPolygon@@@\xyhexagon@@}%

759  \or \DN@{\xyPolygon@@@\xyheptagon@@}%
760  \or \DN@{\xyPolygon@@@\xyoctagon@@}%
761  \or \DN@{\xyPolygon@@@\xynonagon@@}%
762  \or \DN@{\xyPolygon@@@\xydecagon@@}%
763  \or \DN@{\xyPolygon@@@\xyundecagon@@}%
764  \or \DN@{\xyPolygon@@@\xydodecagon@@}%
765  \else \DN@{\xylargePolygon@{0}{\xypolyNUMSIDES@}}%
766 \fi\fi
767 \else
768 \DN@{\xylargePolygon@{\xypolyALIGN@}{\xypolyNUMSIDES@}}%
769 \fi \next@ \xypoly@@@x}
771 \xydef@\xypoly@@@x{\restore\xypoly@x}
773 \xydef@\xypolytoosmall@#1{\xyerror@{#1 sides is too few for a polygon}}

Here is \xyPolygon@@@. It constructs a list of tokens to be interpreted, after having closed the grouping that was current while parsing. It starts by setting the value of \xypolyNUMSIDES@, then a \save before adjusting the scale according to the value of \xypolySCALE@.

784 \xydef@\xyPolygon@@@#1{%
785 \toks@={\def\xypolyNUMSIDES@}%
786 \expandafter\addtotoks@\expandafter{\expandafter{\xypolyNUMSIDES@}\save}%

787 %

788 \ifx\empty\xypolySCALE@ \addtotoks@{\POS"}%
789 \else \addtotoks@{\POS;0;}%
790 \expandafter\addtotoks@\expandafter{\xypolySCALE@\relax\POS"}%
791 \fi
792 \expandafter\addtotoks@\expandafter{\xypolyPREFIX@0"\relax}%

793 %

794 \ifx\xypreSPOKES@\relax
795 \addtotoks@{#1{;}}%
796 \expandafter\addtotoks@\expandafter{\expandafter{\xypolyVERTEX@}}%
797 \expandafter\addtotoks@\expandafter{\expandafter{\xypolyPREFIX@}}%
798 \DN@##1\next@{\def\tmp@{**\dir##1}}%
799  \expandafter\next@\expandafter{\xypolySPOKES@}\next@
800  \expandafter\addtotoks@\expandafter{\expandafter{\tmp@}}%
801 \else
802 \expandafter\DN@\expandafter{\expandafter\ar\xypreSPOKES@}%
803 \addtotoks@{#1}%
804 \expandafter\addtotoks@\expandafter{\expandafter{\next@}}%
805 \expandafter\addtotoks@\expandafter{\expandafter{\xypolyVERTEX@}}%
806 \expandafter\addtotoks@\expandafter{\expandafter{\xypolyPREFIX@}{}}%
807 \fi
808 \expandafter\addtotoks@\expandafter{\expandafter{\xypostSPOKES@}}%

809 %

810 \ifx\xypreSIDES@\relax
811 \addtotoks@{{;}}%
812 \DN@##1\next@{\def\tmp@{**\dir##1}}%
813  \expandafter\next@\expandafter{\xypolySIDES@}\next@
814  \expandafter\addtotoks@\expandafter{\expandafter{\tmp@}}%
815 \else

816 \expandafter\DN@\expandafter{\expandafter\ar\xypreSIDES@}%
817 \expandafter\addtotoks@\expandafter{\expandafter{\next@}{}}%
818 \fi
819 \expandafter\addtotoks@\expandafter{\expandafter{\xypostSIDES@}}%
820 \ifx\xypolyALIGN@\empty
821 \ifnum\xypolyNUMSIDES@>12\addtotoks@{{0}}\fi
822 \else
823 \expandafter\addtotoks@\expandafter{\expandafter{\xypolyALIGN@}}%
824 \fi
825 \expandafter\DN@\expandafter{\expandafter\endgroup\the\toks@ }%
826 \next@}

Note how \endgroup closes the grouping. All the information for the layout of the polygon is contained in \xypolyNUMSIDES@ and the specific polygon macro contained in the final \next@.

Here is where the polygons are defined, individually.

839 \xydef@\xytriangle@@#1#2#3#4#5#6#7#8{%
840 \xy@@{\xypolynode@=\@ne}%
841 \POS#1"#30"+(0,1)#2="#31"#4#5\relax
842 \xy@@{\advance\xypolynode@\@ne}%
843 \POS"#30"#1"#30"+(-\cosPIon6, -.5)#2="#32"#4#5\relax
844 \xy@@{\advance\xypolynode@\m@ne}%
845 \POS"#31"#6"#32"#7#8\relax
846 \xy@@{\advance\xypolynode@\tw@}%
847 \POS"#30"#1"#30"+(\cosPIon6,-.5)#2="#33"#4#5\relax
848 \xy@@{\advance\xypolynode@\m@ne}%
849 \POS"#32"#6"#33"#7#8\relax
850 \xy@@{\advance\xypolynode@\@ne}%
851 \POS"#33"#6"#31"#7#8\relax }
853 \xydef@\xysquare@@#1#2#3#4#5#6#7#8{%
854 \xy@@{\xypolynode@=\@ne}%
855 \POS#1"#30"+(\halfroottwo,\halfroottwo)#2="#31"#4#5\relax
856 \xy@@{\advance\xypolynode@\@ne}%
857 \POS"#30"#1"#30"+(-\halfroottwo,\halfroottwo)#2="#32"#4#5\relax
858 \xy@@{\advance\xypolynode@\m@ne}%
859 \POS"#31"#6"#32"#7#8\relax
860 \xy@@{\advance\xypolynode@\tw@}%
861 \POS"#30"#1"#30"-(\halfroottwo,\halfroottwo)#2="#33"#4#5\relax
862 \xy@@{\advance\xypolynode@\m@ne}%
863 \POS"#32"#6"#33"#7#8\relax
864 \xy@@{\advance\xypolynode@\tw@}%
865 \POS"#30"#1"#30"-(-\halfroottwo,\halfroottwo)#2="#34"#4#5\relax
866 \xy@@{\advance\xypolynode@\m@ne}%
867 \POS"#33"#6"#34"#7#8\relax
868 \xy@@{\advance\xypolynode@\@ne}%
869 \POS"#34"#6"#31"#7#8\relax }
871 \xydef@\xypentagon@@#1#2#3#4#5#6#7#8{%
872 \xy@@{\xypolynode@=\@ne}%
873 \POS#1"#30"+(\cosPIon{10},\sinPIon{10})#2="#31"#4#5\relax
874 \xy@@{\advance\xypolynode@\@ne}%

875 \POS"#30"#1"#30"+(0,1)#2="#32"#4#5\relax
876 \xy@@{\advance\xypolynode@\m@ne}%
877 \POS"#31"#6"#32"#7#8\relax
878 \xy@@{\advance\xypolynode@\tw@}%
879 \POS"#30"#1"#30"+(-\cosPIon{10},\sinPIon{10})#2="#33"#4#5\relax
880 \xy@@{\advance\xypolynode@\m@ne}%
881 \POS"#32"#6"#33"#7#8\relax
882 \xy@@{\advance\xypolynode@\tw@}%
883 \POS"#30"#1"#30"-(\sinPIon5,\cosPIon5)#2="#34"#4#5\relax
884 \xy@@{\advance\xypolynode@\m@ne}%
885 \POS"#33"#6"#34"#7#8\relax
886 \xy@@{\advance\xypolynode@\tw@}%
887 \POS"#30"#1"#30"+(\sinPIon5,-\cosPIon5)#2="#35"#4#5\relax
888 \xy@@{\advance\xypolynode@\m@ne}%
889 \POS"#34"#6"#35"#7#8\relax
890 \xy@@{\advance\xypolynode@\@ne}%
891 \POS"#35"#6"#31"#7#8\relax }
893 \xydef@\xyhexagon@@#1#2#3#4#5#6#7#8{%
894 \xy@@{\xypolynode@=\@ne}%
895 \POS#1"#30"+(1,0)#2="#31"#4#5\relax
896 \xy@@{\advance\xypolynode@\@ne}%
897 \POS"#30"#1"#30"+(.5,\halfrootthree)#2="#32"#4#5\relax
898 \xy@@{\advance\xypolynode@\m@ne}%
899 \POS"#31"#6"#32"#7#8\relax
900 \xy@@{\advance\xypolynode@\tw@}%
901 \POS"#30"#1"#30"+(-.5,\halfrootthree)#2="#33"#4#5\relax
902 \xy@@{\advance\xypolynode@\m@ne}%
903 \POS"#32"#6"#33"#7#8\relax
904 \xy@@{\advance\xypolynode@\tw@}%
905 \POS"#30"#1"#30"-(1,0)#2="#34"#4#5\relax
906 \xy@@{\advance\xypolynode@\m@ne}%
907 \POS"#33"#6"#34"#7#8\relax
908 \xy@@{\advance\xypolynode@\tw@}%
909 \POS"#30"#1"#30"-(.5,\halfrootthree)#2="#35"#4#5\relax
910 \xy@@{\advance\xypolynode@\m@ne}%
911 \POS"#34"#6"#35"#7#8\relax
912 \xy@@{\advance\xypolynode@\tw@}%
913 \POS"#30"#1"#30"-(-.5,\halfrootthree)#2="#36"#4#5\relax
914 \xy@@{\advance\xypolynode@\m@ne}%
915 \POS"#35"#6"#36"#7#8\relax
916 \xy@@{\advance\xypolynode@\@ne}%
917 \POS"#36"#6"#31"#7#8\relax }
919 \xydef@\xyheptagon@@#1#2#3#4#5#6#7#8{%
920 \xy@@{\xypolynode@=\@ne}%
921 \POS#1"#30"+(\sinTwoPIon7,\cosTwoPIon7)#2="#31"#4#5\relax
922 \xy@@{\advance\xypolynode@\@ne}%
923 \POS"#30"#1"#30"+(0,1)#2="#32"#4#5\relax
924 \xy@@{\advance\xypolynode@\m@ne}%
925 \POS"#31"#6"#32"#7#8\relax

926 \xy@@{\advance\xypolynode@\tw@}%
927 \POS"#30"#1"#30"+(-\sinTwoPIon7,\cosTwoPIon7)#2="#33"#4#5\relax
928 \xy@@{\advance\xypolynode@\m@ne}%
929 \POS"#32"#6"#33"#7#8\relax
930 \xy@@{\advance\xypolynode@\tw@}%
931 \POS"#30"#1"#30"-(\sinThreePIon7,\cosThreePIon7)#2="#34"#4#5\relax
932 \xy@@{\advance\xypolynode@\m@ne}%
933 \POS"#33"#6"#34"#7#8\relax
934 \xy@@{\advance\xypolynode@\tw@}%
935 \POS"#30"#1"#30"-(\sinPIon7,\cosPIon7)#2="#35"#4#5\relax
936 \xy@@{\advance\xypolynode@\m@ne}%
937 \POS"#34"#6"#35"#7#8\relax
938 \xy@@{\advance\xypolynode@\tw@}%
939 \POS"#30"#1"#30"+(\sinPIon7,-\cosPIon7)#2="#36"#4#5\relax
940 \xy@@{\advance\xypolynode@\m@ne}%
941 \POS"#35"#6"#36"#7#8\relax
942 \xy@@{\advance\xypolynode@\tw@}%
943 \POS"#30"#1"#30"+(\sinThreePIon7,-\cosThreePIon7)#2="#37"#4#5\relax
944 \xy@@{\advance\xypolynode@\m@ne}%
945 \POS"#36"#6"#37"#7#8\relax
946 \xy@@{\advance\xypolynode@\@ne}%
947 \POS"#37"#6"#31"#7#8\relax }
949 \xydef@\xyoctagon@@#1#2#3#4#5#6#7#8{%
950 \xy@@{\xypolynode@=\@ne}%
951 \POS#1"#30"+(\cosPIon8,\sinPIon8)#2="#31"#4#5\relax
952 \xy@@{\advance\xypolynode@\@ne}%
953 \POS"#30"#1"#30"+(\sinPIon8,\cosPIon8)#2="#32"#4#5\relax
954 \xy@@{\advance\xypolynode@\m@ne}%
955 \POS"#31"#6"#32"#7#8\relax
956 \xy@@{\advance\xypolynode@\tw@}%
957 \POS"#30"#1"#30"-(\sinPIon8,-\cosPIon8)#2="#33"#4#5\relax
958 \xy@@{\advance\xypolynode@\m@ne}%
959 \POS"#32"#6"#33"#7#8\relax
960 \xy@@{\advance\xypolynode@\tw@}%
961 \POS"#30"#1"#30"-(\cosPIon8,-\sinPIon8)#2="#34"#4#5\relax
962 \xy@@{\advance\xypolynode@\m@ne}%
963 \POS"#33"#6"#34"#7#8\relax
964 \xy@@{\advance\xypolynode@\tw@}%
965 \POS"#30"#1"#30"-(\cosPIon8,\sinPIon8)#2="#35"#4#5\relax
966 \xy@@{\advance\xypolynode@\m@ne}%
967 \POS"#34"#6"#35"#7#8\relax
968 \xy@@{\advance\xypolynode@\tw@}%
969 \POS"#30"#1"#30"-(\sinPIon8,\cosPIon8)#2="#36"#4#5\relax
970 \xy@@{\advance\xypolynode@\m@ne}%
971 \POS"#35"#6"#36"#7#8\relax
972 \xy@@{\advance\xypolynode@\tw@}%
973 \POS"#30"#1"#30"+(\sinPIon8,-\cosPIon8)#2="#37"#4#5\relax
974 \xy@@{\advance\xypolynode@\m@ne}%
975 \POS"#36"#6"#37"#7#8\relax

976 \xy@@{\advance\xypolynode@\tw@}%
977 \POS"#30"#1"#30"+(\cosPIon8,-\sinPIon8)#2="#38"#4#5\relax
978 \xy@@{\advance\xypolynode@\m@ne}%
979 \POS"#37"#6"#38"#7#8\relax
980 \xy@@{\advance\xypolynode@\@ne}%
981 \POS"#38"#6"#31"#7#8\relax }
983 \xydef@\xynonagon@@#1#2#3#4#5#6#7#8{%
984 \xy@@{\xypolynode@=\@ne}%
985 \POS#1"#30"+(\sinFourPIon9,\cosFourPIon9)#2="#31"#4#5\relax
986 \xy@@{\advance\xypolynode@\@ne}%
987 \POS"#30"#1"#30"+(\sinTwoPIon9,\cosTwoPIon9)#2="#32"#4#5\relax
988 \xy@@{\advance\xypolynode@\m@ne}%
989 \POS"#31"#6"#32"#7#8\relax
990 \xy@@{\advance\xypolynode@\tw@}%
991 \POS"#30"#1"#30"+(0,1)#2="#33"#4#5\relax
992 \xy@@{\advance\xypolynode@\m@ne}%
993 \POS"#32"#6"#33"#7#8\relax
994 \xy@@{\advance\xypolynode@\tw@}%
995 \POS"#30"#1"#30"+(-\sinTwoPIon9,\cosTwoPIon9)#2="#34"#4#5\relax
996 \xy@@{\advance\xypolynode@\m@ne}%
997 \POS"#33"#6"#34"#7#8\relax
998 \xy@@{\advance\xypolynode@\tw@}%
999 \POS"#30"#1"#30"+(-\sinFourPIon9,\cosFourPIon9)#2="#35"#4#5\relax
1000 \xy@@{\advance\xypolynode@\m@ne}%
1001 \POS"#34"#6"#35"#7#8\relax
1002 \xy@@{\advance\xypolynode@\tw@}%
1003 \POS"#30"#1"#30"-(\cosPIon6,\sinPIon6)#2="#36"#4#5\relax
1004 \xy@@{\advance\xypolynode@\m@ne}%
1005 \POS"#35"#6"#36"#7#8\relax
1006 \xy@@{\advance\xypolynode@\tw@}%
1007 \POS"#30"#1"#30"-(\sinPIon9,\cosPIon9)#2="#37"#4#5\relax
1008 \xy@@{\advance\xypolynode@\m@ne}%
1009 \POS"#36"#6"#37"#7#8\relax
1010 \xy@@{\advance\xypolynode@\tw@}%
1011 \POS"#30"#1"#30"+(\sinPIon9,-\cosPIon9)#2="#38"#4#5\relax
1012 \xy@@{\advance\xypolynode@\m@ne}%
1013 \POS"#37"#6"#38"#7#8\relax
1014 \xy@@{\advance\xypolynode@\tw@}%
1015 \POS"#30"#1"#30"+(\cosPIon6,-\sinPIon6)#2="#39"#4#5\relax
1016 \xy@@{\advance\xypolynode@\m@ne}%
1017 \POS"#38"#6"#39"#7#8\relax
1018 \xy@@{\advance\xypolynode@\@ne}%
1019 \POS"#39"#6"#31"#7#8\relax }
1021 \xydef@\xydecagon@@#1#2#3#4#5#6#7#8{%
1022 \xy@@{\xypolynode@=\@ne}%
1023 \POS#1"#30"+(1,0)#2="#31"#4#5\relax
1024 \xy@@{\advance\xypolynode@\@ne}%
1025 \POS"#30"#1"#30"+(\cosPIon5,\sinPIon5)#2="#32"#4#5\relax
1026 \xy@@{\advance\xypolynode@\m@ne}%

1027 \POS"#31"#6"#32"#7#8\relax
1028 \xy@@{\advance\xypolynode@\tw@}%
1029 \POS"#30"#1"#30"+(\sinPIon{10},\cosPIon{10})#2="#33"#4#5\relax
1030 \xy@@{\advance\xypolynode@\m@ne}%
1031 \POS"#32"#6"#33"#7#8\relax
1032 \xy@@{\advance\xypolynode@\tw@}%
1033 \POS"#30"#1"#30"-(\sinPIon{10},-\cosPIon{10})#2="#34"#4#5\relax
1034 \xy@@{\advance\xypolynode@\m@ne}%
1035 \POS"#33"#6"#34"#7#8\relax
1036 \xy@@{\advance\xypolynode@\tw@}%
1037 \POS"#30"#1"#30"-(\cosPIon5,-\sinPIon5)#2="#35"#4#5\relax
1038 \xy@@{\advance\xypolynode@\m@ne}%
1039 \POS"#34"#6"#35"#7#8\relax
1040 \xy@@{\advance\xypolynode@\tw@}%
1041 \POS"#30"#1"#30"-(1,0)#2="#36"#4#5\relax
1042 \xy@@{\advance\xypolynode@\m@ne}%
1043 \POS"#35"#6"#36"#7#8\relax
1044 \xy@@{\advance\xypolynode@\tw@}%
1045 \POS"#30"#1"#30"-(\cosPIon5,\sinPIon5)#2="#37"#4#5\relax
1046 \xy@@{\advance\xypolynode@\m@ne}%
1047 \POS"#36"#6"#37"#7#8\relax
1048 \xy@@{\advance\xypolynode@\tw@}%
1049 \POS"#30"#1"#30"-(\sinPIon{10},\cosPIon{10})#2="#38"#4#5\relax
1050 \xy@@{\advance\xypolynode@\m@ne}%
1051 \POS"#37"#6"#38"#7#8\relax
1052 \xy@@{\advance\xypolynode@\tw@}%
1053 \POS"#30"#1"#30"+(\sinPIon{10},-\cosPIon{10})#2="#39"#4#5\relax
1054 \xy@@{\advance\xypolynode@\m@ne}%
1055 \POS"#38"#6"#39"#7#8\relax
1056 \xy@@{\advance\xypolynode@\tw@}%
1057 \POS"#30"#1"#30"+(\cosPIon5,-\sinPIon5)#2="#310"#4#5\relax
1058 \xy@@{\advance\xypolynode@\m@ne}%
1059 \POS"#39"#6"#310"#7#8\relax
1060 \xy@@{\advance\xypolynode@\@ne}%
1061 \POS"#310"#6"#31"#7#8\relax }
1063 \xydef@\xyundecagon@@#1#2#3#4#5#6#7#8{%
1064 \xy@@{\xypolynode@=\@ne}%
1065 \POS#1"#30"+(\sinFourPIon{11},\cosFourPIon{11})#2="#31"#4#5\relax
1066 \xy@@{\advance\xypolynode@\@ne}%
1067 \POS"#30"#1"#30"+(\sinTwoPIon{11},\cosTwoPIon{11})#2="#32"#4#5\relax
1068 \xy@@{\advance\xypolynode@\m@ne}%
1069 \POS"#31"#6"#32"#7#8\relax
1070 \xy@@{\advance\xypolynode@\tw@}%
1071 \POS"#30"#1"#30"+(0,1)#2="#33"#4#5\relax
1072 \xy@@{\advance\xypolynode@\m@ne}%
1073 \POS"#32"#6"#33"#7#8\relax
1074 \xy@@{\advance\xypolynode@\tw@}%
1075 \POS"#30"#1"#30"+(-\sinTwoPIon{11},\cosTwoPIon{11})#2="#34"#4#5\relax
1076 \xy@@{\advance\xypolynode@\m@ne}%

1077 \POS"#33"#6"#34"#7#8\relax
1078 \xy@@{\advance\xypolynode@\tw@}%
1079 \POS"#30"#1"#30"+(-\sinFourPIon{11},\cosFourPIon{11})#2="#35"#4#5\relax
1080 \xy@@{\advance\xypolynode@\m@ne}%
1081 \POS"#34"#6"#35"#7#8\relax
1082 \xy@@{\advance\xypolynode@\tw@}%
1083 \POS"#30"#1"#30"-(\sinFivePIon{11},\cosFivePIon{11})#2="#36"#4#5\relax
1084 \xy@@{\advance\xypolynode@\m@ne}%
1085 \POS"#35"#6"#36"#7#8\relax
1086 \xy@@{\advance\xypolynode@\tw@}%
1087 \POS"#30"#1"#30"-(\sinThreePIon{11},\cosThreePIon{11})#2="#37"#4#5\relax
1088 \xy@@{\advance\xypolynode@\m@ne}%
1089 \POS"#36"#6"#37"#7#8\relax
1090 \xy@@{\advance\xypolynode@\tw@}%
1091 \POS"#30"#1"#30"-(\sinPIon{11},\cosPIon{11})#2="#38"#4#5\relax
1092 \xy@@{\advance\xypolynode@\m@ne}%
1093 \POS"#37"#6"#38"#7#8\relax
1094 \xy@@{\advance\xypolynode@\tw@}%
1095 \POS"#30"#1"#30"+(\sinPIon{11},-\cosPIon{11})#2="#39"#4#5\relax
1096 \xy@@{\advance\xypolynode@\m@ne}%
1097 \POS"#38"#6"#39"#7#8\relax
1098 \xy@@{\advance\xypolynode@\tw@}%
1099 \POS"#30"#1"#30"+(\sinThreePIon{11},-\cosThreePIon{11})#2="#310"#4#5\relax
1100 \xy@@{\advance\xypolynode@\m@ne}%
1101 \POS"#39"#6"#310"#7#8\relax
1102 \xy@@{\advance\xypolynode@\tw@}%
1103 \POS"#30"#1"#30"+(\sinFivePIon{11},-\cosFivePIon{11})#2="#311"#4#5\relax
1104 \xy@@{\advance\xypolynode@\m@ne}%
1105 \POS"#310"#6"#311"#7#8\relax
1106 \xy@@{\advance\xypolynode@\@ne}%
1107 \POS"#311"#6"#31"#7#8\relax }
1109 \xydef@\xydodecagon@@#1#2#3#4#5#6#7#8{%
1110 \xy@@{\xypolynode@=\@ne}%
1111 \POS#1"#30"+(\cosPIon{12},\sinPIon{12})#2="#31"#4#5\relax
1112 \xy@@{\advance\xypolynode@\@ne}%
1113 \POS"#30"#1"#30"+(\halfroottwo,\halfroottwo)#2="#32"#4#5\relax
1114 \xy@@{\advance\xypolynode@\m@ne}%
1115 \POS"#31"#6"#32"#7#8\relax
1116 \xy@@{\advance\xypolynode@\tw@}%
1117 \POS"#30"#1"#30"+(\sinPIon{12},\cosPIon{12})#2="#33"#4#5\relax
1118 \xy@@{\advance\xypolynode@\m@ne}%
1119 \POS"#32"#6"#33"#7#8\relax
1120 \xy@@{\advance\xypolynode@\tw@}%
1121 \POS"#30"#1"#30"-(\sinPIon{12},-\cosPIon{12})#2="#34"#4#5\relax
1122 \xy@@{\advance\xypolynode@\m@ne}%
1123 \POS"#33"#6"#34"#7#8\relax
1124 \xy@@{\advance\xypolynode@\tw@}%
1125 \POS"#30"#1"#30"-(\halfroottwo,-\halfroottwo)#2="#35"#4#5\relax
1126 \xy@@{\advance\xypolynode@\m@ne}%

1127 \POS"#34"#6"#35"#7#8\relax
1128 \xy@@{\advance\xypolynode@\tw@}%
1129 \POS"#30"#1"#30"-(\cosPIon{12},-\sinPIon{12})#2="#36"#4#5\relax
1130 \xy@@{\advance\xypolynode@\m@ne}%
1131 \POS"#35"#6"#36"#7#8\relax
1132 \xy@@{\advance\xypolynode@\tw@}%
1133 \POS"#30"#1"#30"-(\cosPIon{12},\sinPIon{12})#2="#37"#4#5\relax
1134 \xy@@{\advance\xypolynode@\m@ne}%
1135 \POS"#36"#6"#37"#7#8\relax
1136 \xy@@{\advance\xypolynode@\tw@}%
1137 \POS"#30"#1"#30"-(\halfroottwo,\halfroottwo)#2="#38"#4#5\relax
1138 \xy@@{\advance\xypolynode@\m@ne}%
1139 \POS"#37"#6"#38"#7#8\relax
1140 \xy@@{\advance\xypolynode@\tw@}%
1141 \POS"#30"#1"#30"-(\sinPIon{12},\cosPIon{12})#2="#39"#4#5\relax
1142 \xy@@{\advance\xypolynode@\m@ne}%
1143 \POS"#38"#6"#39"#7#8\relax
1144 \xy@@{\advance\xypolynode@\tw@}%
1145 \POS"#30"#1"#30"+(\sinPIon{12},-\cosPIon{12})#2="#310"#4#5\relax
1146 \xy@@{\advance\xypolynode@\m@ne}%
1147 \POS"#39"#6"#310"#7#8\relax
1148 \xy@@{\advance\xypolynode@\tw@}%
1149 \POS"#30"#1"#30"+(\halfroottwo,-\halfroottwo)#2="#311"#4#5\relax
1150 \xy@@{\advance\xypolynode@\m@ne}%
1151 \POS"#310"#6"#311"#7#8\relax
1152 \xy@@{\advance\xypolynode@\tw@}%
1153 \POS"#30"#1"#30"+(\cosPIon{12},-\sinPIon{12})#2="#312"#4#5\relax
1154 \xy@@{\advance\xypolynode@\m@ne}%
1155 \POS"#311"#6"#312"#7#8\relax
1156 \xy@@{\advance\xypolynode@\@ne}%
1157 \POS"#312"#6"#31"#7#8\relax }
1161 \xydef@\xylargePolygon@#1#2{%
1162 \dimen@=#1\p@
1163 \xyPolygon@@@\xypolygon@@}
1164 % \xyerror@{Sorry, polygons with #2 sides are not implemented; maximum 12.}{}}

We need a looping construction that will not interfere with others used at a high level.

1171 \xydef@\xypolyrepeat@{\fi}
1172 \xydef@\xypolybody@{}
1173 \xydef@\xypolyiterate@{\xypolybody@\expandafter\xypolyiterate@\else\fi}
1174 \xydef@\xypolyloop@#1\xypolyrepeat@{\def\xypolybody@{#1}\xypolyiterate@}

The counter \xypolynode@ keeps track of the current vertex, spoke and side. Since the user may choose to place another \xypolygon along any such piece, it is necessary to calculate the angle for each vertex afresh, using only information passed via the parameters #1,…,#9.

1183 \xydef@\xypolygon@@#1#2#3#4#5#6#7#8#9{\save
1184 \vfromcartesianangle@{#9}\edef\next@{\the\X@c,\the\Y@c\addGT@\empty}%
1185 \xy@@{\xypolynode@=\@ne}%
1186 \toks@={\POS#1"#30"+}%

1187 \expandafter\expandafter\expandafter\addtotoks@\expandafter
1188 \expandafter\expandafter{\addLT@\empty}%
1189 \expandafter\addtotoks@\expandafter{\next@#2="#31"#4#5\relax}%
1190 \xy@@\dontleave@ \the\toks@

1191 %

1192 \xypolyloop@
1193 \dimen@=360\p@ \count@@=\xypolyNUMSIDES@\relax \advance\dimen@ .5\count@@
1194 \divide\dimen@ \xypolyNUMSIDES@ \relax
1195 \multiply\dimen@\xypolynode@ \relax \advance\dimen@ #9\p@
1196 \edef\tmp@{%
1197  \noexpand\vfromcartesianangle@{\expandafter\removePT@\the\dimen@}}%
1198 \tmp@ \edef\next@{\the\X@c,\the\Y@c\addGT@\empty}%
1199 \xy@@{\advance\xypolynode@\@ne}\count@=\xypolynode@
1200 \toks@={\POS"#30"#1"#30"+}\edef\nextii@{\the\count@}%
1201 \expandafter\expandafter\expandafter\addtotoks@\expandafter
1202 \expandafter\expandafter{\addLT@\space}%
1203 \expandafter\addtotoks@\expandafter{\next@#2="#3}%
1204 \expandafter\addtotoks@\expandafter{\nextii@"#4#5\relax}%
1205 \the\toks@

1206 %

1207 \count@=\xypolynode@ \xy@@{\advance\xypolynode@\m@ne}%
1208 \toks@={\POS"#3}\expandafter\addtotoks@\expandafter{\the\xypolynode@"#6"#3}%
1209 \expandafter\addtotoks@\expandafter{\the\count@"#7#8\relax}%
1210 \the\toks@
1211 \xy@@{\advance\xypolynode@\@ne}\count@=\xypolyNUMSIDES@ \relax
1212 \ifnum\xypolynode@<\count@ \relax \xypolyrepeat@

1213 %

1214 \toks@={\POS"#3}%
1215 \expandafter\addtotoks@\expandafter{\xypolyNUMSIDES@"#6"#31"#7#8\relax}%
1216 \the\toks@ \restore }

The end & Log

DOCMODE3

1226

1227 \xyendinput
1229 % $Log: xypoly.doc,v $
1230 % Revision 3.7  1999/02/16 15:12:50  krisrose
1231 % Interim release (Y&Y fonts now free).

1232 %

1233 % Revision 3.4  1997/05/18 01:13:24  ross
1234 % Essential bugfixes.

1235 %

1236 % Revision 3.3  1996/12/18  09:28:35  ross
1237 % cosmetic changes in documentation

1238 %

1239 % Revision 3.1  1995/09/05  20:28:57  ross
1240 % Releasing version 3.1!

3.8. LATTICE AND WEB FEATURE 389

1242 % Revision 3.0  1995/07/07  20:13:19  ross
1243 % Major release w/new User's Guide!

1244 %

1245 % Revision 2.13  1995/07/04  15:04:51  ross
1246 % Ready for release of v3.

1247 %

1248 % Revision 2.12  1994/10/25  03:01:14  ross
1249 % Final 3beta release [bug fixes & AMS-LaTeX fitting].

1250 %

1251 % Created by Ross Moore, September 1994.

3.8 Lattice and web feature

Vers. 3.3 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This feature provides macros to facilitate typesetting of arrangements of points within a 2-dimensional lattice or “web-like” structure.

Header:

1 %% $Id: xyweb.doc,v 3.3 1996/12/18 09:52:11 ross Exp $
2 %%
3 %% Xy-pic ``Lattice and web'' feature.
4 %% Copyright (c) 1994-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{web}{Lattice and web feature}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

42 \message{lattices,}

We need two counters and macros to access their values.

50 \xynew@{count}\lattice@A
51 \xynew@{count}\lattice@B
52 \xydef@\latticeA{\lattice@A}
53 \xydef@\latticeB{\lattice@B}

Currently the only routines implemented with this feature are some “quick and dirty” macros for dropping objects at the points of an integer lattice. To Do: More sophisticated routines will be developed for later versions of XY-pic, as the need arises.

Mathematically speaking, let u⃗ and v⃗ be vectors pointing in independent directions within the plane. Then the lattice spanned by u⃗ and v⃗ is the infinite set of points L given by:

L = {a u⃗ + b v⃗ ; for a, b integers} .

Within XY-pic the vectors u⃗ and v⃗ can be established as the current coordinate basis vectors. The following macros typeset a finite subset of an abstract lattice.

          \xylattice#1#2#3#4 points in lattice

          \croplattice#1#2#3#4#5#6#7#8

… in specific rectangle.

The parameters #1 … #4 are to be integers a_{min}, a_{max}, b_{min} and b_{max}, so that the portion of the lattice to be typeset is that collection of vectors in L for which a_{min} ≤ a ≤ a_{max} and b_{min} ≤ b ≤ b_{max}.

[figure: ∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘ •a; s^{(1)}; s^{(2)}]

\def\latticebody{%
\ifnum\latticeA=1 \ifnum\latticeB=-1 %
\else\drop{\circ}\fi\else\drop{\circ}\fi}
\xy *\xybox{0;<1.5pc,1mm>:<1mm,1.5pc>::
,0,{\xylattice{-4}4{-3}3}
 ,(1,-1)="a"*{\bullet}*+<2pt>!UL{a}
 ,(-1,1)."a"*\frm{.}}="L"
,{"L"+L \ar "L"+R*+!L{s^{(1)}}}
,{"L"+D \ar "L"+U*+!D{s^{(2)}}}
\endxy

In the above code, notice how the basis is first established then the \xylattice typeset. Doing this within an \xybox allows axes to be sized and placed appropriately. Since lattice points are determined by their (integer) coordinate displacements, they can be revisited to add extra ⟨object⟩s into the overall picture. More generally, the origin for lattice-coordinates is the current ⟨pos⟩ c, when the \xylattice command is encountered. Easy accessibility is maintained, as seen in the next example.

When the basis vectors u⃗ and v⃗ are not perpendicular the collection of points with a, b in these ranges will fill out a skew parallelogram. Generally it is useful to plot only those points lying within a fixed rectangle. This is the purpose of \croplattice, with its extra parameters #5 … #8 determining the ‘cropping’ rectangle within which lattice points will be typeset. Other points will not be typeset even when a and b are within the specified ranges. Explicitly the horizontal range of the cropping rectangle is X_{min} to X_{max}, with X_{min} being the X-coordinate of the vector #5 × u⃗, where #5 is a ⟨number⟩ (not necessarily an integer). Similarly X_{max} is the X-coordinate of #6 × u⃗. The vertical extents are Y_{min} and Y_{max}, given by the Y -coordinates of #7 × v⃗ and #8 × v⃗ respectively.

[figure: ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ ∘ • α •β; s^{(1)}; s^{(2)}]

\def\latticebody{%
\ifnum\latticeA=1 \ifnum\latticeB=-1 %
\else \drop{\circ}\fi\else
\ifnum\latticeA=0 \ifnum\latticeB=1\else
\drop{\circ}\fi\else\drop{\circ}\fi\fi}
\xy +(2,2)="o",0*\xybox{%
 0;<3pc,1.5mm>:<0.72pc,1.65pc>::,{"o"
 \croplattice{-4}4{-4}4{-2.6}{2.6}{-3}3}
 ,"o"+(0,1)="a"*{\bullet}*+!D{\alpha}
 ,"o"+(1,-1)="b"*{\bullet}*+!L{\beta}
 ,"o"+(0,-1)="c","o"+(-1,1)="d"
 ,"a"."c"="e",!DR*{};"a"**\dir{.}
 ,"e",!UL*{};"c"**\dir{.}
 ,"b"."d"="f",!DL*{};"b"**\dir{.}
 ,"f",!UR*{};"d"**\dir{.}
 ,"e"."f"*\frm{.}}="L","o"."L"="L"
 ,{"L"+L \ar "L"+R*+!L{s^{(1)}}}
 ,{"L"+D \ar "L"+U*+!D{s^{(2)}}}
\endxy

The routines \xylattice and \croplattice simply cycle through the allowable range of values for \lattice@A and \lattice@B, with \lattice@B varying within the inner loop.

161 \xydef@\xylattice#1#2#3#4{\xy@{LATTICE}{\xylattice@{#1}{#2}{#3}{#4}}}%
163 \xydef@\xylattice@#1#2#3#4{%
164 \lattice@A=#1\relax
165 \loop \bgroup\lattice@B=#3\relax
166 \innerlatticeloop@{#4}%
167 \edef\tmp@{\egroup

168  \X@min=\the\X@min \X@max=\the\X@max
169  \Y@min=\the\Y@min \Y@max=\the\Y@max
170 }\tmp@ \ifnum\lattice@A<#2\relax \advance\lattice@A\@ne
171 \repeat }
173 \xydef@\innerlatticeloop@#1{%
174 \loop \enter@{\cfromthec@}\enter@{\cplusthec@}%
175 \vfromcartesian@@ \the\lattice@A,\the\lattice@B @%
176 \edef\latticeX{\expandafter\removePT@\the\X@c}%
177 \edef\latticeY{\expandafter\removePT@\the\Y@c}%
178 \leave@ \latticebody \leave@
179 \ifnum\lattice@B<#1\relax \advance\lattice@B\@ne
180 \repeat }

With \xylattice getting the picture size correct is simply a matter of passing \X@min, X@max, etc. outside of the inner group. However with \croplattice these are first set to correspond to the ‘cropping rectangle’ then subsequently merged with their original values.

190 \xydef@\croplattice#1#2#3#4#5#6#7#8{\xy@{LATTICE}%
191 {\xycroplattice@{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}}}%
193 \xydef@\xycroplattice@#1#2#3#4#5#6#7#8{%
194 \enter@{\X@min=\the\X@min \X@max=\the\X@max
195 \Y@min=\the\Y@min \Y@max=\the\Y@max}%
196 \enter@{\cfromthec@}\enter@{\cplusthec@}%
197 \vfromcartesian@@ #5,0 @\leave@ \X@min=\X@c \leave@
198 \enter@{\cfromthec@}\enter@{\cplusthec@}%
199 \vfromcartesian@@ #6,0 @\leave@ \X@max=\X@c \leave@
200 \enter@{\cfromthec@}\enter@{\cplusthec@}%
201 \vfromcartesian@@ 0,#7 @\leave@ \Y@min=\Y@c \leave@
202 \enter@{\cfromthec@}\enter@{\cplusthec@}%
203 \vfromcartesian@@ 0,#8 @\leave@ \Y@max=\Y@c \leave@
204 \lattice@A=#1\relax
205 \loop
206 \bgroup\lattice@B=#3\relax
207  \enter@{\cfromthec@}\innercroplatticeloop@{#4}\leave@
208 \egroup
209 \ifnum\lattice@A<#2\relax \advance\lattice@A\@ne
210 \repeat \mergecropextents@ }
212 \xydef@\innercroplatticeloop@#1{%
213 \loop
214 \enter@{\cfromthec@}\enter@{\cplusthec@}%
215  \vfromcartesian@@ \the\lattice@A,\the\lattice@B @%
216  \edef\latticeX{\expandafter\removePT@\the\X@c}%
217  \edef\latticeY{\expandafter\removePT@\the\Y@c}%
218 \leave@ \DN@{\latticebody}%
219 \ifdim\X@c<\X@min\DN@{}%
220 \else\ifdim\X@c>\X@max\DN@{}%
221 \else\ifdim\Y@c<\Y@min\DN@{}%
222 \else\ifdim\Y@c>\Y@max\DN@{}%
223 \fi\fi\fi\fi \next@ \leave@
224 \ifnum\lattice@B<#1\relax \advance\lattice@B\@ne

225 \repeat }
227 \xydef@\mergecropextents@{%
228 \edef\tmp@{%
229 \noexpand\ifdim\X@min>\the\X@min \X@min=\the\X@min\noexpand\fi
230 \noexpand\ifdim\X@max<\the\X@max \X@max=\the\X@max\noexpand\fi
231 \noexpand\ifdim\Y@min>\the\Y@min \Y@min=\the\Y@min\noexpand\fi
232 \noexpand\ifdim\Y@max<\the\Y@max \Y@max=\the\Y@max\noexpand\fi}%
233 \leave@ \tmp@ }

The \latticebody macro. At each lattice point within the specified range for a, b (and within the cropping rectangle when \croplattice is used), a macro called \latticebody is expanded. This is meant to be user-definable, so as to be able to adapt to any specific requirement. It has a default expansion given by …

                          \def\latticebody{\drop{\bullet}} .

The following macros may be useful when specifying what to do at each point of the lattice.

\latticebody  expanded at lattice points

             \defaultlatticebody resets to default

\latticeA  a-value of lattice point
\latticeB  b-value of lattice point
\latticeX  X-coord, offset in pts…
\latticeY  Y -coord, … from lattice origin.

As in the examples presented above, the object dropped at the lattice point can be varied according to its location, or omitted altogether.

The default \latticebody macro …

266 \xydef@\deflatticebody@{\def\latticebody{\drop{\bullet}}}
267 \xydef@\defaultlatticebody{\deflatticebody@}
268 \deflatticebody@

In the final example the \latticebody macro performs a calculation to decide which lattice points should be emphasised:

[figure: . . . . . . . • …. • … • . • • . . . . . . . . . . . . . . • . . . . . . . • . . . . .; σ^{(1)}; σ^{(2)}]

\def\latticebody{\dimen0=\latticeX pt
 \ifdim\dimen0>0pt \divide\dimen0 by 64
 \dimen0=\latticeY\dimen0 \relax
 \ifdim 0pt>\dimen0 \dimen0=-\dimen0 \fi
 \ifdim 10pt>\dimen0 \drop{\bullet}%
 \else\drop{.}\fi \else\drop{.}\fi}
\xy*\xybox{0;<3pc,2.57mm>:<.83pc,2.25pc>::
,0,{\croplattice{-3}5{-5}5
  {-1.3}{4.5}{-3.4}{4.4}}}="L"
,{"L"+L \ar "L"+!R*+!L{\sigma^{(1)}}}
,{"L"+D \ar "L"+!U*+!D{\sigma^{(2)}}}
\endxy

The end & Log DOCMODE3

302 \xyendinput
304 % $Log: xyweb.doc,v $
305 % Revision 3.3  1996/12/18  09:52:11  ross
306 % no changes

307 %

308 % Revision 3.1  1995/09/05 20:36:33  ross
309 % Release!

310 %

311 % Revision 3.0  1995/07/07  20:13:19  ross
312 % Major release w/new User's Guide!

313 %

314 % Revision 2.13  1995/07/05  10:36:22  ross
315 % Ready for v3 release?

316 %

317 % NEW for version 3.

3.9 Circle, Ellipse, Arc feature

Vers. 3.4 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This feature provides a means to a specify circles of arbitrary radius, drawn with a variety of line styles. Similarly ellipses may be specified, having arbitrary major/minor axes aligned in any direction. A circular arc joining two points can be constructed with specified tangent direction at one end.

All the curves described here—circles, ellipses and sectors of these—are constructed using the curves from the xycurve extension. As such any comments given there concerning memory requirements are equally valid here, perhaps even more so. Use of the xyps PostScript back-end is highly recommended.

Header:

1 %% $Id: xyarc.doc,v 3.4 1997/05/18 01:13:24 ross Exp $
2 %%
3 %% Xy-pic ``Circles, Ellipses and Arcs'' feature.

4 %% Copyright (c) 1995-1997 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The XY-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The XY-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{arc}{Circle, Ellipse, Arc feature}{\stripRCS$Revision: 3.4 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

The arcs are not truly circular or elliptical, but are approximations given by cubic Bézier segments. Hence the xycurve feature must be loaded.

53 \xyrequire{curve}
54 \xycatcodes

The basic ⟨object⟩ defined here is \arc. So far it is only implemented as a ⟨decor⟩ation, called

\ellipse.

62 \xydef@\ellipse#1#{\xy@{ELLIPSE}{\hbox\bgroup\save@}%
63 \let\endarc@=\endellipse@@ \xyFN@\preARC@ #1@}
65 \xydef@\endellipse@@{\xy@{endELLIPSE}{\leave@\origDirection@
66 \edef\next@{\egroup \X@min=\the\X@min \X@max=\the\X@max
67  \Y@min=\the\Y@min \Y@max=\the\Y@max }\next@}\let\bstartPLACE@=\relax}
69 \xydef@\preARC@{%
70 \ifx\next\space@ \expandafter\DN@\space{\xyFN@\preARC@}%
71 \else\ifx\next @\DN@{\xy@{ellipseARC}\ellipticARC@ \arc@}%
72 \else\ifx\next ~\DN@~##1{\tildeARC@{##1}}%
73 \else\DN@{\xy@{ellipticARC}\ellipticARC@ \arc@}%
74 \fi\fi\fi \next@ }
76 %\xydef@\arc#1#{\xy@{ARC}{\hbox\bgroup\save@}%
77 %  \let\endarc@=\endarc@@\arc@{#1}}
78 %\xydef@\endarc@@{\xy@{endARC}{\leave@\origDirection@

We start by recording the curve ⟨style⟩ and initialising some methods and ⟨pos⟩ names, to be able to easily access important ⟨pos⟩ and ⟨direction⟩ information.

When the ... in \arc...{⟨style⟩} is particularly simple, e.g. ⟨empty⟩ or ^or _, then we can branch immediately to \fullCircle@. Otherwise more parsing is required.

91 \xydef@\arc@#1@#2{\DN@{#2}%
92 \ifx\next@\empty \xy@{arcSTYLE}{\def\arcSTYLE{-}}%
93 \else \xy@{arcSTYLE}{\def\arcSTYLE{#2}}\fi \arc@i
94 \DNii@{#1}%
95 \ifx\nextii@\empty \DN@{\fullCircle@}%
96 \else \DN@{_}%
97  \ifx\next@\nextii@ \xy@{_}{\def\arcOrient@@{_}}%
98  \let\arcOrient@@=\next@ \DN@{\fullCircle@}%
99 \else \DN@{^}%
100 \ifx\next@\nextii@ \xy@{^}{\def\arcOrient@@{^}}%
101  \let\arcOrient@@=\next@ \DN@{\fullCircle@}%
102 \else \DN@{\def\afterARCextents@@{%
103  \xy@{aftARCext}{\let\doCircleArc@=\doCircleArc@@}%
104  \ellipseArc@ \xy@{doCircARCs}{\doCircleArcs@}\endarc@ }%
105 %   \xy@{doCircARCs}{\leave@ \doCircleArcs@}\endarc@ }%
106 \xyFN@\getarcparams@#1@}\fi\fi\fi
107 \next@ }

When further parsing is required, using \getarcparams@, then an @ token is used to mark the end of the relevant tokens.

Before any parsing at all the current p and c are recorded as named ⟨pos⟩itions 0@p and 0@c, as well as a point 0@m along the line in the current direction from p. A method \origDirection@ is defined to artificially re-impose this direction independent of the p and c that may be current at the time. \startDirection@ is initialised to this method, though parsing may change its value. Other methods are initialised, in particular the default orientation; their values can be expected to change with subsequent parsing.

123 \xydef@\arc@i{\xy@{ARCi}{%
124 \save@\idfromc@{0@c}\cfromp@\idfromc@{0@p}%
125 \enter@\cplusthec@ \enter@\relax\begingroup\vfromslide@i{}@\czeroEdge@
126 \leave@\idfromc@{0@m}\leave@ \zeroDivideLimit@{50}%
127 \edef\origDirection@{\Direction=\the\Direction
128 \relax\noexpand\imposeDirection@}%
129 \let\startDirection@=\origDirection@ \def\startDirection@@{}%
130 \def\endDirection@{}\def\endDirection@@{}\def\arcOrient@@{^}}%
131 \def\arcOrient@@{^}\let\processDirections@=\checkstartDirection@
132 \def\arcRadius@{}\def\ellipseRatio@{}\def\arcScale@{\arcScale@@}}
138 \message{circles,}

3.9.1 Full Circles

The xyarc feature allows a much wider range of possibilities for typesetting circles than is available with \cir. Firstly the radius is no longer restricted to a finite collection of sizes. Secondly fancy line (curve) styles are available, as with curved arrows. Finally there are a variety of ways of specifying the desired radius, relative to other parts of the picture being built, as in the following example.

[figure: •; p; •; c]

\xy 0;/r5pc/:*\dir{*}="p",*+!DR{p};
p+(.5,-.5)*\dir{*}="c",*+++!L{c}**\dir{-}
,{\ellipse<>{:}},{\ellipse(.5){}}
,0;(.5,.5)::,"p";"c",{\ellipse(.5){.}}
,{\ellipse<5pt>{=}}\endxy

The following give circles centred at c.

\ellipse<>{⟨style⟩}  radius = dist(p, c)
\ellipse<⟨dimen⟩>{..} radius is the ⟨dimen⟩

\ellipse(⟨num⟩){⟨style⟩} unit circle scaled ⟨num⟩, in the current basis.

Note that if the current basis is not square then the latter variant, namely \ellipse(⟨num⟩), will typeset an ellipse rather than a circle. On the other hand the first two variants always specify true circles. In the 2nd case, i.e. when ⟨dimen⟩ is ⟨empty⟩, the size of the object at p is taken into account when drawing the circle; if this is not desired then kill the size using a null object, e.g. ;*{};.

Currently the \ellipse macro works only as a ⟨decor⟩. In future versions there will be an ⟨object⟩ called \arc having elliptical shape, via \circleEdge with possibly unequal extents. Also it will be possible to \connect\arc, which will set the current connection so that any place on the full ellipse, not just the visible sector, will be accessible using an extension to the usual ⟨place⟩ mechanism.

To Do: make this be!!

The simplest cases of full circles go straight to \circleArc@.

191 \xydef@\fullCircle@{\xy@{fullCIRC}{\let\endDirection@=\relax
192 \let\doCircleArc@=\doMergeEndArc@@}\circleArc@ }%

If the first non-space token following \arc is < then the current c is taken to be the centre of the circle or ellipse, or sector thereof. The first parsing is done to interpret information concerning the radius, (or axes of an ellipse) along with an orientation. This can be specified either as absolute dimensions, enclosed in <… >, or relative to the current basis by (…), or based on the line \overline{pc} using <> or <,⟨dimen⟩> or (,⟨num⟩).

204 \xydef@\getarcparams@{%
205 \ifx\space@\next \expandafter\DN@\space{\xyFN@\getarcparams@}%gobble spaces
206 \else\addLT@\ifx \next \xy@{<}{}%
207 \addGT@{\addLT@\DN@##1}{\splitRadius@dim##1,,@}%
208 % \else\ifx \next (\xy@{(}{}\DN@(##1){\splitRadius@##1,,@}%
209 \else\ifx\next (\DN@({\xyFN@\checkRadOpen@}%
210 \else\ifx\next @\xy@{@}{}\DN@ @{\fullEllipse@}%
211 \else \addLQ@\ifx \next \addLQ@\DN@{\xy@`{}\ARCturn@}%
212 \else \DN@{\getarcExtents@}%
213 \fi\fi\fi\fi\fi \next@ }
215 \xydef@\checkRadOpen@{%

216 \ifx\next *\DN@{\xyFN@\getarcExtents@ (}%
217 \else \xy@{(}{}\DN@##1){\splitRadius@##1,,@}%
218 \fi \next@ }

The centre is now stored as "0@0", since the value of "0@c" will be changed to agree with "0@p". This is so that start/finish directions will agree, ensuring all four quadrants be drawn. The following method is actually executed after all the radius/axes information has been parsed.

228 \xydef@\fixedRadiusArc@{%
229 \xy@{fixRadArc}{\save@ \idfromc@{0@0}\cfromp@\idfromc@{0@c}\leave@}%
230 \xyFN@\fixedRadiusArc@i }
232 \xydef@\fixedRadiusArc@i{%
233 \ifx\next\space@ \expandafter\DN@\space{\xyFN@\fixedRadiusArc@i}%
234 \else\ifx\next @\xy@{@}{}\DN@ @{\fullEllipse@}%
235 \else\DN@{\let\processDirections@=\processArcDirections@
236 \def\afterARCextents@@{\xy@{aftARCext}{\let\doCircleArc@=\doCircleArc@@
237  \ellipseSector@}}\xyFN@\getarcExtents@}%
238 \fi\fi \next@ }

When a full circle or ellipse is required then there are three methods which must be invoked when establishing the local basis change.

\arcScale@ Initially this has value \arcScale@@ which is based on \overline{pc}. It is changed only by (⟨num⟩) and (⟨num⟩,⟨num⟩); see the code for \splitRadius@ below. When executed, this method will establish the required basis, at least partially.

252 \xydef@\arcScale@@{\xy@{arcSCALE@@}{\save@
253 \cfromid@{0@0}\pfromc@\cfromid@{0@p}\setbase@\X@p\Y@p\X@c\Y@c}}

\arcRadius@ Initially ⟨empty⟩, this changes with <⟨dimen⟩,⟨dimen⟩> and <⟨dimen⟩> to \arcScale@dim which gets the radius by a ⟨slide⟩ of given ⟨dimen⟩ along the line \overline{pc}.

262 \xydef@\arcScale@dim#1{\xy@{arcSCALEdim}{\save@
263 \cfromid@{0@0}\pfromc@ \cfromid@{0@p}\setupDirection@\cfromp@
264 \enter@\cplusthec@ \begingroup\vfromslide@i#1@%
265 \setbase@\X@p\Y@p\X@c\Y@c \idfromc@{0@p}}}

\ellipseRatio@ Initially ⟨empty⟩, this changes with <⟨dimen⟩,⟨dimen⟩> to \ellipseScale@dim which establishs the (\X@basey, \Y@basey) by a ⟨slide⟩ perpendicular to the line \overline{pc}, or to \ellipseScale@ with (,⟨num⟩) to simply set the perpendicular basis direction using ⟨num⟩ as a coordinate.

277 \xydef@\ellipseScale@dim#1{\xy@{ellSCALEdim}{\setupDirection@\cfromp@
278 \enter@\cplusthec@ \aboveDirection@\xydashl@ \vfromslide@{#1}\leave@
279 \setbase@@\X@c\Y@c}}
281 \xydef@\ellipseScale@#1{\xy@{ellSCALE@}%
282 {\vfromcartesian@@0,#1@\setbase@@\X@c\Y@c}}

The methods \splitRadius@dim and \splitRadius@ complete the interpretation of the radius/axes specification. They must determine whether one or two pieces of information have been explicitly provided, and act accordingly.

293 \xydef@\splitRadius@dim#1,#2,#3@{%
294 \DN@{#1}\ifx\next@\empty\dimen@=\z@\else\dimen@=#1\relax%\splinetracing

295 \expandafter\def\expandafter\arcRadius@
296  \expandafter{\arcScale@dim{#1}}\fi
297 \DN@{#2}\ifx\next@\empty\dimen@ii=\z@\def\ellipseRatio@{}%
298 \else\dimen@ii=#2\relax \expandafter
299 \def\expandafter\ellipseRatio@\expandafter{\ellipseScale@dim{#2}}%
300 \fi \fixedRadiusArc@ }
302 \xydef@\splitRadius@#1,#2,#3@{%
303 \DN@{#1}\ifx\next@\empty\dimen@=\z@\else\dimen@=#1\p@\relax\fi
304 \DN@{#2}\ifx\next@\empty\dimen@ii=\z@\else\dimen@ii=#2\p@\relax\fi
305 \ifdim\dimen@=\z@ \ifdim\dimen@ii=\z@\else \expandafter
306 \def\expandafter\ellipseRatio@\expandafter{\ellipseScale@{#2}}\fi
307 \else
308 \ifdim\dimen@ii=\z@
309  \def\arcScale@{\xy@{arcSCALE@}{\save@\cfromid@{0@0}%
310  \X@origin=\X@c \Y@origin=\Y@c
311  \X@xbase=#1\X@xbase \Y@xbase=#1\Y@xbase
312  \X@ybase=#1\X@ybase \Y@ybase=#1\Y@ybase
313  \advance\X@c\X@xbase \advance\Y@c\Y@xbase \czeroEdge@
314  \idfromc@{0@p}\idfromc@{0@c}}}%
315 \else
316  \def\arcScale@{\xy@{arcSCALE@}{\save@\cfromid@{0@0}%
317  \X@origin=\X@c \Y@origin=\Y@c
318  \X@xbase=#1\X@xbase \Y@xbase=#1\Y@xbase
319  \X@ybase=#2\X@ybase \Y@ybase=#2\Y@ybase
320  \advance\X@c\X@xbase \advance\Y@c\Y@xbase \czeroEdge@
321  \idfromc@{0@p}\idfromc@{0@c}}}%
322 \fi
323 \fi \fixedRadiusArc@ }
325 \xydef@\baseOrient@{\DN@{_}\ifx\next@\arcOrient@@
326 \X@ybase=-\X@ybase \Y@ybase=-\Y@ybase \fi }
333 \message{ellipses,}

3.9.2 Ellipses

There are several ways to specify an ellipse, apart from the method illustrated above in which the basis must be changed from square. Basically we must specify the lengths of the major and minor axes. Also it is necessary to specify an alignment for one axis.

In the following, the ellipse is centred on c and one axis is aligned along the line \overline{pc}, except with the final variant where it aligns with the current basis. When used ⟨num⟩ is treated as a scale factor, multiplying an appropriate length.

\ellipse<⟨dimen⟩,⟨dimen⟩>{..} given axes lengths
\ellipse<,⟨dimen⟩>\{⟨style⟩\} one axis is \overline{pc}
\ellipse(,⟨num⟩){⟨style⟩}  ...perp. axis scaled

\ellipse(⟨num⟩,⟨num⟩){..} scaled axes aligned with basis.

In the latter variant, if the second ⟨num⟩ is ⟨empty⟩ then this is equivalent to both ⟨num⟩s having the same value, which is in turn equivalent to the final variant for circles.

[figure: •; p; •; c]

\xy 0;/r5pc/:*\dir{*},*++!DR(.5){p}
*\frm{-};p+(.5,-.5)*\dir{*}="c",
**\dir{-},*+!UL{c},"c",
,{\ellipse(1,.4){:}},{\ellipse(,.75){}}
,{\ellipse<15pt,10pt>{=}}
;*{};{\ellipse<,10pt>{.}}\endxy

As with full circles, full ellipses require little preparation.

377 \xydef@\fullEllipse@{\xy@{fullELLIPSE}%
378 {\def\startDirection@{}\let\doCircleArc@=\doMergeEndArc@@}%
379 \ellipseArc@
380 \xy@{doCIRCarcs}{\leave@ \doCircleArcs@}\endarc@ }

3.9.3 Drawing arcs

This method is common to full circles, ellipses and circular arcs. It first executes the methods

\arcScale@, \arcRadius@, \ellipseRatio@ where necessary, then examines \arcOrient@@ to de-

cide if the arc is to be typeset clockwise or counter-clockwise.

393 \xydef@\ellipseArc@{%
394 \arcScale@ \arcRadius@ \ellipseRatio@
395 \xy@{arcCONTROLS}{\baseOrient@ \arcControls@ \let\bstartPLACE@=\relax }}

Here is where the “control points” are defined, for each of the four Bézier cubic segments, using coordinates in the constructed basis. The endpoints of the segments—though, not necessarily of the arc—are stored as 0p, 1c, 2c, 3c and the tangential control points are stored as 1m, 2m, …, 8m.

405 \xydef@\cubicARCcontrols@@{\czeroEdge@
406 \vfromcartesian@@0,1@\idfromc@{1@c}%
407 \vfromcartesian@@-1,0@\idfromc@{2@c}%
408 \vfromcartesian@@0,-1@\idfromc@{3@c}%
409 \vfromcartesian@@1,\arcparam@ @\idfromc@{1@m}%
410 \vfromcartesian@@\arcparam@,1@\idfromc@{2@m}%
411 \vfromcartesian@@-\arcparam@,1@\idfromc@{3@m}%
412 \vfromcartesian@@-1,\arcparam@ @\idfromc@{4@m}%
413 \vfromcartesian@@-1,-\arcparam@ @\idfromc@{5@m}%
414 \vfromcartesian@@-\arcparam@,-1@\idfromc@{6@m}%
415 \vfromcartesian@@\arcparam@,-1@\idfromc@{7@m}%
416 \vfromcartesian@@1,-\arcparam@ @\idfromc@{8@m}%

417 }

Drawing the circle/ellipse/arc means tracing along the requisite cubic segments. The method \doCircleArc@@ is used for full circles/ellipses when complete segments are to be typeset. The

methods \doMergeStartArc@, \doMergeEndArc@@ and \doMergeBothArc@ are used when a segment

is not complete. The work by “merging” the initial/final point of the curved segment with the appropriate point required to be at the extremity of the arc. Typesetting of the curve should not take place within the region covered by this merged object.

To overcome the difficulty of the curve leaving then re-entering this region, a second merge is performed to extend it suitably. This is the purpose of \cfromcontrols@. Due to the “convex-hull property” of the Bézier cubic segment, a point can be constructed from the end-points and control points which can be used to extend the rectangle to cover a suitable portion of the curve.

437 \xydef@\doCircleArc@@#1#2{\save@ \ifcase#2\relax
438 \doCircleArc@@@{0@p}{1@m}{2@m}{1@c}{#1}\or
439 \doCircleArc@@@{1@c}{3@m}{4@m}{2@c}{#1}\or
440 \doCircleArc@@@{2@c}{5@m}{6@m}{3@c}{#1}\or
441 \doCircleArc@@@{3@c}{7@m}{8@m}{0@p}{#1}\or
442 \doCircleArc@@@{0@p}{1@m}{2@m}{1@c}{#1}\or
443 \doCircleArc@@@{1@c}{3@m}{4@m}{2@c}{#1}\or
444 \doCircleArc@@@{2@c}{5@m}{6@m}{3@c}{#1}\or
445 \doCircleArc@@@{3@c}{7@m}{8@m}{0@p}{#1}\fi \leave@ }
447 \xydef@\doCircleArc@@@#1#2#3#4#5{%
448 \cfromid@{#1}\pfromc@\senter@
449 \cfromid@{#2}\spushc@\cfromid@{#3}\spushc@\cfromid@{#4}%
450 \connect@\crvs{#5}\relax\sinit@\sleave@}
452 \xydef@\doMergeEndArc@@#1#2{\save@\ifcase#2\relax
453 \doMergeEnd@@@{0@p}{1@m}{2@m}{1@c}{#1}\relax\or
454 \doMergeEnd@@@{1@c}{3@m}{4@m}{2@c}{#1}\relax\or
455 \doMergeEnd@@@{2@c}{5@m}{6@m}{3@c}{#1}\relax\or
456 \doMergeEnd@@@{3@c}{7@m}{8@m}{0@p}{#1}@\fi \leave@ }
458 \xydef@\doMergeEnd@@@#1#2#3#4#5#6{%
459 \cfromid@{#1}\pfromc@\senter@
460 \cfromid@{#2}\spushc@\cfromid@{#3}\spushc@\cfromid@{#4}%
461 \ifx#6\relax
462 \L@c=.1\p@ \R@c=\L@c \U@c=\L@c \D@c=\L@c \Edge@c={\rectangleEdge}\fi
463 \enter@\cmergethec@\cfromid@{0@c}\leave@
464 \enter@\cmergethec@\cfromcontrols@{#1}{#2}{#3}{#4}\leave@
465 \connect@\crvs{#5}\relax
466 \sinit@\sleave@}
468 \xydef@\doMergeStartArc@#1#2{\save@\ifcase#2\relax
469 \doMergeStart@@{0@p}{1@m}{2@m}{1@c}{#1}@\or
470 \doMergeStart@@{1@c}{3@m}{4@m}{2@c}{#1}\relax\or
471 \doMergeStart@@{2@c}{5@m}{6@m}{3@c}{#1}\relax\or
472 \doMergeStart@@{3@c}{7@m}{8@m}{0@p}{#1}\relax\fi \leave@ }
474 \xydef@\doMergeStart@@#1#2#3#4#5#6{%
475 \cfromid@{#1}\ifx#6\relax
476 \L@c=.1\p@ \R@c=\L@c \U@c=\L@c \D@c=\L@c \Edge@c={\rectangleEdge}\fi
477 \enter@\cmergethec@\cfromid@{0@x}\leave@
478 \enter@\cmergethec@\cfromcontrols@{#4}{#3}{#2}{#1}\leave@
479 \pfromc@
480 \senter@ \cfromid@{#2}\spushc@\cfromid@{#3}\spushc@\cfromid@{#4}%

481 \connect@\crvs{#5}\relax\sinit@\sleave@}
483 \xydef@\doMergeBothArc@#1#2{\save@\ifcase#2\relax
484 \doMergeBoth@@{0@p}{1@m}{2@m}{1@c}{#1}@\or
485 \doMergeBoth@@{1@c}{3@m}{4@m}{2@c}{#1}\relax\or
486 \doMergeBoth@@{2@c}{5@m}{6@m}{3@c}{#1}\relax\or
487 \doMergeBoth@@{3@c}{7@m}{8@m}{0@p}{#1}\relax\fi \leave@ }
489 \xydef@\doMergeBoth@@#1#2#3#4#5#6{%
490 \cfromid@{#1}\ifx#6\relax
491 \L@c=.1\p@ \R@c=\L@c \U@c=\L@c \D@c=\L@c \Edge@c={\rectangleEdge}\fi
492 \enter@\cmergethec@\cfromid@{0@x}\leave@
493 \enter@\cmergethec@\cfromcontrols@{#4}{#3}{#2}{#1}\leave@
494 \pfromc@
495 \senter@ \cfromid@{#2}\spushc@\cfromid@{#3}\spushc@\cfromid@{#4}%
496 \enter@\cmergethec@\cfromid@{0@c}\leave@
497 \enter@\cmergethec@\cfromcontrols@{#1}{#2}{#3}{#4}\leave@
498 \connect@\crvs{#5}\relax\sinit@\sleave@}
500 \xydef@\doMergeEndArc@#1#2{\count@@=#2\relax
501 \ifnum\count@@>\thr@@ \advance\count@@-4\fi\relax
502 \doMergeEndArc@@{#1}\count@@ }
504 \xydef@\doStraightArc@@#1{\xy@{STRAITarc}{\save@
505 \cfromid@{0@p}\pfromc@\cfromid@{0@c}%
506 \senter@\connect@\crvs{#1}\sinit@\sleave@\leave@}}
508 \xydef@\cfromcontrols@#1#2#3#4{\bgroup
509 \cfromid@{#1}\L@p=\X@c \U@p=\Y@c
510 \cfromid@{#4}\R@p=\X@c \D@p=\Y@c
511 \cfromid@{#3}\A@=\X@c \B@=\Y@c \cfromid@{#2}%
512 \ifdim\R@p>\L@p \ifdim\A@>\R@p \R@p=\A@
513  \ifdim\X@c>\R@p \R@p=\X@c\fi\fi
514 \else \ifdim\A@<\R@p \R@p=\A@
515  \ifdim\X@c<\R@p \R@p=\X@c\fi\fi
516 \fi
517 \ifdim\D@p>\U@p \ifdim\B@>\D@p \D@p=\B@
518  \ifdim\Y@p>\D@p \D@p=\Y@p\fi\fi
519 \else \ifdim\B@<\D@p \D@p=\B@
520  \ifdim\Y@p<\D@p \D@p=\Y@p\fi\fi
521 \fi
522 \edef\next@{\egroup \X@c=\the\R@p \Y@c=\the\D@p}\next@ }

The next method controls which segments are typeset. It is rather primitive and could well be im-

proved; e.g. to be more like \doEllipseSectors@ with \forwardSectors@ and \backwardSectors@.

First it calculates the \startDirection@@ as a number, using the current base. Next it calculates \quadDirection@ which records the angle of the y-axis in the current base. Depending on the required orientation, read from \arcOrient@@, this latter number is adjusted to be minimal greater than \startDirection@@ for a counter-clockwise arc, or maximal less than it for a clockwise one. Similarly the value of \endDirection@@ is made larger or smaller than \startDirection@@, according to orientation, by adding ±8192 if necessary.

Each required segment is typeset using \doCircleArc@@ except that the final segment uses the value of \doCircleArc@. When the end-point is the original c then this value is \doMergeEndArc@@, 3.9. CIRCLE, ELLIPSE, ARC FEATURE 403 so that the arc will stop at the edge of this ⟨pos⟩, otherwise \doCircleArc@@ is used.

(The following macro can be shortened by making use of the methods \forwardSectors@ and

\backwardSectors@, as in \doEllipseSectors@.

548 \xydef@\doCircleArcs@{\save@
549 \cfromid@{0@0}\pfromc@\cfromid@{0@p}\setupDirection@
550 \startDirection@ \edef\startDirection@@{\the\Direction}%
551 \cfromid@{1@c}\setupDirection@ \edef\quadDirection@{\the\Direction}\relax
552 \count@=\quadDirection@ \relax\def\nextii@{^}%
553 \let\preDirection@@=\startDirection@@
554 \ifx\nextii@\arcOrient@@
555 \ifnum\quadDirection@>\startDirection@@ \relax
556 \else \advance\count@ by8192 \relax\edef\quadDirection@{\the\count@}\fi
557 \ifx\endDirection@@\empty
558  \ifx\endDirection@\relax
559  \bgroup\cfromid@{0@c}\setupDirection@
560  \edef\next@{\egroup \count@@=\the\Direction}\next@ \relax
561  \ifnum\count@@<\startDirection@@ \advance\count@@ 8192 \fi
562  \edef\endDirection@@{\the\count@@}%
563  \else
564  \count@@=\startDirection@@
565  \advance\count@@ by8192 \edef\endDirection@@{\the\count@@}%
566  \fi
567 \else
568  \count@@=\endDirection@@ \relax\ifnum\count@@<\startDirection@@ \relax
569  \advance\count@@ by8192 \edef\endDirection@@{\the\count@@}\fi
570 \fi % \forwardSectors@
571 \ifnum\endDirection@@>\quadDirection@
572 \DN@{\expandafter\doCircleArc@@\expandafter{\arcSTYLE}{0}}%
573 \else
574 \DN@{\expandafter\doCircleArc@\expandafter{\arcSTYLE}{0}}%
575 \fi

576 %

577 \else % \arcOrient@@ = _

578 %

579 \ifnum\count@<\startDirection@@\relax\else\advance\count@ by-8192 \relax
580 \edef\quadDirection@{\the\count@}\fi
581 \ifx\endDirection@@\empty
582  \ifx\endDirection@\relax
583  \bgroup\cfromid@{0@c}\setupDirection@
584  \edef\next@{\egroup \count@@=\the\Direction}\next@ \relax
585  \ifnum\count@@>\startDirection@@ \advance\count@@-8192 \fi
586  \edef\endDirection@@{\the\count@@}%
587  \else
588  \count@@=\startDirection@@
589  \advance\count@@ by-8192 \edef\endDirection@@{\the\count@@}%
590  \fi
591 \else
592  \count@@=\endDirection@@ \relax \ifnum\count@@>\startDirection@@
593  \advance\count@@ by-8192 \edef\endDirection@@{\the\count@@}\fi

594 \fi %\backwardSectors@
595 \ifnum\endDirection@@<\quadDirection@
596  \DN@{\expandafter\doCircleArc@@\expandafter{\arcSTYLE}{0}}%
597 \else \DN@{\expandafter\doCircleArc@\expandafter{\arcSTYLE}{0}}\fi
598 \fi
599 \next@ \relax

600 %

601 \count@=\quadDirection@ \relax\def\nextii@{^}\DN@{}%
602 \ifx\nextii@\arcOrient@@
603 \count@@=\startDirection@@ \advance\count@@ by4096 \relax
604 \ifnum \count@<\endDirection@@ \relax
605 \ifnum\endDirection@@>\count@@
606 \DN@{\expandafter\doCircleArc@@\expandafter{\arcSTYLE}{1}}%
607 \else \DN@{\expandafter\doCircleArc@\expandafter{\arcSTYLE}{1}}\fi
608 \fi
609 \else
610 \count@@=\startDirection@@ \advance\count@@ by-4096 \relax
611 \ifnum \count@>\endDirection@@ \relax
612 \ifnum\endDirection@@<\count@@
613 \DN@{\expandafter\doCircleArc@@\expandafter{\arcSTYLE}{1}}%
614 \else \DN@{\expandafter\doCircleArc@\expandafter{\arcSTYLE}{1}}\fi
615 \fi\fi
616 \next@ \relax

617 %

618 \ifx\next@\empty \else \relax
619 \count@=\startDirection@@ \relax\def\nextii@{^}\DN@{}%
620 \ifx\nextii@\arcOrient@@ \advance\count@ by4096 \relax
621 \count@@=\quadDirection@ \advance\count@@ by4096 \relax
622 \ifnum \count@<\endDirection@@
623 \ifnum\endDirection@@>\count@@
624 \DN@{\expandafter\doCircleArc@@\expandafter{\arcSTYLE}{2}}%
625 \else \DN@{\expandafter\doCircleArc@\expandafter{\arcSTYLE}{2}}\fi
626 \fi
627 \else \advance\count@ by-4096 \relax
628 \count@@=\quadDirection@ \advance\count@@ by-4096 \relax
629 \ifnum \count@>\endDirection@@ \relax
630 \ifnum\endDirection@@<\count@@
631 \DN@{\expandafter\doCircleArc@@\expandafter{\arcSTYLE}{2}}%
632 \else \DN@{\expandafter\doCircleArc@\expandafter{\arcSTYLE}{2}}\fi
633 \fi\fi
634 \next@ \relax
635 \fi

636 %

637 \ifx\next@\empty \else \relax
638 \count@=\quadDirection@ \def\nextii@{^}\DN@{}%
639 \ifx\nextii@\arcOrient@@ \advance\count@ by4096 \relax
640 \ifnum \count@<\endDirection@@
641 \DN@{\expandafter\doCircleArc@\expandafter{\arcSTYLE}{3}}\fi
642 \else \advance\count@ by-4096 \relax

643 \ifnum \count@>\endDirection@@
644 \DN@{\expandafter\doCircleArc@\expandafter{\arcSTYLE}{3}}\fi
645 \fi \next@ \relax
646 \fi

647 %

648 \leave@ }
654 \message{elliptical arcs,}

3.9.4 Circular and Elliptical Arcs

The xyarc feature handles arcs to be specified in two essentially different ways, according to what information is provided by the user. We call these the “radius-unknown/end-points known” and the “radius-known/end-points unknown” cases.

radius unknown, end-points known

The simplest case, though not necessarily the most common, is that of a circular arc from p to c, with radius and centre unspecified. To uniquely specify the arc, the tangent direction at p is taken to be along the current direction, given by \Direction, as set by the latest ⟨connect⟩ion. If no connection has been used, then the default ⟨direction⟩ is “up”.

\ellipse_{⟨style⟩} clockwise arc from p to c
\ellipse^{⟨style⟩} counter-clockwise arc
\ellipse{⟨style⟩} also counter-clockwise

With this information only, a unique circle can be found whose radius and centre need not be specified in advance. For a unique arc it is sufficient to specify the orientation around the circle.

The exception is when the current direction is from p to c, in which case no circle exists. Instead a straight line is typeset accompanied by the following message:

                      Xy-pic Warning: straight arc encountered

The following example shows how, given three points o, p and c, to continue the line \overline{op} by a circular arc to c joining smoothly at p.

[figure: •; p; •; o; •; c; •; a]

\xy 0;/r5pc/:*=+\dir{*}*+!UR{p};
p+(.5,-.5)*\dir{*}="o",*+!UL{o}
,+(0,.81)*=<6.1pt>\dir{*}*\frm{-}="c"
,*+!DL{c},"o",**\dir{-},
"c",{\ellipse_{}},{\ellipse^{.}}
%
,"o"+(1.5,.2)*\dir{*}="a"*+!UL{a}
,"o";p+/_1pc/,**{},"a",{\ellipse_{}}
\endxy

Note how the remainder of the circle can be specified separately. The example also shows how to specify an arc which leaves a particular point perpendicular to a specific direction.

Slightly more complicated is when the tangent direction at p is specified, but different from the current direction; a unique circular arc can still be defined. More complicated is when a specific tangent direction is required also at c. In this case the arc produced is a segment of an ellipse. (If the required tangent at p points to c then a straight segment is drawn, as in the circular case described above.)

\ellipse⟨dir⟩_{p},⟨orient⟩{..}  circular
\ellipse⟨dir⟩_{p},⟨orient⟩,⟨dir⟩_{c}{..} elliptical
\ellipse⟨dir⟩_{p},⟨orient⟩⟨dir⟩_{c}{..} elliptical
\ellipse⟨dir⟩_{p},⟨orient⟩,=⟨dir⟩_{c}{..} elliptical
\ellipse`⟨coord⟩⟨orient⟩{..}  elliptical

In these cases ⟨dir⟩_{p} and ⟨dir⟩_{c} are ⟨direction⟩ specifications, as in figure 1.5 and note 1.4l, and ⟨orient⟩ must be either ^or _for anti-/clockwise respectively, defaulting to ^if ⟨empty⟩. Beware that the (*⟨pos⟩⟨decor⟩*) form must be used for this ⟨direction⟩ variant, as if an object modifier.

The second and third cases in the above table generally give identical results. The second ‘,’ is thus optional, except in two specific situations:

1. ⟨orient⟩ is empty and ⟨dir⟩_{c} has ^or _as the first token;

2. ⟨orient⟩ is ^and ⟨dir⟩_{c} has ^as first token. Without the , then ^^would be interpreted by TEX as part of a special ligature for a hexadecimal character code.

If both ⟨orient⟩ and ⟨dir⟩_{c} are ⟨empty⟩ then even the first ‘,’ can be omitted.

[figure: •; p; •; o; •; c]

\xy 0;/r5pc/:*=<8.1pt>\dir{*}="p",*\frm{-}
,*++!U{p},"p";p+(.5,-.5)*+\dir{*}="o"
,*+!UL{o},+(0,.81)*=<8.1pt>\dir{*}="c"
,*\frm{-},*++!L{c},"o"**\dir{-},"c"
,{\ellipse :a(50),_:0{:}}
,{\ellipse :a(30),_:a(-45){}}
,{\ellipse :a(40),_{.}},
;*{};{\ellipse :a(20),^=_{=}}\endxy

Note that only the slope of ⟨dir⟩_{p} and ⟨dir⟩_{c} is significant; rotations by 180^{∘} being immaterial.

[figure: •; p; •; o; •; c; •; q]

\xy 0;/r5pc/:*\dir{*}="p",*+!UR{p}
;p+(.5,-.5)*\dir{*}="o",*++!L{o}**\dir{-}
,p+(.5,.5)*\dir{*}="c",*++!D{c},"c"
;p+(1,.1)*\dir{*}="q",*++!L{q}**\dir{-}
,"o";"p",**{};"c"
,{\ellipse![["o";"p"]],_![["q";"c"]]{}}
,{\ellipse![["o";"p"]],![["c";"q"]]{.}}
\endxy

The = variant establishes the ⟨direction⟩ parsing to begin with the direction resulting from ⟨dir⟩_{p} instead of the original direction. If ⟨dir⟩_{c} is required to be the original direction then use :0. It cannot be ⟨empty⟩ since this is interpreted as requiring a circular arc with unspecified tangent at c; see the example above. However when ⟨dir⟩_{p} and ⟨dir⟩_{c} are parallel there is a whole family^{4} of possible ellipses with the specified tangents.

With no further hint available, a choice is made based on the distance between p and c. If the required direction is perpendicular to \overline{pc} this choice results in a circular arc. The optional factor in =(⟨num⟩) is used to alter this choice; the default (1) is assumed when nothing follows the =. This factor is used to “stretch” the ellipse along the specified direction. For a negative ⟨num⟩ the orientation reverses.

[figure: •; p; •; o; •; c]

\xy ;/r5pc/:*+=<10.1pt>\dir{*}="p";p*\frm{-}
,*++!UR{p},p+(.5,-.5)*\dir{*}="o",**\dir{-}
,*+!UL{o},+(0,.81)*=<8.1pt>\dir{*}="c"
,*\frm{-},*++!DL{c},"c"
,{\ellipse r,={}},{\ellipse r,=(2){.}}
,{\ellipse r,^=(3){.}},{\ellipse r,=(-2){}}
,{\ellipse r,=(-1){.}}\endxy

The final variant uses the directions from p and c to the given ⟨coord⟩. If ⟨orient⟩ is ⟨empty⟩ then the orientation is determined to give the shortest path along the ellipse. Specifying an ⟨orient⟩ of ^ or _will force the orientation, even if this means travelling ‘the long way’ around the ellipse. For example, see next figure.

Alternative curves In some cases the circular or elliptic curve can be replaced by a curve with different shape, having the same tangent directions at the end-points. When a full circle/ellipse is specified then one gets instead a closed curve constructed from 4 spline segments. Other variants use a single segment, 2 or 3 segments, or some portion of all 4 segments. Possibilities are given in the following table.

\ellipse~e ...{⟨..⟩} elliptical, as above
\ellipse~q ...{⟨..⟩} parabolic segments
\ellipse~c ...{⟨..⟩} cubic segments
\ellipse~i ...{⟨..⟩} interpolating cubic
\ellipse~p ...{⟨..⟩} cuspidal cubic

4Indeed this is always so. The algorithm used for the general case tends toward parallel lines—clearly unsuitable.

\ellipse~c(⟨num⟩)...{⟨..⟩} cubic segments, with “looseness”

In the latter case the ⟨num⟩, typically between 0 and 1, controls how soon the curve begins to bend away from the tangent direction. Smaller values give tighter curves — 0 for straight lines — with ~c being the same as ~c(1) and ~q is ~c(.66667), that is ⟨num⟩= \frac{2}{3}.

The curve produced by the “interpolating” variant ~i actually passes through the control point "x", with slope parallel to the line \overline{pc}. Since the tangents at p and c point toward "x" the curvature is quite gentle until near "x" where the curve bends rapidly, yet smoothly. This is obtained also by using ~c(1.33333), that is ⟨num⟩= \frac{4}{3}. Since <num> > 1 the “convex hull property” does not hold; indeed the curve is entirely outside the convex hull of p, c and "x", apart from those points themselves.

The ‘cuspidal’ variant ~p is equivalent to ~c(2). It exhibits a cusp. For <num> > 2 the curve is so “loose” that it exhibits loops. (The author offers no guarantees on the usefulness of such curves for any particular purpose; however they do look nice. ◯_{¨⌣})

[figure: •; p; •; c]

\xy 0;/r6pc/:*+\dir{*}="p",*+!UR{p},"p";
p+(.5,-.5)*+\dir{*}="c",*+!UL{c}
,"p"+(.825,-.25)="x"*\dir{+},"c"
,{\xycompile{\ellipse`"x"{-}}}
,{\xycompile{\ellipse~q`"x"^{.}}}
,{\xycompile{\ellipse~c`"x"{.}}}
,{\xycompile{\ellipse~c(.3)`"x"^{:}}}
,{\xycompile{\ellipse~c(2.3)`"x"{-}}}
,{\xycompile{\ellipse~i`"x"^{.}}}
,{\xycompile{\ellipse~p`"x"^{-}}}
\endxy

Hint: When exploring to find the best location for the “control-point” (e.g. the "x" in the above example), then use \xycompile as shown, changing the location outside of the compilation. This speeds up the reprocessing with the changed value.

Furthermore, the ellipses are not true ellipses, but are constructed from four Bézier cubic curves, one for each quadrant of the circle or ellipse. To do this it is sufficient to establish the control points for each cubic segment. This is straightforward, using the following “magic number”, given a square basis such that the desired circle is the unit circle, or rectangular basis for which the “unit circle” is the desired ellipse. Thus ~e is equivalent to ~c(.5517847).

889 \xydef@\arcmagic@@{0.5517847}
890 \xylet@\arcmagic=\arcmagic@@

This is the magic number, exactly given by \frac{1}{12}(\sqrt{385} − 13), that helps construct the Bézier cubic curve that best approximates a quarter-turn arc of a circle. It does so with remarkable accuracy, differing by at most .5% of the radius at any angle; the average deviation along the whole quadrant being less than .13%.

904 \xydef@\tildeARC@#1{%
905 \if q#1\DN@{\xy@{quadARC}\quadARC@ \arc@}%
906 \else\if c#1\DN@{\xyFN@\cubicARC@i}%
907 \else\if e#1\DN@{\xy@{ellipticARC}\ellipticARC@ \arc@}%
908 \else\if i#1\DN@{\xy@{interpARC}\interpARC@ \arc@}%
909 \else\if p#1\DN@{\xy@{cuspidalARC}\cuspidalARC@ \arc@}%
910 \else\xywarning@{unknown arc type: #1 }%
911 \DN@{\xy@{ellipticARC}\ellipticARC@ \arc@}%
912 \fi\fi\fi\fi\fi \next@ }
914 \xydef@\cubicARC@i{%
915 \ifx\next\space@ \expandafter\DN@\space{\xyFN@\cubicARC@i}%
916 \else\ifx\next (\DN@(##1){\xy@{cubicARC(##1)}{\cubicARC@{##1}}\arc@}%
917 \else \DN@{\xy@{cubicARC(1)}{\cubicARC@{1}}\arc@}%
918 \fi\fi \next@ }
922 \xydef@\ellipticARC@{\let\arcControls@=\cubicARCcontrols@@
923 \edef\arcparam@{\arcmagic@@}}
925 \xydef@\cubicARC@#1{\let\arcControls@=\cubicARCcontrols@@
926 \dimen@=#1\p@ \edef\arcparam@{\expandafter\removePT@\the\dimen@}}
928 \xydef@\quadARC@{\let\arcControls@=\cubicARCcontrols@@
929 \def\arcparam@{.66667}}
931 \xydef@\cuspidalARC@{\let\arcControls@=\cubicARCcontrols@@
932 \def\arcparam@{2}}
934 \xydef@\interpARC@{\let\arcControls@=\cubicARCcontrols@@
935 \def\arcparam@{1.33333}}

Avoiding overflows If ⟨dir⟩_{p} and ⟨dir⟩_{c} are intended to be equal then the method of the previous paragraph should be used. However it may happen that “nearly parallel” directions may be specified, perhaps by accident. There is then the possibility of “numerical overflow” or a “division by zero” error. The latter may be accompanied by a warning message:

                          Xy-pic Warning: division by 0 in
                              \intersect@, replaced by 50

This indicates that the number 50 has been used as the result of a division by zero. In many contexts this will produce an acceptable result. However it may lead to an “overflow” in other situations, or to drawing beyond the normal page boundary. This can be controlled using a ⟨decor⟩ of type ,{\zeroDivideLimit{⟨num⟩}}, prior to specifying the \ellipse. The value 50 will be replaced by ⟨num⟩ whenever a “division by zero” would otherwise be encountered in an intersection calculation.

961 \xydef@\ARCturn@{\xy@@\bgroup\afterCOORD{%
962 \xy@@{\edef\next@{\egroup \A@=\the\X@c \B@=\the\Y@c}\next@}\ARCturn@@}}
964 \xydef@\ARCturn@@#1@{\DN@{#1}\DNii@{^}%
965 \ifx\next@\nextii@ \xy@{^}{\def\arcOrient@@{^}}%
966 \else\DNii@{_}\ifx\next@\nextii@ \xy@{_}{\def\arcOrient@@{_}}%
967 \else\xy@{}{\def\arcOrient@@{}}\fi\fi
968 \xy@@\ARCturn@@@ \processDirections@@ }
970 \xydef@\ARCturn@@@{%

971 \bgroup\cfromid@{0@p}\X@p=\X@c \Y@p=\Y@c \X@c=\A@ \Y@c=\B@
972 \setupDirection@ \edef\next@{\egroup\count@=\the\Direction}\next@\relax
973 \edef\startDirection@@{\the\count@ }%
974 \bgroup\cfromid@{0@c}\X@p=\A@ \Y@p=\B@
975 \setupDirection@ \edef\next@{\egroup\count@=\the\Direction}\next@\relax
976 \edef\endDirection@@{\the\count@}%
977 \ifx\arcOrient@@\empty
978 \bgroup\cfromid@{0@p}\X@p=\X@c \Y@p=\Y@c \cfromid@{0@c}%
979  \setupDirection@ \edef\next@{\egroup\count@@=\the\Direction}\next@\relax
980 \count@=-\count@@ \advance\count@\startDirection@@ \relax \count@=-\count@
981 \ifnum\count@>4096 \def\arcOrient@@{_}%
982 \else\ifnum\count@<-4096 \def\arcOrient@@{^}%
983 \else\ifnum\count@>\z@ \def\arcOrient@@{^}%
984 \else\def\arcOrient@@{_}\fi\fi\fi
985 \fi }
991 \xydef@\circleArc@{%
992 \xy@{circARC@}{\cfromid@{0@p}\pfromc@\cfromp@\startDirection@
993 \arcCenter@\idfromc@{0@0}%
994 \def\startDirection@{\bgroup
995  \cfromid@{0@0}\pfromc@\cfromid@{0@p}\setupDirection@
996  \edef\next@{\egroup \Direction=\the\Direction}\next@
997  \relax\imposeDirection@}}%
998 \ifx\endDirection@@\empty
999 \ifx\arcRadius@\empty \ifx\ellipseRatio@\empty\else
1000 \DN@{\arcScale@@}\ifx\arcScale@\next@\else
1001 \xy@@{\bgroup\cfromid@{0@0}\pfromc@\cfromid@{0@c}\setupDirection@
1002  \edef\next@{\egroup \Direction=\the\Direction}\next@
1003 \edef\endDirection@@{\the\Direction}}\fi\fi\fi\fi
1004 \ellipseArc@ \xy@@{\leave@ \doCircleArcs@}\endarc@ }
1005 % \ellipseArc@ \xy@@{\doCircleArcs@}\endarc@ }

The following methods calculate the centre of a circle using the perpendicular to the required angle at p and the perpendicular bisector of the line \overline{pc}.

1013 \xydef@\arcbisector{%
1014 \cfromid@{0@p}\pfromc@\cfromid@{0@c}\setupDirection@
1015 \advance\X@c\X@p\divide\X@c\tw@
1016 \advance\Y@c\Y@p\divide\Y@c\tw@ \czeroEdge@ \pfromc@
1017 \enter@\cplusthec@ \enter@\relax\begingroup
1018 \aboveDirection@\xydashl@ \vfromslide@i{}@\leave@ }
1020 \xydef@\arcCenter@{%
1021 \cfromid@{0@p}\pfromc@\cfromid@{0@m}\setupDirection@
1022 \cfromp@\enter@\cplusthec@ \enter@\relax\begingroup
1023 \aboveDirection@\xydashl@ \vfromslide@i{}@\leave@\no@@
1024 \arcCenter@i }
1026 \xydef@\arcCenter@i{%
1027 \enter@{\pfromthep@}\setupDirection@ \Creset@@
1028 \let\PLACEedgep@@=\PLACEedgep@ \let\PLACEedgec@@=\PLACEedgec@
1029 \enter@{\pfromthep@\basefromthebase@}\bgroup

1030 \arcbisector \edef\next@{\egroup
1031  \X@c =\the\X@c \Y@c=\the\Y@c \X@p=\the\X@p \Y@p=\the\Y@p }%
1032  \next@ \Cintercept@@ \leave@\leave@ }

radius known, end-points unknown

The language for these is a combination of most of that used above, but the interpretation of the ⟨direction⟩s is different...

\ellipse<⟨radius⟩>⟨dir⟩_{1},⟨orient⟩,⟨dir⟩_{2}{..}
\ellipse<⟨radius⟩>⟨dir⟩_{1},⟨orient⟩,=⟨dir⟩_{2}{..}

where ⟨radius⟩ is one of the forms used above to describe a circle or ellipse. Not all of the ellipse will be typeset—only that arc starting with ⟨dir⟩_{1} as tangent vector, tracing via ⟨orient⟩ until the tangent points in direction ⟨dir⟩_{2}. This effectively extends the notation used with \cir in 1.6.2. Note that rotating a given ⟨dir⟩_{i} by 180^{∘} specifies a different arc on the same ellipse/circle. Reversing the ⟨orient⟩ no longer gives the complementary arc, but this complement rotated 180^{∘}.

[figure: •; p; •; c]

\xy 0;/r5pc/:*\dir{*}="p",*+!DR{p};
p+(.5,-.5)*\dir{*}="c",*+!UL{c}**\dir{-}
,"c",{\ellipse<15pt>_,=:a(45){=}}
  ,{\ellipse<>__,=:a(30){-}}
,{\ellipse(1,.4){.}}
  ,{\ellipse(1,.4)_,=:a(120){-}}
,{\ellipse(,.75){.}}
  ,{\ellipse(,.75)_,^,^{-}}\endxy

1075 \xydef@\getarcExtents@{%
1076 \ifx\space@\next\expandafter\DN@\space{\xyFN@\getarcExtents@}%
1077 \else\ifx\next @\xy@{@}{}\DN@ @{\fullEllipse@}%
1078 \else\DN@{\xy@{arcEXTENTs}{\save@
1079 \def\startDirection@{\Direction=\startDirection@@ \imposeDirection@}}%
1080 \xyFN@\getarcExtents@ii}\fi\fi \next@ }
1082 \xydef@\getarcExtents@ii{%
1083 \ifx\next!\xy@{![[}{}\DN@![[##1]]{\getxyDirection@{##1}\getarcExtents@iv}%
1084 \else\DN@{\getarcExtents@iv}\fi \next@ }
1086 \xydef@\getarcExtents@iv{\afterDIRECTIONorEMPTY
1087 {\xy@{startDIR}{\edef\startDirection@@{\the\Direction}\leave@}%
1088 \xyFN@\getarcOrientation@}%
1089 {\xy@{startDIR}{\edef\startDirection@@{\the\Direction}\leave@}%
1090 \xyFN@\getarcOrientation@}}

1092 \xydef@\getarcOrientation@{%
1093 \ifx\space@\next\expandafter\DN@\space{\xyFN@\getarcOrientation@}%
1094 \else\ifx\next @\xy@{@}{}\DN@{\getEndDirection@x}%
1095 \else\ifx\next,\xy@{,}{}\DN@,{\xyFN@\getarcOrientation@i}%
1096 \else\DN@{\getarcOrientation@i}\fi\fi\fi \next@ }%
1098 \xydef@\getarcOrientation@i{%
1099 \ifx\space@\next\expandafter\DN@\space{\xyFN@\getarcOrientation@i}%
1100 \else\ifx\next @\xy@{@}{}\DN@{\getEndDirection@x}%
1101 \else\ifx\next^{}\DN@##1{\xy@{^}{\def\arcOrient@@{^}}%
1102 \def\arcOrient@@{^}\xyFN@\getEndDirection@}%
1103 \else\ifx\next_\DN@##1{\xy@{_}{\def\arcOrient@@{_}}%
1104 \def\arcOrient@@{_}\xyFN@\getEndDirection@}%
1105 \else\DN@{\xyFN@\getEndDirection@}%
1106 \fi\fi\fi\fi \next@ }
1108 \xydef@\getEndDirection@{%
1109 \ifx\space@\next\expandafter\DN@\space{\xyFN@\getEndDirection@}%
1110 \else\ifx\next,\DN@,{\xy@{,}{}\xyFN@\getEndDirection@}%
1111 \else\addEQ@\ifx\next\addEQ@\DN@{\xy@{=}{\save@\startDirection@}%
1112 \xyFN@\getEqDirection@}%
1113 \else \ifx\next!\DN@![[##1]]{\xy@{![[}{\save@}\getxyDirection@{##1}%
1114 \xy@{endDIR}{\edef\endDirection@@{\the\Direction}}%
1115 \xyFN@\getEndDirection@i}%
1116 \else \DN@{\xy@{origDIR}{\save@\origDirection@}\getEndDirection@i}%
1117 \fi\fi\fi\fi \next@ }
1119 \xydef@\getEqDirection@{%
1120 \ifx\space@\next\expandafter\DN@\space{\xyFN@\getEqDirection@}%
1121 \else\ifx\next @\xy@{@}{}\DN@ @{%
1122 \xy@{sameDIR}{\edef\endDirection@@{\startDirection@@}\leave@}%
1123 \parEllipse@{1}{}}%
1124 % \else\ifx\next (\DN@(##1)##2@{\xy@{()}{\leave@}\parEllipse@{##1}{##2}}%
1125 \else\ifx\next (\DN@({\xyFN@\checkEqOpen@}%
1126 \else \DN@{\getEndDirection@i}\fi\fi\fi \next@ }
1128 \xydef@\checkEqOpen@{%
1129 \ifx\next *\DN@{\getEndDirection@i (}%
1130 \else \DN@##1)##2@{\xy@{()}\leave@ \parEllipse@{##1}{##2}}%
1131 \fi \next@ }
1133 \xydef@\getEndDirection@i{\afterDIRECTIONorEMPTY
1134 {\xy@{endDIR}{\edef\endDirection@@{\the\Direction}\leave@}%
1135 \getEndDirection@x }%
1136 {\xy@{endDIR}\leave@ \getEndDirection@x }}
1138 \xydef@\getEndDirection@x#1@{%
1139 \DN@{#1}\ifx\next@\empty\relax \else\xywarning@{\omittingTokens@}\fi
1140 \processDirections@ }
1142 \xydef@\omittingTokens@{omitting unused tokens: \codeof\next@ }
1146 \xydef@\processDirections@@{%
1147 \ifx\endDirection@@\empty \skewCircle@

1148 \else \skewEllipse@ \expandafter \afterARCextents@@ \fi }
1150 \xydef@\processArcDirections@{%
1151 \xy@{ARCdirs}{\ifx\endDirection@@\empty
1152 \origDirection@ \edef\endDirection@@{\the\Direction}\fi}%
1153 \ellipseArc@
1154 \xy@{procARCdirs}\processArcDirections@@
1155 \let\arcScale@\ellsave@ \let\arcRadius@\ellsave@ \def\ellipseRatio@{}%
1156 \xy@{circSECTORS}{\doCircleSectors@}\endarc@ }
1158 \xydef@\ellsave@{\xy@@{\save@}}
1160 \xydef@\processArcDirections@@{\save@
1161 \bgroup \cfromid@{0@0}\pfromc@ \Direction=\startDirection@@
1162 \DN@{_}\ifx\next@\arcOrient@@
1163 \advance\Direction \ifnum\Direction<\z@-\fi 4096 \relax\fi
1164 \imposeDirection@
1165 \d@X=\cosDirection\Y@ybase \advance\d@X-\sinDirection\X@ybase
1166 \d@Y=-\cosDirection\Y@xbase \advance\d@Y\sinDirection\X@xbase
1167 \setupDirection@i
1168 \d@X=-\cosDirection\X@ybase \advance\d@X\sinDirection\X@xbase
1169 \d@Y=-\cosDirection\Y@ybase \advance\d@Y\sinDirection\Y@xbase
1170 \enter@\cplusthec@\X@c=\d@X \Y@c=\d@Y \leave@ \czeroEdge@
1171 \setupDirection@i
1172 \czeroEdge@
1173 \edef\next@{\egroup \cfromthec@ \count@=\the\Direction}\next@
1174 \edef\startDirection@@{\the\count@}\idfromc@{0@x}%

1175 %

1176 \bgroup \cfromid@{0@0}\pfromc@ \Direction=\endDirection@@
1177 \DN@{_}\ifx\next@\arcOrient@@
1178 \advance\Direction \ifnum\Direction<\z@-\fi 4096 \relax\fi
1179 \imposeDirection@
1180 \d@X=\cosDirection\Y@ybase \advance\d@X-\sinDirection\X@ybase
1181 \d@Y=-\cosDirection\Y@xbase \advance\d@Y\sinDirection\X@xbase
1182 \setupDirection@i
1183 \d@X=-\cosDirection\X@ybase \advance\d@X\sinDirection\X@xbase
1184 \d@Y=-\cosDirection\Y@ybase \advance\d@Y\sinDirection\Y@xbase
1185 \enter@\cplusthec@\X@c=\d@X \Y@c=\d@Y \leave@
1186 \czeroEdge@
1187 \setupDirection@i
1188 \edef\next@{\egroup \cfromthec@ \count@=\the\Direction}\next@
1189 \edef\endDirection@@{\the\count@}\idfromc@{0@c}%

1190 %

1191 \count@=\startDirection@@ \relax \count@@=\endDirection@@ \relax
1192 \DN@{^}\ifx\arcOrient@@\next@
1193 \ifnum\count@@>\count@ \else\advance\count@@ 8192 \relax\fi
1194 \else
1195 \ifnum\count@@<\count@ \else\advance\count@@-8192 \relax\fi\fi
1196 \edef\startDirection@@{\the\count@}%
1197 \edef\endDirection@@{\the\count@@}}%
1199 \xydef@\doCircleSectors@{%

1200 \let\doCircleArc@=\doMergeEndArc@@ \leave@ \leave@
1201 \cfromid@{0@0}\pfromc@\cfromid@{0@p}\setupDirection@
1202 \count@=\Direction \DN@{^}\ifx\arcOrient@@\next@
1203 \ifnum\count@>\startDirection@@ \advance\count@-8192 \fi\relax
1204 \count@@=\count@ \advance\count@@ 8192 \relax
1205 \ifnum\count@@<\endDirection@@ \advance\count@@ 8192 \fi\relax
1206 \else
1207 \ifnum\count@<\startDirection@@ \advance\count@ 8192 \fi\relax
1208 \count@@=\count@ \advance\count@@-8192 \relax
1209 \ifnum\count@@>\endDirection@@ \advance\count@@-8192 \fi\relax
1210 \fi \relax
1211 \edef\preDirection@@{\the\count@}\edef\postDirection@@{\the\count@@}%
1212 \cfromid@{1@c}\setupDirection@ \count@=\Direction
1213 \def\nextii@{^}\ifx\nextii@\arcOrient@@
1214 \DN@{\forwardSectors@\doEllipseSectors@}%
1215 \ifnum\count@<\preDirection@@ \advance\count@ 8192 \relax
1216 \else \count@@=\count@\advance\count@-8192 \relax
1217 \ifnum\count@@<\preDirection@@ \else\count@=\count@@ \fi\fi
1218 \else
1219 \DN@{\backwardSectors@\doEllipseSectors@}%
1220 \ifnum\count@>\preDirection@@ \advance\count@-8192 \relax
1221 \else \count@@=\count@\advance\count@ 8192 \relax
1222 \ifnum\count@@>\preDirection@@ \else\count@=\count@@ \fi\fi
1223 \fi \edef\quadDirection@{\the\count@}%
1224 \next@ }
1226 \xydef@\forwardSectors@{%
1227 \ifnum \startDirection@@<\quadDirection@ \def\startSector@@{0}%
1228 \else\count@=\preDirection@@ \advance\count@ 4096 \relax
1229 \ifnum \startDirection@@<\count@ \def\startSector@@{1}%
1230 \else\count@=\quadDirection@ \advance\count@ 4096 \relax
1231 \ifnum\startDirection@@<\count@ \def\startSector@@{2}%
1232 \else \def\startSector@@{3}\fi\fi\fi

1233 %

1234 \ifnum\quadDirection@ <\endDirection@@ \relax
1235 \count@=\preDirection@@ \advance\count@ 4096 \relax
1236 \ifnum\count@<\endDirection@@ \relax
1237 \count@=\quadDirection@ \advance\count@ 4096 \relax
1238 \ifnum\count@<\endDirection@@ \relax
1239  \count@=\preDirection@@ \advance\count@ 8192 \relax
1240  \ifnum\count@<\endDirection@@ \relax
1241  \count@=\quadDirection@ \advance\count@ 8192 \relax
1242  \ifnum\count@<\endDirection@@ \relax
1243  \count@=\preDirection@@ \advance\count@ 12288 \relax
1244  \ifnum\count@<\endDirection@@ \relax
1245  \count@=\quadDirection@ \advance\count@ 12288 \relax
1246  \ifnum\count@<\endDirection@@ \def\endSector@@{7}%
1247  \else \def\endSector@@{6}\fi
1248  \else \def\endSector@@{5}\fi
1249  \else \def\endSector@@{4}\fi

1250  \else \def\endSector@@{3}\fi
1251 \else \def\endSector@@{2}\fi
1252 \else \def\endSector@@{1}\fi
1253 \else \def\endSector@@{0}\fi }
1255 \xydef@\backwardSectors@{%
1256 \ifnum \startDirection@@>\quadDirection@ \def\startSector@@{0}%
1257 \else\count@=\preDirection@@ \advance\count@-4096 \relax
1258 \ifnum \startDirection@@>\count@ \def\startSector@@{1}%
1259 \else\count@=\quadDirection@ \advance\count@-4096 \relax
1260 \ifnum\startDirection@@>\count@ \def\startSector@@{2}%
1261 \else \def\startSector@@{3}\fi\fi\fi

1262 %

1263 \ifnum\quadDirection@>\endDirection@@ \relax
1264 \count@=\preDirection@@ \advance\count@-4096 \relax
1265 \ifnum\count@>\endDirection@@ \relax
1266 \count@=\quadDirection@ \advance\count@-4096 \relax
1267 \ifnum\count@>\endDirection@@ \relax
1268  \count@=\preDirection@@ \advance\count@-8192 \relax
1269  \ifnum\count@>\endDirection@@ \relax
1270  \count@=\quadDirection@ \advance\count@-8192 \relax
1271  \ifnum\count@>\endDirection@@ \relax
1272  \count@=\preDirection@@ \advance\count@-12288 \relax
1273  \ifnum\count@>\endDirection@@ \relax
1274  \count@=\quadDirection@ \advance\count@-12288 \relax
1275  \ifnum\count@>\endDirection@@ \def\endSector@@{7}%
1276  \else \def\endSector@@{6}\fi
1277  \else \def\endSector@@{5}\fi
1278  \else \def\endSector@@{4}\fi
1279  \else \def\endSector@@{3}\fi
1280 \else \def\endSector@@{2}\fi
1281 \else \def\endSector@@{1}\fi
1282 \else \def\endSector@@{0}\fi }
1284 \xydef@\doEllipseSectors@{%
1285 \ifx\startSector@@\endSector@@
1286 \DN@{\expandafter\doMergeBothArc@\expandafter{\arcSTYLE}{\endSector@@}}%
1287 \else
1288 \expandafter\doMergeStartArc@\expandafter{\arcSTYLE}{\startSector@@}%
1289 \edef\countArcs@@{\startSector@@}%
1290 \loop@ \count@=\countArcs@@ \relax \advance\count@\@ne
1291 \ifnum \count@ < \endSector@@ \edef\countArcs@@{\the\count@}%
1292  \bgroup\expandafter\doCircleArc@@\expandafter{\arcSTYLE}{\countArcs@@}%
1293  \egroup
1294 \repeat@
1295 \DN@{\expandafter\doMergeEndArc@\expandafter{\arcSTYLE}{\endSector@@}}%
1296 \fi \next@ }

parsing of directions When the starting direction is along the line \overline{pc} then a straight segment is typeset, ignoring any requested ending direction.

1303 \xydef@\checkstartDirection@{%

1304 \bgroup\no@@ \edef\next@{\egroup\count@@=\the\Direction}\next@\relax
1305 \ifnum\count@@=\startDirection@@ \relax \DN@{\straightArc@}%
1306 \else \advance\count@@-\startDirection@@ \relax
1307 \ifnum\count@@=\ifnum\count@@<\z@-\fi 4096 \relax \DN@{\straightArc@}%
1308 \else \DN@{\processDirections@@}\fi\fi \next@ }
1310 \xydef@\straightArc@{\xywarning@{straight arc encountered}%
1311 \xy@@{\let\bstartPLACE@=\relax
1312 \expandafter\doStraightArc@@\expandafter{\arcSTYLE}}\endarc@ }%
1318 \xydef@\skewEllipse@{\xy@@{\doskewEllipse@}%
1319 \def\afterARCextents@@{\xy@{aftARCext}{\let\doCircleArc@=\doMergeEndArc@@}%
1320 \ellipseArc@ \xy@{doCircARCs}{\doCircleArcs@}\endarc@ }%
1321 \let\arcScale@=\relax \def\arcRadius@{}\def\ellipseRatio@{}}
1323 \xydef@\skewCircle@{\xy@@{\setupDirection@}%
1324 \ifnum\Direction=\startDirection@@\relax\DN@{\halfEllipse@{1}}%
1325 \else
1326 \xy@@{\def\startDirection@{\Direction=\startDirection@@\imposeDirection@}%
1327 \cfromid@{0@p}\enter@\cplusthec@ \startDirection@
1328 \enter@\relax\begingroup\vfromslide@i{}@\czeroEdge@\leave@\idfromc@{0@m}%
1329 \let\endDirection@=\relax \let\doCircleArc@=\doMergeEndArc@@}%
1330 \DN@{\circleArc@}%
1331 \fi \next@ }
1333 \xydef@\doskewEllipse@{%
1334 \def\startDirection@{\Direction=\startDirection@@ \relax
1335 \imposeDirection@}\startDirection@ \cfromid@{0@p}%
1336 \enter@\cplusthec@ \enter@\relax\begingroup\vfromslide@i{}@\leave@
1337 \idfromc@{0@x}%
1338 \ifx\endDirection@@\empty \parallelDirection@
1339 \else
1340 \def\endDirection@{\Direction=\endDirection@@ \relax
1341 \imposeDirection@ }\endDirection@ \skewEllB@
1342 \bgroup\setupDirection@\edef\next@{\egroup\count@@=\the\Direction}\next@
1343 \edef\endDirection@@{\the\count@@}%

1344 \fi

1345 \cfromid@{0@p}\bgroup \setupDirection@
1346 \edef\next@{\egroup \count@@=\the\Direction}\next@
1347 \edef\startDirection@@{\the\count@@}}
1349 \xydef@\halfEllipse@#1{\xy@@{%
1350 \cfromid@{0@p}\pfromc@\cfromid@{0@c}\no@@
1351 \edef\endDirection@@{\the\Direction}%
1352 \advance\X@c\X@p \divide\X@c\tw@ \advance\Y@c\Y@p \divide\Y@c\tw@
1353 \idfromc@{0@0}\pfromc@ \cfromid@{0@p}\setbase@\X@p\Y@p\X@c\Y@c
1354 \dimen@=\X@origin \advance\dimen@-\X@c \dimen@ii=\cosDirection\dimen@
1355 \dimen@=\Y@origin \advance\dimen@-\Y@c \advance\dimen@ii \sinDirection\dimen@
1356 \X@c=\X@origin \Y@c=\Y@origin \enter@\cplusthec@
1357 \dimen@=#1\p@ \ifdim\dimen@<\z@ \DN@{^}\dimen@ii=-#1\dimen@ii
1358 \ifx\next@\arcOrient@@\def\arcOrient@@{_}\else\def\arcOrient@@{^}\fi
1359 \else \dimen@ii=#1\dimen@ii\fi

1360 \startDirection@ \enter@\relax\begingroup\expandafter
1361 \vfromslide@i\expandafter{\the\dimen@ii}@\leave@
1362 \idfromc@{1@c}\setbase@@ \X@c \Y@c \adjustBaseOrient@
1363 \count@@=\endDirection@@ \relax
1364 \DN@{^}\advance\count@@\ifx\arcOrient@@\next@\else-\fi 4096 \relax
1365 \edef\startDirection@@{\the\count@@}%
1366 \def\startDirection@{\Direction=\startDirection@@ \imposeDirection@ }%
1367 \let\doCircleArc@=\doMergeEndArc@@ }%
1368 \let\arcScale@=\relax \ellipseArc@
1369 % \xy@@{\leave@ \doCircleArcs@}\endarc@ }
1370 \xy@@{\doCircleArcs@}\endarc@ }
1372 \xydef@\parallelDirection@{\show\parallelDirection@}%
1374 \xydef@\parEllipse@#1#2{\DN@{#2}\ifx\next@\empty
1375 \else\xywarning@{\omittingTokens@ }\fi \halfEllipse@{#1}}
1377 \xydef@\skewEllB@{\cfromid@{0@c}\pfromc@\enter@\cplusthec@
1378 \enter@\relax\begingroup\vfromslide@i{}@\leave@
1379 \enter@{\pfromthep@\basefromthebase@}\no@@
1380 \bgroup \cfromid@{0@p}\pfromc@\cfromid@{0@x}\edef\next@{\egroup
1381 \X@c =\the\X@c \Y@c=\the\Y@c \X@p=\the\X@p \Y@p=\the\Y@p }\next@
1382 \Cintercept@@\leave@ \idfromc@{0@x}\cfromid@{0@p}\enter@\cplusthec@
1383 \cfromid@{0@c}\leave@ \enter@\cplusthec@ \cfromid@{0@x}%
1384 \X@c=-\X@c \Y@c=-\Y@c \leave@ \idfromc@{0@0}\pfromc@\cfromid@{0@p}%
1385 \setbase@\X@p\Y@p\X@c\Y@c \cfromid@{0@c}\setbase@@\X@c\Y@c
1386 \adjustBaseOrient@ }
1388 \xydef@\adjustBaseOrient@{%
1389 \edef\tmp@{\expandafter\removePT@\the\X@xbase}\dimen@=\Y@ybase
1390 \divide\dimen@ 64 \relax \dimen@ii=\tmp@\dimen@
1391 \edef\tmp@{\expandafter\removePT@\the\X@ybase}\dimen@=\Y@xbase
1392 \divide\dimen@ 64 \relax \dimen@=\tmp@\dimen@
1393 \ifdim\dimen@>\dimen@ii \X@ybase=-\X@ybase \Y@ybase=-\Y@ybase \fi }

The end & Log

1409 \xyendinput
1411 % $Log: xyarc.doc,v $
1412 % Revision 3.4  1997/05/18 01:13:24  ross
1413 % Essential bugfixes.

1414 %

1415 % Revision 3.3  1996/12/18 14:21:23  ross
1416 % Ross's version

1417 %

1418 % Revision 3.3.1.1  1996/12/18  08:50:58  ross
1419 % *** empty log message ***

1420 %

1421 % Revision 3.2  1995/09/19  18:20:20  ross
1422 % Bug fix release.

1423 %

1424 % Revision 3.1  1995/09/05  20:36:33  ross

418 CHAPTER 3. FEATURES

1425 % Release!

1426 %

1427 % Revision 3.0  1995/07/07  20:13:19  ross
1428 % Major release w/new User's Guide!

1429 %

1430 % Revision 2.13  1995/07/04  15:04:51  ross
1431 % Ready for release of v3.

1432 %

1433 % NEW for version 3.

3.10 Knots and Links feature

Vers. 3.4 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This feature provides a language for specifying knots, links and general arrangements of crossing strings. Header:

1 %% $Id: xyknot.doc,v 3.4 1997/05/18 01:13:24 ross Exp $
2 %%
3 %% Xy-pic ``Knots and Links'' feature.
4 %% Copyright (c) 1994-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this macro package; if not, write to the Free Software Foundation,
22 %% Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{knot}{Knots and Links feature}{\stripRCS$Revision: 3.4 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

To Do: Document this feature!

44 \message{knots and links,}

This knot feature is really a ‘construction kit’, providing pieces which may be placed appropriately to form knots and links. The types of pieces provided are of two kinds: the “crossings”, representing one string crossing over or under another; and “joins” which are used to connect what would otherwise be loose ends. Several types of each are provided, along with a simple way of specifying where to place arrowheads and labels.

All the pieces ultimately use curves from the curve extension, usually indirectly via the arrow feature. As such, processing can be memory-intensive and may seem rather slow. All the warnings and advice given elsewhere on techniques to handle pages and individual diagrams with many curves are especially applicable when using this feature.

Most constructions use \ar so make sure this feature is loaded.

158 \xyrequire{arrow}\xycatcodes

[figure]

simple link figure-8 knot

[figure]

cinquefoil

Crossings

A “crossing” is intended to represent two strings passing close by, but not meeting. The macros provided specify typesetting within a square cell of coordinate values; using a non-square basis alters this shape, but see also note 3.10c below, for the technique that was used in the “cinquefoil” example above.

Notes

3.10a. Several families of crossing are provided. Those having names as \v... and \h... are designed to stack respectively vertically and horizontally. More precisely the current ⟨pos⟩ starts at the topleft corner and finishes at either the bottom-left or top-right. Say that a crossing is either a ‘vertical crossing’ or ‘horizontal crossing’ respectively.

This certainly applies to the \..cross.. and \..twist.. families, see figure 3.8 in which the strings enter and leave the square all with vertical tangents or all with horizontal tangents. Indeed all crossings are either vertical or horizontal, with the final letter indicating which for the \xover.. families.

Furthermore there is a natural orientation for each crossing, as well as along each strand. This corresponds to the order in which ink is applied to the printed page, following the natural parametrization of each strand as a curved connection or arrow. This orientation determines whether a crossing is ‘over’ (mathematically, positive or right-handed) or ‘under’ (mathematically, negative or lefthanded). It is used in determining the location of labels and the direction of arrowheads placed along the strings. Note that \..cross.. and \..twist.. crossings may set the same curves, but with different orientation and label-positioning.

Figure 3.8 displays the orientation on all the crossings, grouping them into subfamilies consisting of right-handed, left-handed and non-crossings. Also indicated are the default positions for labels and arrow-tips; each piece uses the same code for tips and labels, e.g. \vover<>|>>><{x}|{y}>{z}.

The \x... crossings do not stack easily since their tangents are at 45^{∘} to the coordinate axes. It is the last letter in the name which denotes whether the particular crossing is vertical or horizontal.

On the other hand \vover , \vunder etc. stack vertically on top of a \vcross , \vtwist etc.; similarly \hover stacks at the left of \hcross , \htwist etc.

   $$\xy 0;/r1pc/:
    ,{\vunder\vtwist\vtwist\vunder-}\endxy
   \qquad\qquad\qquad \xy 0;/r1pc/:+(0,-1.5)
    ,{\hover\hcross\hcross\hover-}\endxy$$

Parsing

324 \xydef@\xykparsecross@{%
325 \def\xykSCALE@@{}\edef\xyknotPLACE{\xykmidPLACE@}%
326 \let\xykparser@=\xykparsecross@@
327 \def\xykdefaultbreak@{\let\xykbreak@=\xykforetemp@
328 \def\xyknotPLACE{(.5)}\appendtoholder@}%
329 \xyFN@\xykparsescale@ }
331 {\xyuncatcodes \catcode`@=11
332 \gdef\next{%
333 \ifx\space@\next \expandafter\DN@\space{\xyFN@\xykparsecross@@}%
334 \else\addLT@\ifx\next \addLT@\DN@{\xyprecross@}%
335 \else\addGT@\ifx\next \addGT@\DN@{\xypostcross@}%
336 \else\addEQ@\ifx\next \addEQ@\DN@{\xyFN@\xykparsetips@@}%
337 \else\ifx|\next\DN@|{\xymidcross@}%
338 \else\addAT@\ifx\next \addAT@\DN@(##1){%
339 \xyadjustBREAK@i##1@@\xyFN@\xykparsecross@@}%
340 \else\DN@{\afterknot@}%
341 \fi\fi\fi\fi\fi\fi \next@ }}
342 \xylet@\xykparsecross@@=\next
346 \xydef@\xyprecross@{%
347 \def\xykholder@{\xykprebreak@@}%
348 \edef\xyknotPLACE{\xykprePLACE@}%
349 \xyFN@\xykparsebreak@}
351 \xydef@\xypostcross@{%
352 \def\xykholder@{\xykpostbreak@@}%
353 \edef\xyknotPLACE{\xykpostPLACE@}%
354 \xyFN@\xykparsebreak@}
356 \xydef@\xymidcross@{%
357 \def\xykholder@{\xykmidbreak@@}%
358 \edef\xyknotPLACE{\xykmidPLACE@}%
359 \xyFN@\xykparsebreak@}

These macros are common to most crossings.

3.10. KNOTS AND LINKS FEATURE 421

365 \xydef@\xykcross@#1{\xykcheckTIPS@
366 \expandafter\toks@\expandafter{\expandafter#1\knotSTYLE}}
368 \xydef@\xykoverstring@{\addtotoks@{{}}\xykmidbreak@ \xyknottips@}
369 \xydef@\xykunderstring@{\xykprebreak@ \xykpostbreak@ \xyknottips@}

“cross” crossings: The initialisation…

381 \xydef@\vcross{\begingroup\def\afterknot@{\xyvcross}%
382 \def\xykprePLACE@{(.1)}\def\xykpostPLACE@{(.9)}%
383 \def\xykmidPLACE@{(.9)}\def\xykpostbreak@@{|\knothole}%
384 \xyFN@\xykparsecross@ }%
385 \xydef@\hcross{\begingroup\def\afterknot@{\xyhcross}%
386 \def\xykprePLACE@{(.1)}\def\xykpostPLACE@{(.9)}%
387 \def\xykmidPLACE@{(.9)}\def\xykpostbreak@@{|\knothole}%
388 \xyFN@\xykparsecross@ }%
389 \xydef@\vcrossneg{\begingroup\def\afterknot@{\xyvcrossneg}%
390 \def\xykprePLACE@{(.1)}\def\xykpostPLACE@{(.9)}%
391 \def\xykmidPLACE@{(.9)}\def\xykpostbreak@@{|\knothole}%
392 \xyFN@\xykparsecross@ }%
393 \xydef@\hcrossneg{\begingroup\def\afterknot@{\xyhcrossneg}%
394 \def\xykprePLACE@{(.1)}\def\xykpostPLACE@{(.9)}%
395 \def\xykmidPLACE@{(.9)}\def\xykpostbreak@@{|\knothole}%
396 \xyFN@\xykparsecross@ }%
397 \xydef@\vuncross{\begingroup\def\afterknot@{\xyvuncross}%
398 \def\xykprePLACE@{(.1)}\def\xykpostPLACE@{(.9)}%
399 \def\xykmidPLACE@{(.9)}\def\xykpostbreak@@{}%
400 \xyFN@\xykparsecross@ }%
401 \xydef@\huncross{\begingroup\def\afterknot@{\xyhuncross}%
402 \def\xykprePLACE@{(.1)}\def\xykpostPLACE@{(.9)}%
403 \def\xykmidPLACE@{(.9)}\def\xykpostbreak@@{}%
404 \xyFN@\xykparsecross@ }%

The interface…

410 \xydef@\xyvcross{\xykcross@\xykcrossv
411 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(0,-1)}}
413 \xydef@\xyhcross{\xykcross@\xykcrossh
414 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(1,0)}}
416 \xydef@\xyvcrossneg{\xykcross@\xykcrossv
417 \xykunderstring@ \xykoverstring@ \xykhvobject@{+(0,-1)}}
419 \xydef@\xyhcrossneg{\xykcross@\xykcrossh
420 \xykunderstring@ \xykoverstring@ \xykhvobject@{+(1,0)}}
422 \xydef@\xyvuncross{\xykcross@\xykuncrossv
423 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(0,-1)}}
425 \xydef@\xyhuncross{\xykcross@\xykuncrossh
426 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(1,0)}}

422 CHAPTER 3. FEATURES

The drawing code…

432 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,
433 "^<",{\xykz_\ar #1@'{"_<"**{}?(.25)@+,?+(.375,0)@+,
434 "_>";"^>"**{}?-(.375,0)@+,?(.25)@+}"_>"#3#4#5},
435 "_<",{\xykz^\ar #2@'{"^<"**{}?(.25)@+,?+(.375,0)@+,
436 "^>";"_>"**{}?-(.375,0)@+,?(.25)@+}"^>"#6#7#8}
437 \restore\POS #9}}
438 \xylet@\xykcrossv=\next
440 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,
441 "_<",{\xykz_\ar #1@'{"_>"**{}?(.25)@+,?+(0,.375)@+,
442 "^>";"^<"**{}?-(0,.375)@+,?(.25)@+}"^>"#3#4#5},
443 "_>",{\xykz^\ar #2@'{"_<"**{}?(.25)@+,?+(0,.375)@+,
444 "^<";"^>"**{}?-(0,.375)@+,?(.25)@+}"^<"#6#7#8}
445 \restore\POS #9}}
446 \xylet@\xykcrossh=\next
448 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,
449 "^<",{\xykz^\ar #1@'{"_<"**{}?(.25)@+,?(.375)+(.375,0)@+,
450 "^>";"_>"**{}?(.375)-(.375,0)@+,?(.25)@+}"^>"#3#4#5},
451 "_<",{\xykz^\ar #2@'{"^<"**{}?(.25)@+,?(.375)+(.375,0)@+,
452 "_>";"^>"**{}?(.375)-(.375,0)@+,?(.25)@+}"_>"#6#7#8}
453 \restore\POS #9}}
454 \xylet@\xykuncrossv=\next
456 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,
457 "_<",{\xykz^\ar #1@'{"_>"**{}?(.25)@+,?(.375)+(0,.375)@+,
458 "^<";"^>"**{}?(.375)-(0,.375)@+,?(.25)@+}"^<"#3#4#5},
459 "_>",{\xykz^\ar #2@'{"_<"**{}?(.25)@+,?(.375)+(0,.375)@+,
460 "^>";"^<"**{}?(.375)-(0,.375)@+,?(.25)@+}"^>"#6#7#8}
461 \restore\POS #9}}
462 \xylet@\xykuncrossh=\next

“over” crossings: The initialisation…

474 \xydef@\vover{\begingroup\def\afterknot@{\xyvover}%
475 \def\xykprePLACE@{(.2)}\def\xykpostPLACE@{(.9)}%
476 \def\xykmidPLACE@{(.8)}\def\xykpostbreak@@{|(.725)\knothole}%
477 \xyFN@\xykparsecross@ }%
479 \xydef@\hover{\begingroup\def\afterknot@{\xyhover}%
480 \def\xykprePLACE@{(.2)}\def\xykpostPLACE@{(.9)}%
481 \def\xykmidPLACE@{(.8)}\def\xykpostbreak@@{|(.725)\knothole}%
482 \xyFN@\xykparsecross@ }%
484 \xydef@\vunder{\begingroup\def\afterknot@{\xyvunder}%
485 \def\xykprePLACE@{(.1)}\def\xykpostPLACE@{(.8)}%
486 \def\xykmidPLACE@{(.2)}\def\xykpostbreak@@{|(.275)\knothole}%
487 \xyFN@\xykparsecross@ }%
489 \xydef@\hunder{\begingroup\def\afterknot@{\xyhunder}%

490 \def\xykprePLACE@{(.1)}\def\xykpostPLACE@{(.8)}%
491 \def\xykmidPLACE@{(.2)}\def\xykpostbreak@@{|(.275)\knothole}%
492 \xyFN@\xykparsecross@ }%
494 \xydef@\vunover{\begingroup\def\afterknot@{\xyvunover}%
495 \def\xykprePLACE@{(.1)}\def\xykpostPLACE@{(.9)}%
496 \def\xykmidPLACE@{(.8)}\def\xykpostbreak@@{}%
497 \xyFN@\xykparsecross@ }%
499 \xydef@\hunover{\begingroup\def\afterknot@{\xyhunover}%
500 \def\xykprePLACE@{(.1)}\def\xykpostPLACE@{(.9)}%
501 \def\xykmidPLACE@{(.8)}\def\xykpostbreak@@{}%
502 \xyFN@\xykparsecross@ }%
505 \xydef@\xoverv{\begingroup\def\afterknot@{\xyxoverv}%
506 \def\xykprePLACE@{(.15)}\def\xykpostPLACE@{(.85)}%
507 \def\xykmidPLACE@{(.15)}\def\xykpostbreak@@{|\knothole}%
508 \xyFN@\xykparsecross@ }%
510 \xydef@\xunderv{\begingroup\def\afterknot@{\xyxunderv}%
511 \def\xykprePLACE@{(.15)}\def\xykpostPLACE@{(.85)}%
512 \def\xykmidPLACE@{(.15)}\def\xykpostbreak@@{|\knothole}%
513 \xyFN@\xykparsecross@ }%
515 \xydef@\xoverh{\begingroup\def\afterknot@{\xyxoverh}%
516 \def\xykprePLACE@{(.15)}\def\xykpostPLACE@{(.85)}%
517 \def\xykmidPLACE@{(.15)}\def\xykpostbreak@@{|\knothole}%
518 \xyFN@\xykparsecross@ }%
520 \xydef@\xunderh{\begingroup\def\afterknot@{\xyxunderh}%
521 \def\xykprePLACE@{(.15)}\def\xykpostPLACE@{(.85)}%
522 \def\xykmidPLACE@{(.85)}\def\xykpostbreak@@{|\knothole}%
523 \xyFN@\xykparsecross@ }%
525 \xydef@\xunover{\begingroup\def\afterknot@{\xyxunover}%
526 \def\xykprePLACE@{(.15)}\def\xykpostPLACE@{(.85)}%
527 \def\xykmidPLACE@{(.15)}\def\xykpostbreak@@{}%
528 \xyFN@\xykparsecross@ }%
530 \xydef@\xunoverv{\begingroup\def\afterknot@{\xyxunoverv}%
531 \def\xykprePLACE@{(.2)}\def\xykpostPLACE@{(.8)}%
532 \def\xykmidPLACE@{(.2)}\def\xykpostbreak@@{}%
533 \xyFN@\xykparsecross@ }%
535 \xydef@\xunoverh{\begingroup\def\afterknot@{\xyxunoverh}%
536 \def\xykprePLACE@{(.2)}\def\xykpostPLACE@{(.8)}%
537 \def\xykmidPLACE@{(.8)}\def\xykpostbreak@@{}%
538 \xyFN@\xykparsecross@ }%

The interface…

544 \xydef@\xyvover{\xykcross@\xykoverv
545 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(0,-1)}}
547 \xydef@\xyhover{\xykcross@\xykoverh
548 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(1,0)}}

550 \xydef@\xyvunder{\xykcross@\xykoverv
551 \xykunderstring@ \xykoverstring@ \xykhvobject@{+(0,-1)}}
553 \xydef@\xyhunder{\xykcross@\xykoverh
554 \xykunderstring@ \xykoverstring@ \xykhvobject@{+(1,0)}}
556 \xydef@\xyvunover{\xykcross@\xykunoverv
557 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(0,-1)}}
559 \xydef@\xyhunover{\xykcross@\xykunoverh
560 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(1,0)}}
563 \xydef@\xyxoverv{\xykcross@\xykxoverv
564 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(0,-1)}}
566 \xydef@\xyxunderv{\xykcross@\xykxoverv
567 \xykunderstring@ \xykoverstring@ \xykhvobject@{+(0,-1)}}
569 \xydef@\xyxoverh{\xykcross@\xykxoverh
570 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(1,0)}}
572 \xydef@\xyxunderh{\xykcross@\xykxoverh
573 \xykunderstring@ \xykoverstring@ \xykhvobject@{+(1,0)}}
575 \xydef@\xyxunover{\xykcross@\xykxoverv
576 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(1,0)}}
578 \xydef@\xyxunoverv{\xykcross@\xykxunoverv
579 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(0,-1)}}
581 \xydef@\xyxunoverh{\xykcross@\xykxunoverh
582 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(1,0)}}

The drawing code…

589 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,
590 "^<",{\xykz^\ar #1@'{"^>"**{}?(.25)@+,?(.625)+(0,-.125)@+,
591 "_>";"^>"**{}?(.625)-(.125,0)@+,?(.25)@+}"_>"#3#4#5},
592 "_<",{\xykz^\ar #2@'{"^<"**{}?(.25)@+,?(.625)+(.125,0)@+,
593 "^>";"^<"**{}?(.625)-(0,.125)@+,?(.25)@+}"^>"#6#7#8},\restore\POS#9}}
594 \xylet@\xykoverv=\next
596 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,
597 "_<",{\xykz^\ar #1@'{"^<"**{}?(.25)@+,?(.625)+(.125,0)@+,
598 "^>";"^<"**{}?(.625)-(0,.125)@+,?(.25)@+}"^>"#3#4#5},
599 "_>",{\xykz^\ar #2@'{"_<"**{}?(.25)@+,?(.625)+(0,.125)@+,
600 "^<";"_<"**{}?(.625)+(.125,0)@+,?(.25)@+}"^<"#6#7#8},\restore\POS#9}}
601 \xylet@\xykoverh=\next
603 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,
604 "^<",{\xykz^\ar #1@'{"^>"**{}?(.25)@+,?-(0,.175)@+,?(.75)@+}
605 "^>"#3#4#5},
606 "_<",{\xykz^\ar #2@'{"^<"**{}?(.25)@+,?+(.125,0)@+,
607  "_>"**{}?+(0,.7)@+,"_>";"^>"**{}?-(.125,0)@+,?(.25)@+}
608 "_>"#6#7#8},\restore\POS#9}}
609 \xylet@\xykunoverv=\next
611 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,

3.10. KNOTS AND LINKS FEATURE 425

612 "_<",{\xykz^\ar #1@'{"^<"**{}?(.25)@+,?+(.175,0)@+,?(.75)@+}
613 "^<"#3#4#5},
614 "_>",{\xykz^\ar #2@'{"_<"**{}?(.25)@+,?+(0,.125)@+,
615  "^>"**{}?-(.7,0)@+,"^>";"^<"**{}?-(0,.125)@+,?(.25)@+}
616 "^>"#6#7#8},\restore\POS#9}}
617 \xylet@\xykunoverh=\next
619 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,
620 "^<";"^>"**{}?="^_","_<";"_>"**{}?;"^_",**{}?="^_",
621 "^>",{\xykz^\ar #1@'{"^_"@+}"_<"#3#4#5},
622 "^<",{\xykz_\ar #2@'{"^_"@+}"_>"#6#7#8},\restore\POS#9}}
623 \xylet@\xykxoverv=\next
625 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,
626 "^<";"_<"**{}?="^_","^>";"_>"**{}?;"^_",**{}?="^_",
627 "^<",{\xykz_\ar #1@'{"^_"@+}"_>"#3#4#5},
628 "_<",{\xykz_\ar #2@'{"^_"@+}"^>"#6#7#8},\restore\POS#9}}
629 \xylet@\xykxoverh=\next
631 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,
632 "^<";"^>"**{}?="^_","_<";"_>"**{}?;"^_",**{}?="^_",
633 "^>",{\xykz^\ar #1@'{"^_"@+}"_>"#3#4#5},
634 "^<",{\xykz^\ar #2@'{"^_"@+}"_<"#6#7#8},\restore\POS#9}}
635 \xylet@\xykxunoverv=\next
637 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,
638 "^<";"_<"**{}?="^_","^>";"_>"**{}?;"^_",**{}?="^_",
639 "^<",{\xykz^\ar #1@'{"^_"@+}"^>"#3#4#5},
640 "_<",{\xykz^\ar #2@'{"^_"@+}"_>"#6#7#8},
641 \restore\POS#9}}
642 \xylet@\xykxunoverh=\next

“twist” crossings: The initialisation…

654 \xydef@\vtwist{\begingroup\def\afterknot@{\xyvtwist}%
655 \def\xykprePLACE@{(.1)}\def\xykpostPLACE@{(.9)}%
656 \def\xykmidPLACE@{(.9)}\def\xykpostbreak@@{|\knothole}%
657 \xyFN@\xykparsecross@ }%
658 \xydef@\htwist{\begingroup\def\afterknot@{\xyhtwist}%
659 \def\xykprePLACE@{(.1)}\def\xykpostPLACE@{(.9)}%
660 \def\xykmidPLACE@{(.9)}\def\xykpostbreak@@{|\knothole}%
661 \xyFN@\xykparsecross@ }%
662 \xydef@\vtwistneg{\begingroup\def\afterknot@{\xyvtwistneg}%
663 \def\xykprePLACE@{(.1)}\def\xykpostPLACE@{(.9)}%
664 \def\xykmidPLACE@{(.9)}\def\xykpostbreak@@{|\knothole}%
665 \xyFN@\xykparsecross@ }%
666 \xydef@\htwistneg{\begingroup\def\afterknot@{\xyhtwistneg}%
667 \def\xykprePLACE@{(.1)}\def\xykpostPLACE@{(.9)}%
668 \def\xykmidPLACE@{(.9)}\def\xykpostbreak@@{|\knothole}%
669 \xyFN@\xykparsecross@ }%

670 \xydef@\vuntwist{\begingroup\def\afterknot@{\xyvuntwist}%
671 \def\xykprePLACE@{(.15)}\def\xykpostPLACE@{(.85)}%
672 \def\xykmidPLACE@{(.85)}\def\xykpostbreak@@{}%
673 \xyFN@\xykparsecross@ }%
674 \xydef@\huntwist{\begingroup\def\afterknot@{\xyhuntwist}%
675 \def\xykprePLACE@{(.15)}\def\xykpostPLACE@{(.85)}%
676 \def\xykmidPLACE@{(.85)}\def\xykpostbreak@@{}%
677 \xyFN@\xykparsecross@ }%

The interface…

683 \xydef@\xyvtwist{\xykcross@\xyktwistv
684 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(0,-1)}}
686 \xydef@\xyvtwistneg{\xykcross@\xyktwistv
687 \xykunderstring@ \xykoverstring@ \xykhvobject@{+(0,-1)}}
689 \xydef@\xyvuntwist{\xykcross@\xykuntwistv
690 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(0,-1)}}
692 \xydef@\xyhtwist{\xykcross@\xyktwisth
693 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(1,0)}}
695 \xydef@\xyhuntwist{\xykcross@\xykuntwisth
696 \xykoverstring@ \xykunderstring@ \xykhvobject@{+(1,0)}}
698 \xydef@\xyhtwistneg{\xykcross@\xyktwisth
699 \xykunderstring@ \xykoverstring@ \xykhvobject@{+(1,0)}}

The drawing code…

705 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,
706 "^>",{\xykz_\ar #1@'{"_>"**{}?(.25)@+,?-(.375,0)@+,
707 "_<";"^<"**{}?+(.375,0)@+,?(.25)@+}"_<"#3#4#5},
708 "^<",{\xykz^\ar #2@'{"_<"**{}?(.25)@+,?+(.375,0)@+,
709 "_>";"^>"**{}?+(-.375,0)@+,?(.25)@+}"_>"#6#7#8}
710 \restore\POS #9}}
711 \xylet@\xyktwistv=\next
713 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,
714 "^>",{\xykz^\ar #1@'{"_>"**{}?(.125)@+,?(.375)-(.25,0)@+,
715 ?(.625)-(.25,0)@+,?(.875)@+}"_>"#3#4#5},
716 "^<",{\xykz^\ar #2@'{"_<"**{}?(.125)@+,?(.375)+(.25,0)@+,
717 ?(.625)+(.25,0)@+,?(.875)@+}"_<"#6#7#8}
718 \restore\POS #9}}
719 \xylet@\xykuntwistv=\next
721 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,
722 "^<",{\xykz_\ar #1@'{"^>"**{}?(.25)@+,?+(0,-.375)@+,
723 "_>";"_<"**{}?+(0,.375)@+,?(.25)@+}"_>"#3#4#5},
724 "_<",{\xykz^\ar #2@'{"_>"**{}?(.25)@+,?+(0,.375)@+,
725 "^>";"^<"**{}?-(0,.375)@+,?(.25)@+}"^>"#6#7#8}
726 \restore\POS #9}}
727 \xylet@\xyktwisth=\next
729 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\save,
730 "^<",{\xykz^\ar #1@'{"^>",**{}?(.125)@+,?(.375)+(0,-.25)@+,

731 ?(.625)+(0,-.25)@+,?(.875)@+}"^>"#3#4#5},
732 "_<",{\xykz^\ar #2@'{"_>",**{}?(.125)@+,?(.375)+(0,.25)@+,
733 ?(.625)+(0,.25)@+,?(.875)@+}"_>"#6#7#8},\restore\POS #9}}
734 \xylet@\xykuntwisth=\next

3.10b. The above examples also show how to use - to get the mirror-image of a particular crossing. Any numerical scale factor can be used by enclosing it within [..] e.g. [2.3] scaling a single piece without affecting the rest of the picture. The scale-factor must occur before any label or arrow-tip specifiers, see below). Vertical crossings remain vertical under scalings; the current ⟨pos⟩ still moves by 1 coordinate unit in the ‘down’ direction. Similarly horizontal crossings remain horizontal. The single character - is a shorthand version for [-1], effectively giving a half-turn rotation in a rectangular basis.

754 \xydef@\xykparsescale@{%
755 \ifx\space@\next \expandafter\DN@\space{\xyFN@\xykparsescale@}%
756 \else\addDASH@\ifx\next \addDASH@\DN@{\def\xykSCALE@@{-1}%
757 \xyFN@\xykparser@}%
758 \else\ifx[\next \DN@[##1]{\dimen@=##1\p@
759 \ifdim\dimen@=\z@\xywarning@{\xykscaleerror@}%
760 \else\edef\xykSCALE@@{\expandafter\removePT@\the\dimen@}\fi
761 \xyFN@\xykparser@}%
762 \else\ifx~\next \DN@~##1##2##3##4{%
763 \def\xykSCALE@@{@{##1}{##2}{##3}{##4}}\xyFN@\xykparser@}%
764 \else\DN@{\xyFN@\xykparser@}%
765 \fi\fi\fi\fi \next@}
767 \xydef@\xykscaleerror@{Ignoring zero scale factor}

3.10c. A knot-piece need not be rectangular. By specifying ~⟨pos⟩_{1}⟨pos_{2}⟩⟨pos_{3}⟩⟨pos_{4}⟩ the four corners UL, UR, DL, DR are set to the given ⟨pos⟩s respectively. The local basis is established so that

r–hop ↔ \frac{1}{2}(⟨pos_{2}⟩ − ⟨pos_{1}⟩ + ⟨pos_{4}⟩ − ⟨pos_{3}⟩)
u–hop ↔ \frac{1}{2}(⟨pos_{1}⟩ − ⟨pos_{3}⟩ + ⟨pos_{2}⟩ − ⟨pos_{1}⟩) .

3.10d. With a non-rectangularly shaped piece it will usually be necessary to adjust the place where the ‘hole’ occurs in the ‘under’ string. This is done by specifying @(⟨num⟩), with 0 ≤ ⟨num⟩ ≤ 1 being the parameter value of the new location for the hole.

795 %\xydef@\xykobject@{%
796 % \ifx\xykSCALE@@\empty\DN@{\xykkeepscale@}%
797 % \else \DN@{\xyksavescale@{}}%
798 % \fi \next@ }
800 \xydef@\xykhobject@{\aftergroup\xykhadjust@
801 \ifx\xykSCALE@@\empty\DN@{\xykkeepscale@}%
802 \else \DN@{\xyksavescale@{}}%
803 \fi \next@ }
805 \xydef@\xykvobject@{\aftergroup\xykvadjust@
806 \ifx\xykSCALE@@\empty\DN@{\xykkeepscale@}%
807 \else \DN@{\xyksavescale@{}}%
808 \fi \next@ }

810 \xydef@\xykhvobject@{\aftergroup\xykhvadjust@
811 \ifx\xykSCALE@@\empty\DN@{\xykkeepscale@}%
812 \else \DN@{\xyksavescale@{}}%
813 \fi \next@ }
815 \xydef@\xykhuobject@{\aftergroup\xykhuadjust@
816 \ifx\xykSCALE@@\empty\DN@{\xykkeepscale@}%
817 \else \DN@{\xyksavescale@{}}%
818 \fi \next@ }
822 \xydef@\xyksavescale@#1#2{%
823 \expandafter\ifx\the\Edge@c\zeroEdge\relax \def\xyksaveEdgec{}%
824 \else
825 \edef\xyksaveEdgec{\noexpand\Edge@c={\expandafter\noexpand\the\Edge@c}%
826  \L@c=\the\L@c \R@c=\the\R@c \D@c=\the\D@c \U@c=\the\U@c}%
827 \fi

828 %

829 \edef\next@##1##2{\endgroup
830 \def\noexpand\xyksaveEdgec{}%
831 \def\noexpand\xykSCALE@@\noexpand{##1}%
832 \def\noexpand\xykjoincontrol\noexpand{\xykjoincontrol}%
833 \noexpand\toks@\noexpand{##2}%
834 \noexpand\xy@@{\def\noexpand\xyksaveEdgec{}%
835  \def\noexpand\xykSCALE@@{##1}%
836  \def\noexpand\xykjoincontrol{\xykjoincontrol}}}%
837 \expandafter\expandafter\expandafter\next@
838 \expandafter\expandafter\expandafter{\expandafter\xykSCALE@@\expandafter}%
839 \expandafter{\the\toks@}%

840 %

841 \xykrescale@ #1\the\toks@\restore\POS#2}
843 \xydef@\xykkeepscale@{%
844 \edef\next@##1{\endgroup \noexpand\toks@={##1}%
845 \def\noexpand\xykjoincontrol{\xykjoincontrol}}%
846 \expandafter\next@\expandafter{\the\toks@}%
847 \def\xykSCALE@@{}\def\xyksaveEdgec{}%
848 \xy@@{\def\xykSCALE@@{}\def\xyksaveEdgec{}}%
849 \edef\next@{\def\noexpand\xykjoincontrol{\xykjoincontrol}}%
850 \expandafter\xy@@\expandafter{\next@}%
851 \xyknoflexscale@ \the\toks@}
855 \xydef@\xykrescale@{\expandafter\xykcheckscale@\xykSCALE@@ !}%
857 \xydef@\xykcheckscale@#1#2!{%
858 \expandafter\DN@\expandafter{\codeof{#1}}%
859 \expandafter\DNii@\expandafter{\codeof{@}}%
860 \ifx\next@\nextii@\relax\DN@{\xykflexiscale@#2%
861 \xy@@{\divide\X@xbase2\divide\X@ybase2\divide\Y@xbase2\divide\Y@ybase2%
862 \def\xykSCALE@@{}}\def\xykSCALE@@{}%
863 \expandafter\toks@\expandafter{\afterFLEX@}}%
864 \else\DN@{\save \xykrescale@@}\fi \next@ }
866 \xydef@\xykflexiscale@{%

867 \expandafter\def\expandafter\afterFLEX@\expandafter{\the\toks@}%
868 \xykflexiscale@@ }
870 \xydef@\xykrescale@@{%
871 \edef\next@{\X@xbase=\xykSCALE@@\X@xbase \X@ybase=\xykSCALE@@\X@ybase
872 \Y@xbase=\xykSCALE@@\Y@xbase \Y@ybase=\xykSCALE@@\Y@ybase}%
873 \expandafter\xy@@\expandafter{\next@}%
874 \ifdim\xykSCALE@@\p@<\z@\relax \DN@{\xyknegflexscale@}%
875 \else\DN@{\xyknoflexscale@}\fi \next@ }
880 {\xyuncatcodes \gdef\next#1#2#3#4{\save="@",
881 #1,="^<",\POS"@",#2,="^>",\POS"@",#3,="_<",\POS"@",#4,="_>",
882 (0,0);"^>"-"^<"+"_>"-"_<":"^<"-"_<"+"^>"-"_>"::}}
883 \xylet@\xykflexiscale@@=\next
885 {\xyuncatcodes \gdef\next{\save ="^<",
886 +(1,0)="^>",-(1,1)="_<",+(1,0)="_>"\restore }}
887 \xylet@\xyknoflexscale@@=\next
888 \xylet@\xyknoflexscale@=\next
890 {\xyuncatcodes \gdef\next{\save ="_>",
891 +(-1,1)="^<",+(1,0)="^>",-(1,1)="_<"\restore }}
892 \xylet@\xyknegflexscale@@=\next
893 \xylet@\xyknegflexscale@=\next
895 {\xyuncatcodes \gdef\next{\save ="_<",
896 +(1,0)="_>",+(-1,1)="^<",+(1,0)="^>"\restore }}
897 \xylet@\xykhscale@@=\next
899 {\xyuncatcodes \gdef\next{\save ="^>",
900 -(1,0)="^<",+(1,-1)="_>",-(1,0)="_<"\restore }}
901 \xylet@\xykvscale@@=\next
906 \xydef@\xykhadjust@{%
907 \let\xyknoflexscale@=\xykhscale@@
908 \let\xyknegflexscale@=\xyknegflexscale@@ }
910 \xydef@\xykvadjust@{%
911 \let\xyknoflexscale@=\xyknoflexscale@@
912 \let\xyknegflexscale@=\xykhscale@@ }
914 \xydef@\xykhvadjust@{%
915 \let\xyknoflexscale@=\xyknoflexscale@@
916 \let\xyknegflexscale@=\xyknegflexscale@@ }
918 \xydef@\xykhuadjust@{%
919 \let\xyknoflexscale@=\xykhscale@@
920 \let\xyknegflexscale@=\xykvscale@@ }

3.10e. The knot feature allows for the easy placement of the following objects along the strings of a crossing:

• labels on the strings;

• arrowheads for direction or orientation;

• holes in strings, allowing another string to be drawn passing over.

3.10f. The characters <, > and | are used to indicate to which string portion the object is associated; with | denoting the string which crosses the other, while < and > denote the initial and final portions of the ‘crossed’ string.

945 \xydef@\xykprebreak@{%
946 \ifx\xykprebreak@@\empty\addtotoks@{{}}\else
947 \expandafter\addtotoks@\expandafter{\expandafter{\xykprebreak@@}}\fi}
949 \xydef@\xykpostbreak@{%
950 \ifx\xykpostbreak@@\empty\addtotoks@{{}}\else
951 \expandafter\addtotoks@\expandafter{\expandafter{\xykpostbreak@@}}\fi}
953 \xydef@\xykmidbreak@{%
954 \ifx\xykmidbreak@@\empty\addtotoks@{{}}\else
955 \expandafter\addtotoks@\expandafter{\expandafter{\xykmidbreak@@}}\fi}

3.10g. A simple label enclosed in braces, for example \vcross>{x}, is set in math-mode using the \labelstyle, at a pre-determined place on the string portion, shifted in either the ‘above’ or ‘below’ direction from the curve at this point. (For each crossing depicted in figure 3.8 only default values are used for the place and shift-direction.)

3.10h. If the first character within the braces {..} is * e.g. \htwist>{*⟨object⟩}, then a general ⟨object⟩ may be placed as a label. Furthermore if the first character is ^or _or |, then the interpretation is, e.g. \vtwist<{^⟨anchor⟩⟨it⟩}, as in 3.2 to place ⟨it⟩ as a label along an \ar of the arrow feature.

3.10i. A second character < or > specifies that an arrowhead should appear at the pre-determined place on the chosen string. Here > denotes an arrowhead pointing with the natural orientation, while < points against. Due to the curvature of the strings, it is usually best to \UseComputerModernTips rather than normal arrow-tips.

3.10j. To generate a ‘hole’ use \knothole, or simply \khole, as following token. This generates a ‘break’, in the sense of 3.3j. Indeed such a ‘hole’ is used to separate the two portions of the ‘crossed’ string. Default size for the hole is 5pt, which is alterable via \knotholesize{⟨dimen⟩}; normally used to set the size for all holes in a diagram.

3.10k. If the resulting \khole is either too large or perhaps non-existent, this could be due to a technicality in the way breaks in curves are handled. This problem should not occur with the standard crossings, using a rectangular basis, but it may occur with non-rectangular bases. An easy ‘fix’ is to include an extra null-break on the string, using <|, >| or ||, which should place the zero-sized break at parameter value .5 on the curve. The specification should precede a \khole at a higher parameter value, or come after one at a lower value.

The aim of the above ‘fix’ is to position the null-break as close as possible to where the curve is farthest from the line joining its end-points, which is usually at parameter value (.5).

1008 \xydef@\xykparsebreak@{%
1009 \ifx\space@\next \expandafter\DN@\space{\xyFN@\xykparsebreak@}%
1010 \else \addLT@\ifx\next
1011 \expandafter\appendtoholder@\xykbacktemp@\next@
1012 \addLT@\DN@{\xyFN@\xykparser@}%
1013 \else \addGT@\ifx\next
1014 \expandafter\appendtoholder@\xykforetemp@\next@
1015 \addGT@\DN@{\xyFN@\xykparser@}%

1016 \else \ifx|\next
1017 \expandafter\appendtoholer@\xyknulltemp@\next@
1018 \DN@|{\xyFN@\xykparser@}%
1019 \else \ifx\next \bgroup\DN@##1{\checkgroupbreak@##1@}%
1020 \else \ifx (\next\DN@(##1){\xyadjustknotPLACE@i##1@@%
1021 \xyFN@\xykparsebreak@}%
1022 \else \ifx\next \knothole@\DN@##1{\expandafter\appendtoholder@@
1023 \expandafter{\expandafter|\xyknotPLACE\knothole}\next@
1024 \xyFN@\xykparser@}%
1025 \else
1026 \expandafter\xykdefaultbreak@\xykbreak@\next@
1027 \DN@{\xyFN@\xykparser@}%
1028 \fi\fi\fi\fi\fi\fi\fi \next@ }

Templates for arrowheads.

1034 {\xyuncatcodes \gdef\next{^>*\dir{>}}}
1035 \xylet@\xykforetips@=\next
1037 {\xyuncatcodes \gdef\next{^<*\dir{<}}}
1038 \xylet@\xykbacktips@=\next
1040 {\xyuncatcodes \gdef\next{*!/-1pt/=0\dir{>}}}
1041 \xylet@\xykforetemp@=\next
1043 {\xyuncatcodes \gdef\next{*!/1pt/=0\dir{<}}}
1044 \xylet@\xykbacktemp@=\next
1046 {\xyuncatcodes \gdef\next{*=<\xykholesize>[o]{}}}
1047 \xylet@\xykholetemp@=\next
1048 \xydef@\knothole@{\hbox to\xykholesize{%
1049 \dimen@=\xykholesize \divide\dimen@\tw@
1050 \hfill \vrule height\dimen@ depth\dimen@ width\z@ }}
1051 \xylet@\knothole=\knothole@
1052 \xylet@\khole=\knothole@
1054 {\xyuncatcodes \gdef\next{*=<0pt>{}}}
1055 \xylet@\xyknulltemp@=\next
1056 \xylet@\xykbreak@=\xyknulltemp@

When the next token is a begin-group character { then look at the first token inside the group. If it is ^,_or | then the group contents will be an ⟨anchor⟩ for user-chosen places along the string. Otherwise the place is taken to be the already specified \xyknotPLACE and the group contains a label, to be set in the usual way for labels, using _due to the orientation of the curve. However if the first token is * then the user is assumed to be dropping his own label, possibly with ⟨object⟩ modifiers.

1069 \xydef@\checkgroupbreak@#1#2@{%
1070 \ifx|#1\DN@{\appendtoholder@@#1#2\next@ \xyFN@\xykparser@}%
1071 \else \ifx_#1\DN@{\appendtoholder@@_#2\next@ \xyFN@\xykparser@}%
1072 \else \ifx^#1\DN@{\appendtoholder@@^#2\next@ \xyFN@\xykparser@}%
1073 \else
1074 \def\next##1\next{\expandafter\DNii@\expandafter{\xyk@@##1}}%
1075 \expandafter\next\xyknotPLACE\next
1076 \ifx*#1%

1077 \expandafter\DN@\expandafter{%
1078  \expandafter\appendtoholder@@\nextii@#1#2\next@ \xyFN@\xykparser@}%
1079 \else %\expandafter\DNii@\expandafter{\expandafter\xyk@@\xyknotPLACE}%
1080 \expandafter\DN@\expandafter{%
1081  \expandafter\appendtoholder@@\nextii@{#1#2}\next@ \xyFN@\xykparser@}%
1082 \fi\fi\fi\fi \next@ }
1086 {\xyuncatcodes \gdef\next{%
1087 \expandafter{\expandafter^\xyknotPLACE##1}}}%
1088 \DN@{\xydef@\xykholder@@##1}\DNii@{\expandafter\toks@}%
1089 \expandafter\expandafter\expandafter\next@
1090 \expandafter\expandafter\expandafter{\expandafter\nextii@\next}
1092 \xydef@\appendtoholder@#1\next@{\xykholder@@{#1}%
1093 \DN@##1{\expandafter\DN@\expandafter{\xykholder@##1}}%
1094 \expandafter\next@\expandafter{\the\toks@}\appendtoholder@@@ }
1096 \xydef@\appendtoholder@@#1\next@{%
1097 \DN@##1\next@{\expandafter\DN@\expandafter{\xykholder@##1}}%
1098 \next@#1\next@ \appendtoholder@@@}%
1100 \xydef@\appendtoholder@@@{%
1101 \expandafter\expandafter\expandafter\DN@
1102 \expandafter\expandafter\expandafter{\next@}%
1103 \DNii@{\expandafter\def\xykholder@}%
1104 \expandafter\nextii@\expandafter{\next@}}
1109 {\xyuncatcodes \gdef\next{%
1110 \expandafter{\expandafter|\xyknotPLACE##1}}}%
1111 \DN@{\xydef@\xykholer@@##1}\DNii@{\expandafter\toks@}%
1112 \expandafter\expandafter\expandafter\next@
1113 \expandafter\expandafter\expandafter{\expandafter\nextii@\next}
1115 \xydef@\appendtoholer@#1\next@{\xykholer@@{#1}%
1116 \DN@##1{\expandafter\DN@\expandafter{\xykholder@##1}}%
1117 \expandafter\next@\expandafter{\the\toks@}\appendtoholder@@@ }

Multiple breaks, arrow-heads and labels may be specified along the two strings of a crossing; simply place their specifications one after another; e.g. <>|>>><{x}|{y}>{z} was used in figure 3.8.

The only proviso is that all ‘breaks’ along a single strand must occur with increasing order of parameter position. On the ‘crossed’ string this includes the automatic ‘hole’ to create space for the other string. Hence it is advisable to use just the (+..) and (-..) variants for small adjustments, and to keep these correctly ordered.

1136 \xydef@\xykz#1{\let\xyk@@=#1\xy@@{\let\xyk@@=#1}}
1137 {\xyuncatcodes \global\let\next=_}
1138 \xylet@\xyk@@=\next

Adjustment of position along the strings can be achieved using a ⟨factor⟩, as in \vover|(+.1)>. Allowed syntax is (⟨sign⟩⟨num⟩) where ⟨sign⟩ is + or - to increment or decrement from the predefined value. Also allowable are = or ⟨empty⟩ to set the parameter position to ⟨num⟩, which must lie between 0 and 1 to have any meaning.

This parses adjustments of the \xyknotPLACE.

1155 \xydef@\xyadjustknotPLACE@i{%
1156 \ifx\xyknotPLACE\empty\DN@{\dimen@=.5\p@}%
1157 \else\DN@{\expandafter\xygetknotPLACE@@\xyknotPLACE}%
1158 \fi \next@ \relax \let\xywhichknotPLACE@@=\xysetknotPLACE@@
1159 \xyFN@\xyadjustknotPLACE@}
1161 \xydef@\xyadjustknotPLACE@{\expandafter\ifx\space@\next
1162 \expandafter\DN@\space{\xyFN@\xyadjustknotPLACE@}%
1163 \else\addDASH@\ifx\next\DN@{\xyadjustknotPLACE@@}%
1164 \else\addPLUS@\ifx\next\DN@{\xyadjustknotPLACE@@}%
1165 \else\addEQ@\ifx\next\addEQ@\DN@{\dimen@=\z@ \xyadjustknotPLACE@@}%
1166 \else \DN@{\dimen@=\z@ \xyadjustknotPLACE@@}%
1167 \fi\fi\fi\fi \next@}
1169 \xydef@\xyadjustknotPLACE@@#1@@{\advance\dimen@#1\p@
1170 \expandafter\xysetknotPLACE@\expandafter{\the\dimen@}}
1172 \xydef@\xysetknotPLACE@#1{%
1173 \expandafter\xywhichknotPLACE@@\expandafter{\removePT@#1}}
1175 {\xyuncatcodes\gdef\next#1{\def\xyknotPLACE{(#1)}}}%
1176 \xylet@\xysetknotPLACE@@=\next
1178 {\xyuncatcodes \catcode`@=11
1179 \gdef\next(#1){\DN@\next@{#1}\ifx\next@\empty
1180 \dimen@=\z@\else\dimen@=#1\p@ \fi}}%
1181 \xylet@\xygetknotPLACE@@=\next

These use the same mechanism to adjust parameters stored in \xykpostbreak@@ and \xykjoincontrol@@.

1188 %\xydef@\xyadjustJOIN@i#1@@{\xykjoincontrol@i{#1}}%
1189 \xydef@\xyadjustJOIN@i{%
1190 \ifx\xykjoincontrol\empty\DN@{\dimen@=.75\p@}%
1191 \else\DN@{\expandafter\xygetknotPLACE@@\expandafter(\xykjoincontrol)}%
1192 \fi \next@ \relax \let\xywhichknotPLACE@@=\xysetjoincontrol@
1193 \xyFN@\xyadjustknotPLACE@}
1195 %\xydef@\xyadjustBREAK@i#1@@{\def\xykpostbreak@@{|(##1)\knothole}}%
1196 \xydef@\xyadjustBREAK@i{%
1197 \ifx\xykpostbreak@@\empty\DN@{\dimen@=.5\p@}%
1198 \else\DN@{\expandafter\xygetpostBREAK@\xykpostbreak@@}%
1199 \fi \next@ \relax \let\xywhichknotPLACE@@=\xysetpostbreak@
1200 \xyFN@\xyadjustknotPLACE@}
1202 \xydef@\xygetpostBREAK@|#1\knothole{\DN@{#1}%
1203 \ifx\next@\empty\dimen@=.5\p@\else \xygetknotPLACE@@#1\fi}
1205 \xydef@\xysetpostbreak@#1{\def\xykpostbreak@@{|(#1)\knothole}}
1206 \xydef@\xysetjoincontrol@#1{\edef\xykjoincontrol{#1}}

Arrowheads can also be placed at either, or both, ends of of the strings forming a crossing. This is governed by a pair of booleans, initially {FF}. It is changed for all subsequent strings in a diagram by \knottips{..} where the recognised values are {FF}, {FT}, {TF} and {TT}, denoting tips (T) or not (F) at the start and end of each string. To add arrowtips at the start of strings in a particular crossing, append the 2-character combination =< ; similarly => adds tips at the ends, if not already requested. The combinations == and =! specify both ({TT}) and none ({FF}) respectively. These 2-character pairs can be mixed in with any specifications for labels and breaks, etc. Multiple pairs compound their effect; in particular =<=> gives the same result as ==, while =!=< is needed to change {FT} into {TF}.

These are best used with single pieces, as in the following equation.

∇[ [figure] ] − ∇[ [figure] ] = −z ∇[ [figure] ]

   \UseComputerModernTips \knottips{FT}
   \def\Conway#1{\mathord{\nabla\Bigl[\,
    \raise5pt\xybox{0;/r1pc/:#1}\,\Bigr]}}
   $$
   \Conway\htwist - \Conway\htwistneg
    \;=\; -z\,\Conway\huntwist $$

1243 \xydef@\xykparsetips@{%
1244 \def\xyknotTIPS@@{}\def\xyknotPLACE{}%
1245 \let\xykparser@=\xykparsetips@@
1246 \xyFN@\xykparser@ }
1248 \xydef@\xykparsetips@@{%
1249 \ifx\space@\next \expandafter\DN@\space{\xyFN@\xykparsetips@@}%
1250 \else\addLT@\ifx\next
1251 \ifx\xyknotTIPS@@\empty \def\xyknotTIPS@@{TF}%
1252 \else\DN@{FF}\ifx\next@\xyknotTIPS@@ \def\xyknotTIPS@@{TF}%
1253 \else\DN@{FT}\ifx\next@\xyknotTIPS@@ \def\xyknotTIPS@@{TT}%
1254 \fi\fi\fi
1255 \addLT@\DN@{\xyFN@\xykparser@}%
1256 \else\addGT@\ifx\next
1257 \ifx\xyknotTIPS@@\empty \def\xyknotTIPS@@{FT}%
1258 \else\DN@{FF}\ifx\next@\xyknotTIPS@@ \def\xyknotTIPS@@{FT}%
1259 \else\DN@{TF}\ifx\next@\xyknotTIPS@@ \def\xyknotTIPS@@{TT}%
1260 \fi\fi\fi
1261 \addGT@\DN@{\xyFN@\xykparser@}%
1262 \else\addEQ@\ifx\next \def\xyknotTIPS@@{TT}%
1263 \addEQ@\DN@{\xyFN@\xykparser@}%
1264 \else \ifx!\next \def\xyknotTIPS@@{FF}\DN@!{\xyFN@\xykparser@}%
1265 \else\DN@{\xyFN@\xykparser@}%
1266 \fi\fi\fi\fi\fi \next@ }

This reads the setting for tips on string ends.

1272 \xydef@\xykcheckTIPS@{%
1273 \ifx\xyknotTIPS@@\empty \edef\xyknotTIPS@@{\xyknotTIPS@}\fi
1274  \DN@{FF}\ifx\next@\xyknotTIPS@@\def\tmp@{}%
1275 \else\DN@{FT}\ifx\next@\xyknotTIPS@@
1276 \expandafter\def\expandafter\tmp@\expandafter{\xykforetips@}%
1277 \else\DN@{TF}\ifx\next@\xyknotTIPS@@
1278 \expandafter\def\expandafter\tmp@\expandafter{\xykbacktips@}%
1279 \else
1280 \DN@##1\next@{\DN@{\xykforetips@##1}}%
1281 \expandafter\next@\xykbacktips@\next@

1282 \DNii@{\expandafter\def\expandafter\tmp@\expandafter}%
1283 \expandafter\nextii@\expandafter{\next@}%
1284 \fi\fi\fi \def\xyknotTIPS@@{}}
1286 \xydef@\xyknottips@{%
1287 \ifx\tmp@\empty\addtotoks@{{}}\else
1288 \expandafter\addtotoks@\expandafter{\expandafter{\tmp@}}\fi}

Joins

3.10l. The “joins” are used to connect the loose ends of crossing strings. In particular “loops” and “caps” are for placing on ends of horizontal or vertical ‘twist’ and ‘cross’ crossings, leaving the current ⟨pos⟩ fixed. The “bends” join non-adjacent crossings of the same type, either horizontal or vertical.

The \xcap.. pieces are designed to join adjacent \xover.. pieces; they move c either vertically or horizontally, as appropriate. Finally the \xbend.. pieces allow for smooth joins of 45^{∘} slopes to horizontal or vertical slopes. For these the actual positioning of the piece, see figure 3.9, is not entirely obvious.

Figure 3.9 displays the orientation on the joins. Also indicated are default positions for labels and arrow-tips; each piece uses the same code, e.g. \vloop <>|>>><{x}|{y}>{z}. Furthermore the current ⟨pos⟩ before the piece is drawn is marked using ^{∘}; that afterwards is indicated by [figure] or [figure].

The ability to scale in size and place arrow-tips, breaks, labels etc. apply also to ⟨join⟩ pieces. The only difference is…

3.10m. The three places referred to by < ,| ,> are all on a single string. In particular | is always at the middle of the ⟨join⟩, whereas < and > are at earlier and later parameter values respectively. Any adjustments3.10k involving breaks should occur in increasing parameter order.

Parsing

1391 \xydef@\xykparsejoin@{%
1392 \def\xykSCALE@@{}%
1393 \edef\xyknotPLACE{\xykmidPLACE@}%
1394 \let\xykparser@=\xykparsejoin@@
1395 \def\xykdefaultbreak@{\let\xykbreak@=\xykforetemp@
1396 \def\xyknotPLACE{(.5)}\appendtoholder@}%
1397 %  \edef\xyknotPLACE{\xykmidPLACE@}\appendtoholder@}%
1398 \xyFN@\xykparsescale@ }
1402 {\xyuncatcodes \catcode`@=11
1403 \gdef\next{%
1404 \ifx\space@\next \expandafter\DN@\space{\xyFN@\xykparsejoin@@}%
1405 \else\addLT@\ifx\next \let\xykbreak@=\xykbacktemp@
1406 \def\xykdefaultbreak@{\def\xyknotPLACE{(.5)}%
1407 %  \def\xykdefaultbreak@{\edef\xyknotPLACE{\xykmidPLACE@}%
1408 \appendtoholder@}\addLT@\DN@{\xyprecross@}%
1409 \else\addGT@\ifx\next \let\xykbreak@=\xykforetemp@
1410 \def\xykdefaultbreak@{\def\xyknotPLACE{(.5)}%
1411 %  \def\xykdefaultbreak@{\edef\xyknotPLACE{\xykmidPLACE@}%

1412 \appendtoholder@}\addGT@\DN@{\xypostcross@}%
1413 \else\ifx|\next \let\xykbreak@=\xyknulltemp@
1414 % \else\ifx|\next \let\xykbreak@=\xykholetemp@
1415 \def\xykdefaultbreak@{\def\xyknotPLACE{(.5)}%
1416 %  \def\xykdefaultbreak@{\edef\xyknotPLACE{\xykmidPLACE@}%
1417 \appendtoholer@}\DN@|{\xymidcross@}%
1418 \else\addEQ@\ifx\next \addEQ@\DN@{\xyFN@\xykparsetips@@}%
1419 % \else\addAT@\ifx\next \addAT@\DN@{\xykjoincontrol@}%
1420 \else\addAT@\ifx\next \addAT@\DN@(##1){%
1421 \xyadjustJOIN@i##1@@\xyFN@\xykparsejoin@@}%
1422 \else\DN@{\afterknot@}%
1423 \fi\fi\fi\fi\fi\fi \next@ }}
1424 \xylet@\xykparsejoin@@=\next

3.10n. A parameter can be altered, using @⟨adjust⟩, to effect subtle adjustments to the shape of any join. Within a rectangular basis the horizontal or vertical tangents are preserved and overall reflection or rotation symmetry is preserved. Thus this parameter affects the ‘flatness’ of a cap or loop, or the amount of curvature is s-bends and z-bends. For \xcap..s and \xbend..s the 45^{∘} angle is altered; this is especially useful to match the tangents when a knot-piece has been specified using the technique of note 3.10c.

The normal range for these parameters is between 0 and 1. Other values can be used with interesting results—the parameter determines the location of control points for a Bézier cubic curve.

piece  value effect on…
\..cap  .25 flatness of cap;
\..loop .75 flatness of loop;
\sbend.. .75 curvature in the ‘s’;
\zbend.. .75 curvature in the ‘z’;
\xcap..  .5 height of cap, slope at base;
\xbend.. .5 curvature, slope at base.

The following example gives three ways of specifying a ‘trefoil’ knot, using the poly feature to establish the location of the vertices for knot-pieces. In each the ⟨crossing⟩s are calculated to fit together smoothly; a different way of creating ⟨join⟩s is used in each. Also the third displays subtle changes of the 3.10njoin control.

\def\TrefoilA{\xygraph{!{0;/r.75pc/:}
 !P3"a"{~>{}}!P9"b"{~:{(1.3288,0):}~>{}}
 !P3"c"{~:{(2.5,0):}~>{}}
 !{\vover~{"b2"}{"b1"}{"a1"}{"a3"}}
 !{"b4";"b2"**\crv{"c1"}}
 !{\vover~{"b5"}{"b4"}{"a2"}{"a1"}}
 !{"b7";"b5"**\crv{"c2"}}
 !{\vover~{"b8"}{"b7"}{"a3"}{"a2"}}
 !{"b1";"b8"**\crv{"c3"}}}}

%
\def\TrefoilB{\xygraph{!{0;/r.75pc/:}
 !P3"a"{~>{}}!P9"b"{~:{(1.3288,0):}~>{}}
 !P3"c"{~:{(2.5,0):}~>{}}
 !{\vover~{"b2"}{"b1"}{"a1"}{"a3"}}
 !{\vcap~{"c1"}{"c1"}{"b4"}{"b2"}@(+.1)}
 !{\vover~{"b5"}{"b4"}{"a2"}{"a1"}}
 !{\vcap~{"c2"}{"c2"}{"b7"}{"b5"}@(+.2)}
 !{\vover~{"b8"}{"b7"}{"a3"}{"a2"}}
 !{\vcap~{"c3"}{"c3"}{"b1"}{"b8"}}}}
%
\def\TrefoilC{\xygraph{!{0;/r.75pc/:}
 !P3"a"{~>{}}
 !P12"b"{~:{(1.414,0):}~>{}}
 !{\vover~{"b2"}{"b1"}{"a1"}{"a3"}}
 !{\save 0;"b2"-"b5":"b5",
   \xcaph @(+.1)\restore}
 !{\vover~{"b6"}{"b5"}{"a2"}{"a1"}}
 !{\save 0;"b6"-"b9":"b9",
   \xcaph @(+.2)\restore}
 !{\vover~{"b10"}{"b9"}{"a3"}{"a2"}}
 !{\save 0;"b10"-"b1":"b1",
    \xcaph @(+.3)\restore} }}
$$\TrefoilA\quad\TrefoilB
   \quad\TrefoilC$$

1507 \xydef@\xykjoincontrol@@{.75}%
1508 \xydef@\xyk@joincontrol@#1{\DN@{#1}%
1509 \ifx\next@\empty\edef\xykjoincontrol@@{.75}%
1510 \else\dimen@=#1\p@
1511 \edef\xykjoincontrol@@{\expandafter\removePT@\the\dimen@}\fi}
1512 \xylet@\xykjoincontrol\empty %\xyk@joincontrol@
1514 \xydef@\xykjoincontrol@(#1){\DN@{#1}%
1515 \ifx\next@\empty\edef\xykjoincontrol{\xykjoincontrol@@}%
1516 \else\dimen@=#1\p@
1517 \edef\xykjoincontrol{\expandafter\removePT@\the\dimen@}%
1518 \fi \xyFN@\xykparsejoin@@ }
1520 \xydef@\xykjoincontrol@i#1{\DN@{#1}%
1521 \ifx\next@\empty\edef\xykjoincontrol{\xykjoincontrol@@}%
1522 \else\dimen@=#1\p@
1523 \edef\xykjoincontrol{\expandafter\removePT@\the\dimen@}\fi}

These macros are common to most joins.

1529 \xydef@\xykjoin@#1{%
1530 \expandafter\toks@\expandafter{\expandafter#1\knotSTYLE}}
1532 \xydef@\xyksetjoin@{\xykcheckTIPS@
1533 \xykprebreak@ \xykmidbreak@ \xykpostbreak@ \xyknottips@ }

438 CHAPTER 3. FEATURES “cap” joins: The initialisation…

1545 \xydef@\hcap{\begingroup\def\afterknot@{\xyhcap}%
1546 \def\xykprePLACE@{(.385)}\def\xykpostPLACE@{(.615)}%
1547 \def\xykmidPLACE@{(.5)}\edef\xykjoincontrol{.25}%
1548 \xyFN@\xykparsejoin@ }%
1549 \xydef@\vcap{\begingroup\def\afterknot@{\xyvcap}%
1550 \def\xykprePLACE@{(.385)}\def\xykpostPLACE@{(.615)}%
1551 \def\xykmidPLACE@{(.5)}\edef\xykjoincontrol{.25}%
1552 \xyFN@\xykparsejoin@ }%
1553 \xydef@\xcapv{\begingroup\def\afterknot@{\xyxcapv}%
1554 \def\xykprePLACE@{(.2)}\def\xykpostPLACE@{(.8)}%
1555 \def\xykmidPLACE@{(.5)}\edef\xykjoincontrol{.5}%
1556 \xyFN@\xykparsejoin@ }%
1557 \xydef@\xcaph{\begingroup\def\afterknot@{\xyxcaph}%
1558 \def\xykprePLACE@{(.2)}\def\xykpostPLACE@{(.8)}%
1559 \def\xykmidPLACE@{(.5)}\edef\xykjoincontrol{.5}%
1560 \xyFN@\xykparsejoin@ }%

The interface…

1566 \xydef@\xyvcap{\xykjoin@\xykcapv \xyksetjoin@ \xykhobject@{}}
1567 \xydef@\xyhcap{\xykjoin@\xykcaph \xyksetjoin@ \xykvobject@{}}
1568 \xydef@\xyxcapv{\xykjoin@\xykxcapv \xyksetjoin@ \xykvobject@{+(0,-1)}}
1569 \xydef@\xyxcaph{\xykjoin@\xykxcaph \xyksetjoin@ \xykhobject@{+(1,0)}}

The drawing code…

1575 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7{\save,
1576 "_>",{\xyksaveEdgec},{\xykz_\ar #1@'{"^>"**{}?(\xykjoincontrol)@+
1577 ,?-(.25,0)@+,"_<";"^<"**{}?+(.25,0)@+,?(\xykjoincontrol)@+}
1578 "_<"#3#4#5#6},\restore \POS#7}}
1579 \xylet@\xykcapv=\next
1581 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7{\save,
1582 "_<",{\xyksaveEdgec},{\xykz_\ar #1@'{"_>"**{}?(\xykjoincontrol)@+,
1583 ?+(0,.25)@+,"^<";"^>"**{}?-(0,.25)@+,?(\xykjoincontrol)@+}
1584 "^<"#3#4#5#6}
1585 \restore \POS#7}}
1586 \xylet@\xykcaph=\next
1588 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7{\save,
1589 "^>";"_>"**{}?="^_","^<";"_<"**{}?;"^_",**{}?(\xykjoincontrol)="^_",
1590 "_<",{\xyksaveEdgec},{\xykz_\ar #1@'{"^_"@+}
1591 "^<"#3#4#5#6},\restore \POS#7}}
1592 \xylet@\xykxcapv=\next
1594 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7{\save,
1595 "^<";"^>"**{}?="^_","_<";"_>"**{}?;"^_",**{}?(\xykjoincontrol)="^_",
1596 "_>",{\xyksaveEdgec},{\xykz_\ar #1@'{"^_"@+}
1597 "_<"#3#4#5#6},\restore \POS#7}}
1598 \xylet@\xykxcaph=\next

3.10. KNOTS AND LINKS FEATURE 439

“loop” joins: The initialisation and interface…

1608 \xydef@\hloop{\begingroup\def\afterknot@{\xyhloop}%
1609 \def\xykprePLACE@{(.07)}\def\xykpostPLACE@{(.93)}%
1610 \def\xykmidPLACE@{(.5)}\edef\xykjoincontrol{.75}%
1611 \xyFN@\xykparsejoin@ }%
1612 \xydef@\vloop{\begingroup\def\afterknot@{\xyvloop}%
1613 \def\xykprePLACE@{(.07)}\def\xykpostPLACE@{(.93)}%
1614 \def\xykmidPLACE@{(.5)}\edef\xykjoincontrol{.75}%
1615 \xyFN@\xykparsejoin@ }%
1617 \xydef@\xyvloop{\xykjoin@\xykloopv \xyksetjoin@ \xykhobject@{}}
1618 \xydef@\xyhloop{\xykjoin@\xyklooph \xyksetjoin@ \xykvobject@{}}

The drawing code…

1624 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7{\save,
1625 "_>",{\xykz_\ar #1@'{"^>"**{}?(\xykjoincontrol)@+,?(1.25)-(.25,0)@+,
1626 "_<";"^<"**{}?(1.25)+(.25,0)@+,?(\xykjoincontrol)@+}"_<"#3#4#5#6}
1627 \restore \POS#7}}
1628 \xylet@\xykloopv=\next
1630 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7{\save,
1631 "_<",{\xykz_\ar #1@'{"_>"**{}?(\xykjoincontrol)@+,?(1.25)+(0,.25)@+,
1632 "^<";"^>"**{}?(1.25)+(0,-.25)@+,?(\xykjoincontrol)@+}"^<"#3#4#5#6}
1633 \restore \POS#7}}
1634 \xylet@\xyklooph=\next

“bend” joins: The initialisation…

1644 \xydef@\zbendh{\begingroup\def\afterknot@{\xyzbendh}%
1645 \def\xykprePLACE@{(.25)}\def\xykpostPLACE@{(.75)}%
1646 \def\xykmidPLACE@{(.5)}\edef\xykjoincontrol{\xykjoincontrol@@}%
1647 \xyFN@\xykparsejoin@ }%
1648 \xydef@\sbendv{\begingroup\def\afterknot@{\xysbendv}%
1649 \def\xykprePLACE@{(.25)}\def\xykpostPLACE@{(.75)}%
1650 \def\xykmidPLACE@{(.5)}\edef\xykjoincontrol{\xykjoincontrol@@}%
1651 \xyFN@\xykparsejoin@ }%
1652 \xydef@\sbendh{\begingroup\def\afterknot@{\xysbendh}%
1653 \def\xykprePLACE@{(.25)}\def\xykpostPLACE@{(.75)}%
1654 \def\xykmidPLACE@{(.5)}\edef\xykjoincontrol{\xykjoincontrol@@}%
1655 \xyFN@\xykparsejoin@ }%
1656 \xydef@\zbendv{\begingroup\def\afterknot@{\xyzbendv}%
1657 \def\xykprePLACE@{(.25)}\def\xykpostPLACE@{(.75)}%
1658 \def\xykmidPLACE@{(.5)}\edef\xykjoincontrol{\xykjoincontrol@@}%
1659 \xyFN@\xykparsejoin@ }%
1662 \xydef@\xbendr{\begingroup\def\afterknot@{\xyxbendr}%
1663 \def\xykprePLACE@{(.15)}\def\xykpostPLACE@{(.75)}%
1664 \def\xykmidPLACE@{(.5)}\edef\xykjoincontrol{.5}%

1665 \xyFN@\xykparsejoin@ }%
1666 \xydef@\xbendl{\begingroup\def\afterknot@{\xyxbendl}%
1667 \def\xykprePLACE@{(.15)}\def\xykpostPLACE@{(.75)}%
1668 \def\xykmidPLACE@{(.5)}\edef\xykjoincontrol{.5}%
1669 \xyFN@\xykparsejoin@ }%
1670 \xydef@\xbendu{\begingroup\def\afterknot@{\xyxbendu}%
1671 \def\xykprePLACE@{(.15)}\def\xykpostPLACE@{(.75)}%
1672 \def\xykmidPLACE@{(.5)}\edef\xykjoincontrol{.5}%
1673 \xyFN@\xykparsejoin@ }%
1674 \xydef@\xbendd{\begingroup\def\afterknot@{\xyxbendd}%
1675 \def\xykprePLACE@{(.15)}\def\xykpostPLACE@{(.75)}%
1676 \def\xykmidPLACE@{(.5)}\edef\xykjoincontrol{.5}%
1677 \xyFN@\xykparsejoin@ }%

The interface…

1684 \xydef@\xyzbendh{\xykjoin@\xykzbendh \xyksetjoin@ \xykhvobject@{+(1,-1)}}
1685 \xydef@\xysbendv{\xykjoin@\xyksbendv \xyksetjoin@ \xykhvobject@{+(1,-1)}}
1686 \xydef@\xysbendh{\xykjoin@\xyksbendh \xyksetjoin@ \xykhuobject@{+(1,1)}}
1687 \xydef@\xyzbendv{\xykjoin@\xykzbendv \xyksetjoin@ \xykhuobject@{+(1,1)}}
1689 \xydef@\xyxbendr{\xykjoin@\xykxbendr \xyksetjoin@ \xykhvobject@{+(1,-1)}}
1690 \xydef@\xyxbendl{\xykjoin@\xykxbendl \xyksetjoin@ \xykhvobject@{+(0,-1)}}
1691 \xydef@\xyxbendu{\xykjoin@\xykxbendu \xyksetjoin@ \xykhvobject@{+(1,0)}}
1692 \xydef@\xyxbendd{\xykjoin@\xykxbendd \xyksetjoin@ \xykhvobject@{+(1,-1)}}

The implementation…

1699 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7{\save,
1700 "^<",{\xyksaveEdgec},
1701 {\xykz^\ar #1@'{"^>"**{}?(\xykjoincontrol)@+,
1702 "_>";"_<"**{}?(\xykjoincontrol)@+}"_>"#3#4#5#6}%
1703 \restore \POS#7}}
1704 \xylet@\xykzbendh=\next
1706 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7{\save,
1707 "^<",{\xyksaveEdgec},
1708 {\xykz_\ar #1@'{"_<"**{}?(\xykjoincontrol)@+,
1709 "_>";"^>"**{}?(\xykjoincontrol)@+}"_>"#3#4#5#6}%
1710 \restore \POS#7}}
1711 \xylet@\xyksbendv=\next
1713 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7{\save,
1714 "_<",{\xyksaveEdgec},
1715 {\xykz_\ar #1@'{"_>"**{}?(\xykjoincontrol)@+,
1716 "^>";"^<"**{}?(\xykjoincontrol)@+}"^>"#3#4#5#6}%
1717 \restore \POS#7}}
1718 \xylet@\xyksbendh=\next
1720 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7{\save,
1721 "_<",{\xyksaveEdgec},
1722 {\xykz^\ar #1@'{"^<"**{}?(\xykjoincontrol)@+,
1723 "^>";"_>"**{}?(\xykjoincontrol)@+}"^>"#3#4#5#6}%
1724 \restore \POS#7}}
1725 \xylet@\xykzbendv=\next

1728 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7{\save,
1729 "^<"-(0,.5),{\xyksaveEdgec},
1730 {\xykz_\ar #1@'{"_<";"_>"**{}?(\xykjoincontrol)@+,}"_>"#3#4#5#6}%
1731 \restore \POS#7}}
1732 \xylet@\xykxbendr=\next
1734 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7{\save,
1735 "^>"-(0,.5),{\xyksaveEdgec},
1736 {\xykz^\ar #1@'{"_>";"_<"**{}?(\xykjoincontrol)@+,}"_<"#3#4#5#6}%
1737 \restore \POS#7}}
1738 \xylet@\xykxbendl=\next
1740 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7{\save,
1741 "_<"+(.5,0),{\xyksaveEdgec},
1742 {\xykz_\ar #1@'{"_>";"^>"**{}?(\xykjoincontrol)@+,}"^>"#3#4#5#6}%
1743 \restore \POS#7}}
1744 \xylet@\xykxbendu=\next
1746 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7{\save,
1747 "^<"+(.5,0),{\xyksaveEdgec},
1748 {\xykz^\ar #1@'{"^>";"_>"**{}?(\xykjoincontrol)@+,}"_>"#3#4#5#6}%
1749 \restore \POS#7}}
1750 \xylet@\xykxbendd=\next

Changing the string-style

It is not necessary to use solid curves; any style available to curves and arrows can be chosen using…

        \knotstyle{⟨char⟩}  use \dir{⟨char⟩}

\knotstyles{⟨char⟩}{⟨char⟩} two styles
\knotSTYLE{⟨code⟩}  use ⟨code⟩

In each case the new style applies to all subsequent knot pieces, except that the two styles apply only to crossings. The latter case allows use of object ⟨modifier⟩s. The ⟨code⟩ consists of two groups {..}{..} , each containing ⟨arrow⟩ forms, as in 3.2 and notes 3.3m, 3.3r. Only the first ⟨arrow⟩ form is used with ⟨join⟩s whereas the two forms are used respectively with the two strings of a ⟨crossing⟩ in the order that they are drawn.

1780 {\xyuncatcodes \gdef\next{{@{-}}{@{-}}}}
1781 \xylet@\knotSTYLE=\next
1783 {\xyuncatcodes \gdef\next#1{\def\knotSTYLE{{@{#1}}{@{#1}}}}}
1784 \xylet@\knotstyle=\next
1786 {\xyuncatcodes \gdef\next#1#2{\def\knotSTYLE{{@{#1}}{@{#2}}}}}
1787 \xylet@\knotstyles=\next
1789 {\xyuncatcodes \gdef\next#1{\def\knotSTYLE{#1}}}
1790 \xylet@\KNOTstyle=\next

Initialisation: default values for the methods.

1798 \xydef@\knotholesize@#1{\def\xykholesize{#1}}
1799 \xydef@\xykholesize{5pt}

1800 \xylet@\knotholesize=\knotholesize@
1801 \xylet@\holesize=\knotholesize@
1803 \xydef@\knottips#1{\def\xyknotTIPS@{#1}}
1804 \xydef@\xyknotTIPS@{FF}
1805 \xydef@\xyknotTIPS@@{}
1807 \xydef@\xykSCALE@@{}
1809 %\xydef@\xyknotbreak@@{}%
1810 \xydef@\xykprebreak@@{}%
1811 \xydef@\xykpostbreak@@{}%
1812 \xydef@\xykmidbreak@@{}%
1814 \xydef@\xykprePLACE@{(.25)}%
1815 \xydef@\xykpostPLACE@{(.75)}%
1816 \xydef@\xykmidPLACE@{}%
1817 \xylet@\xykPLACE@=\xykmidPLACE@
1829 {\gdef\next#1#2#3#4{%\message{#1:#2:#3:#4}%
1830 \save(0,0);"#2"-"#1"+"#4"-"#3":(.5,0):
1831 "#3"-"#1"+"#4"-"#2"::(0,.5)::}}
1832 \xylet@\xykflexbase@=\next
1833 \xylet@\xykflexbase=\xykflexbase@
1837 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8{\xykflexbase{#1}{#2}{#3}{#4}%
1838 % \save(0,0);"#2"-"#1"+"#4"-"#3":(.5,0):
1839 % "#3"-"#1"+"#4"-"#2"::(0,.5)::
1840 "#1",{\ar @{#5}@'{"#1"+(0,.125)@++(.1875,.125)@+,
1841 "#4"-(.1875,.25)@++(.1875,.125)@+}"#4" #6},
1842 "#2",{\ar @{#5}@'{"#2"+(0,.125)@++(-.1875,.125)@+,
1843 "#3"+(.1875,-.25)@++(-.1875,.125)@+}"#3" #7}%
1844 \restore \POS#8}}
1845 \xylet@\Xtwist=\next
1847 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8{\xykflexbase{#1}{#2}{#3}{#4}%
1848 % \save(0,0);"#2"-"#1"+"#4"-"#3":(.5,0):
1849 % "#3"-"#1"+"#4"-"#2"::(0,.5)::
1850 "#1",{\ar @{#5}@'{"#1"+(0,.0625)@++(.1875,.0625)@+,
1851 "#3"+(.1875,-.125)@++(-.1875,.0625)@+}"#3" #6},
1852 "#2",{\ar @{#5}@'{"#2"+(0,.0625)@++(-.1875,.0625)@+,
1853 "#4"-(.1875,.125)@++(.1875,.0625)@+}"#4" #7}%
1854 \restore \POS#8}}
1855 \xylet@\Xuntwist=\next
1862 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\xykflexbase{#1}{#2}{#3}{#4}%
1863 % \save(0,0);"#2"-"#1"+"#4"-"#3":(.5,0):
1864 % "#3"-"#1"+"#4"-"#2"::(0,.5)::
1865 "#1",{\ar @{#5}@'{"#1"+(.1875,.0625)@++(.1875,.1875)@+,
1866 "#4"+(-#9,-.125)@+}"#4" #6},
1867 "#2",{\ar @{#5}@'{"#2"+(-.1875,.0625)@++(-.1875,.1875)@+,
1868 "#3"+(#9,-.125)@+}"#3" #7}%
1869 \restore \POS#8}}

1870 \xylet@\Xover=\next
1872 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{\xykflexbase{#1}{#2}{#3}{#4}%
1873 % \save(0,0);"#2"-"#1"+"#4"-"#3":(.5,0):
1874 % "#3"-"#1"+"#4"-"#2"::(0,.5)::
1875 "#1",{\ar @{#5}@'{"#1"+(.1875,.0625)@++(.1875,.1875)@+,
1876 "#2"+(-.1875,.0625)@+}"#2" #6},
1877 % "#3"+(#9,-.125)@+}"#3" #6},
1878 "#3",{\ar @{#5}@'{"#3"+(#9,-.125)@+,"#3"+(.25,-.25)@+,
1879 % "#2",{\ar @{#5}@'{"#2"+(-.1875,.0625)@++(-.1875,.1875)@+,
1880 "#4"+(-#9,-.125)@+}"#4" #7}%
1881 \restore \POS#8}}
1882 \xylet@\Xunover=\next
1889 {\xyuncatcodes \gdef\next#1#2#3#4#5#6#7{\xykflexbase{#1}{#2}{#3}{#4}%
1890 % \save(0,0);"#2"-"#1"+"#3"-"#4":(.5,0):
1891 % "#4"-"#1"+"#3"-"#2"::(0,.5)::
1892 "#1",{\ar @{#5}@'{"#1"+(0,.125)@++(.125,.25)@+,
1893 "#4"+(-.125,.375)@++(.125,-.25)@+}"#4" #6},
1894 \restore \POS#7}}
1895 \xylet@\Xcap=\next
1902 {\xyuncatcodes \catcode`@=11
1903 \gdef\next#1#2#3#4#5#6#7#8#9{\dimen@=#1\p@
1904 \ifdim\dimen@=\z@ \DN@{\Xunover{#2}{#3}{#4}{#5}{#8}{#6}{#7}{"#5"}}%
1905 \else\ifdim\dimen@>\z@
1906 \DNii@{#6}\ifx\nextii@\empty
1907  \DN@{\Xover{#2}{#3}{#4}{#5}{#8}{|(.45)\knothole}{#7}{"#5"}}%
1908 \else \DN@{\Xover{#2}{#3}{#4}{#5}{#8}{#6}{#7}{"#5"}}\fi
1909 \else
1910 \DNii@{#7}\ifx\nextii@\empty
1911 \DN@{\Xover{#2}{#3}{#4}{#5}{#8}{#6}{|(.45)\knothole}{"#5"}}%
1912 \else\DN@{\Xover{#2}{#3}{#4}{#5}{#8}{#6}{#7}{"#5"}}\fi
1913 \fi\fi
1914 \def\tmp@{{#9}}\ifx\tmp@\empty\def\tmp@{{0}}\else\dimen@=#9\p@\fi
1915 \expandafter\next@\tmp@ }}
1916 \xylet@\XXover=\next
1918 {\xyuncatcodes \catcode`@=11
1919 \gdef\next#1#2#3#4#5#6#7#8{\dimen@=#1\p@
1920 \ifdim\dimen@=\z@ \DN@{\Xuntwist{#2}{#4}{#3}{#5}{#8}{#6}{#7}{"#5"}}%
1921 \else\ifdim\dimen@>\z@
1922 \DNii@{#6}\ifx\nextii@\empty
1923  \DN@{\Xtwist{#2}{#4}{#3}{#5}{#8}{|(.45)\knothole}{#7}{"#5"}}%
1924 \else \DN@{\Xtwist{#2}{#4}{#3}{#5}{#8}{#6}{#7}{"#5"}}\fi
1925 \else
1926 \DNii@{#7}\ifx\nextii@\empty
1927 \DN@{\Xtwist{#2}{#4}{#3}{#5}{#8}{#6}{|(.45)\knothole}{"#5"}}%
1928 \else\DN@{\Xtwist{#2}{#4}{#3}{#5}{#8}{#6}{#7}{"#5"}}\fi
1929 \fi\fi \next@ }}
1930 \xylet@\XXtwist=\next

444 CHAPTER 3. FEATURES

simplified switch-like interface

1941 {\xyuncatcodes \catcode`@=11
1942 \gdef\next#1#2#3#4{\dimen@=#1\p@
1943 \ifdim\dimen@=\z@ \DN@{\xykuncrossv{#4}{#2}{#3}{+(0,-1)}}%
1944 \else\ifdim\dimen@>\z@
1945 \DNii@{#2}\ifx\nextii@\empty
1946  \DN@{\xyktwistv{#4}{|\knothole}{#3}{+(1,0)}}%
1947 \else \DN@{\xyktwistv{#4}{#2}{#3}{+(1,0)}}\fi
1948 \else
1949 \DNii@{#3}\ifx\nextii@\empty
1950 \DN@{\xyktwistv{#4}{#2}{|\knothole}{+(0,-1)}}%
1951 \else\DN@{\xyktwistv{#4}{#2}{#3}{+(0,-1)}}\fi
1952 \fi\fi \next@ }}
1953 \xylet@\Vcross=\next
1955 {\xyuncatcodes \catcode`@=11
1956 \gdef\next#1#2#3#4{\dimen@=#1\p@
1957 \ifdim\dimen@=\z@ \DN@{\xykuncrossh{#4}{#2}{#3}{+(0,-1)}}%
1958 \else\ifdim\dimen@<\z@
1959 \DNii@{#2}\ifx\nextii@\empty
1960  \DN@{\xyktwisth{#4}{|\knothole}{#3}{+(1,0)}}%
1961 \else \DN@{\xyktwisth{#4}{#2}{#3}{+(1,0)}}\fi
1962 \else
1963 \DNii@{#3}\ifx\nextii@\empty
1964 \DN@{\xyktwisth{#4}{}{|\knothole}{+(1,0)}}%
1965 \else\DN@{\xyktwisth{#4}{#2}{#3}{+(1,0)}}\fi
1966 \fi\fi \next@ }}
1967 \xylet@\Hcross=\next
1969 {\xyuncatcodes \catcode`@=11
1970 \gdef\next#1#2#3{\dimen@=#1\p@ \save
1971 \ifdim\dimen@<\z@
1972 \DN@{\POS="@",p="@@",(0,0);(-1,0):(0,-1)::"@@";"@",}%
1973 \else\DN@{}\fi
1974 \next@ \xykcaph{#3}{#2}\restore }}
1975 \xylet@\Hcap=\next
1977 {\xyuncatcodes \catcode`@=11
1978 \gdef\next#1#2#3{\dimen@=#1\p@ \save
1979 \ifdim\dimen@<\z@
1980 \DN@{\POS="@",p="@@",(0,0);(0,-1)::"@@";"@",}%
1981 \else\DN@{}\fi
1982 \next@ \xykcapv{#3}{#2}\restore }}
1983 \xylet@\Vcap=\next

The end & Log

1995 \xyendinput
1997 % $Log: xyknot.doc,v $
1998 % Revision 3.4  1997/05/18 01:13:24  ross
1999 % Essential bugfixes.

3.11. SMART PATH OPTION 445

2000 %

2001 % Revision 3.3  1996/12/18  09:20:49  ross
2002 % no changes

2003 %

2004 % Revision 3.1  1995/09/05 20:36:33  ross
2005 % Release!

2006 %

2007 % Revision 3.0  1995/07/07  20:13:19  ross
2008 % Major release w/new User's Guide!

2009 %

2010 % Revision 2.13  1995/07/04  15:04:51  ross
2011 % Ready for release of v3.

2012 %

2013 % Created by Ross Moore, September 1994.

3.11 Smart Path option

Vers. 0.0 by George C. Necula ⟨necula@cs.cmu.edu⟩

Header:

1 %% $Id$
2 %%
3 %% Xy-pic ``Smart Path feature'' option.
4 %% Copyright (c) 1998          George C. Necula <necula@cs.cmu.edu>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1998  Kristoffer H. Rose  <krisrose@ens-lyon.fr>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{smartpath}{Smart Path option}{\stripRCS$Revision: 0.0 $}%
27 {George C. Necula}{necula@cs.cmu.edu}%
28 {School of Computer Science,
29  Carnegie Mellon University,

30  5000 Forbes Avenue,
31  Pittsburgh, PA 15213-3891, USA}

This extends the ‘arrow’ feature, which is therefore required, with a “smart” ⟨path⟩ between two ⟨pos⟩itions.

44 \xyrequire{arrow}\xycatcodes

The ⟨turn⟩ syntax is extended with the construction

⟨turn⟩ ⟶`s ⟨diag⟩ _⟨diag⟩ ⟨turnradius⟩

\arin_out/5pt which draws a connector leaving p in the in ⟨diag⟩onal direction and arrives at c in the out ⟨diag⟩onal direction, using 5pt turns. The connector contains only horizontal or vertical lines and \frac{1}{8} sectors of circles of the given (optional) ⟨turnradius⟩.

Bug: Any labels are placed at the end of the connection.

67 % The smart connection algorithm is as follows:

68 %

69 % A smart connector consists only of horizontal and vertical straight
70 % segments connected with 1/4 circles. 1/8 circles might be use at the start
71 % and end of the connector to reach a horizontal or a vertical.

72 %

73 % All possible connectors can be reduced to a series of equivalence classes,
74 % where two connectors are considered equivalent if they are identical after
75 % removing from each of them all the horizontal and vertical straight
76 % segments. Such a connector is called a representative.

77 %

78 % The algorithm first computes 10 representatives that start and end in the
79 % given directions and have at most one point where the orientation is
80 % changed. 5 of the representatives start counter-clockwise and the other
81 % 5 start clockwise. Among the counter-clockwise representatives, 1 does not
82 % have any change in orientation (one arc of circle starting and ending in the
83 % given directions). The other 4 are obtained by changing the orientation in
84 % the four points where the circle is tangent to a horizontal or a vertical.

85 %

86 % For each representative the algorithm determines if it can be extended with
87 % horizontal and vertical segments to reach the destination point when
88 % starting in the source point (the directions are already right by
89 % construction). For example, horizontal straight lines could be inserted
90 % in all the points where the representative is tangent to a horizontal line.
91 % In each such point a straight line segment can be inserted to extend the
92 % connector horizontally but only in the same direction of the connector at
93 % that point (the direction of the connetor in a point is towards the
94 % destination). For example, if the horizontal distance between the source and
95 % destination points is Dx and the horizontal distance between the start and
96 % the end of the representative connector is dx then the distance ``Dx - dx''
97 % must be covered using horizontal straight lines. This distance is
98 % distributed equally among all the horizontal extension points of the right
99 % direction. If no such points exist, then the representative is discarded.
100 % The cost of a connector is the length of the representative plus the total
101 % length of straight extension segments, i.e., |Dx-dx| + |Dy-dy|.

102 %

103 % The algorithm selects among all the representatives that are not discarded,
104 % the one leading to the shortest connection.
107 % Change the PATHturn@ to recognize `s as a smart PATH.
108 \let\origPATHturn@=\PATHturn@
109 \def\PATHturn@{%
110 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PATHturn@}%gobble spaces
111 \else\ifx s\next
112  \let\origPATHturn@i=\PATHturn@i\let\PATHturn@i=\PATHsmartturn@i
113  \let\origPATHturn@cir=\PATHturn@cir\let\PATHturn@cir=\PATHsmartturn@cir
114  \DN@ s{\xyFN@\origPATHturn@}% Let the original routines do the parsing
115 \else
116  \DN@{\origPATHturn@}%
117 \fi\fi
118 \next@}
121 % Changed PATHturn@cir to allow half or full turns
122 \xydef@\PATHsmartturn@cir{%
123 \edef\next@{{\CIRin@@}{\expandafter\noexpand\CIRorient@@}{\CIRout@@}}%
124 \expandafter\PATHturn@i\next@}
127 % This is the changed function for placing the turn
128 \xydef@\PATHsmartturn@i#1#2#3{%
129 \DN@##1{%
130  \def\PATHinit@@{%
131  \xy@@{%
132  \def\sm@CIRin{#1}\def\sm@CIRout{#3}% The IN and OUT directions. Ignore
133  % the orientation
134  \ifx\sm@CIRout\empty %Only on direction is given. Use it as OUT and
135  %use the previous direction as IN
136  \let\sm@CIRout=\sm@CIRin
137  \let\sm@CIRin=\PATHlastout@@
138  \fi
139  ##1\relax}%
140  \xy@@{\enter@{\basefromthebase@}}%
141  \xy@@{\sm@conn}% Draw the connection
142  \xy@@{\X@p=\X@c \Y@p=\Y@c \czeroEdge@% Save the start of the segment
143  \count@=\sm@CIRout\count@=\the\count@% Move forward a dash to
144  % touch the edge
145  \dimen@=\xydashl@ \ABfromdiag@ \advance\X@c\A@ \advance\Y@c\B@
146  \edef\PATHpostpos@@{\X@c=\the\X@c \Y@c=\the\Y@c \noexpand\czeroEdge@
147  \noexpand\PATHomitslide@@true}}%
148  \xy@@{\leave@ %
149  \edef\PATHlastout@@{\sm@CIRout}% Store the last direction
150  \count@=\sm@CIRout \dimen@=\xydashl@ \Directionfromdiag@}}}%
151 \expandafter\next@\expandafter{\the\toks@}\toks@={}%
152 \let\PATHextra@@=\empty
153 \def\PATHpost@@{\xy@@\PATHpostpos@@}%
154 \let\PATHlabelsextra@@=\relax

155 \let\PATHturn@i=\origPATHturn@i
156 \let\PATHturn@cir=\origPATHturn@cir
157 \xyFN@\PATHturn@ii}
160 \xydef@\sm@nil{}
161 \xydef@\sm@nnil{\sm@nil}
162 \xydef@\sm@maxcost{1000mm}% A very long connector
164 % This computes and draws the connection
165 \xydef@\sm@conn{
166 %  \xy@showthe p{Source}\xy@showthe c{Dest}%
167 %  \W@{Computing connector from p in \sm@CIRin\space to c in \sm@CIRout
168 %      .Radius is \turnradius@}%
169 %Adjust the end points to the edge of the objects in the given directions
170 \enter@{\cfromthec@ \DirectionfromtheDirection@}\cfromp@% Adjust p
171 \count@=\sm@CIRin\count@=\the\count@
172 \dimen@=\xydashl@ \ABfromdiag@ \advance\X@p\A@\advance\Y@p\B@
173 \setupDirection@ \the\Edge@c\z@ \czeroEdge@
174 \pfromc@
175 \reverseDirection@
176 % Now leave room for one dash to start with (for placing arrow tails)
177 \count@=\sm@CIRin\count@=\the\count@
178 \dimen@=\xydashl@ \ABfromdiag@
179 % Drop the arrow tail in the right place
180 \edef\tmp@{\noexpand\dir\artail@@}\expandafter\sm@drop@\tmp@
181 \X@c=\X@p\advance\X@c\A@ \Y@c=\Y@p\advance\Y@c\B@ \czeroEdge@
182 % Draw a straight connection from p to c
183 \sm@stri
184 % Set p to the end of the connection
185 \X@p=\X@c \Y@p=\Y@c
186 \leave@
187 %  \xy@showthe p{After adjust}%
188 \enter@{\pfromthep@ \DirectionfromtheDirection@}\pfromc@% Adjust c
189 \count@=\sm@CIRout\count@=\the\count@
190 \dimen@=\xydashl@ \ABfromdiag@ \advance\X@p-\A@\advance\Y@p-\B@
191 \setupDirection@ \the\Edge@c\z@
192 \advance\X@c-\A@\advance\Y@c-\B@% Leave room for a dash to terminate the seg
193 \czeroEdge@                % The final segment will be drawn by PATH@segment
194 % Clear the tail setting for the last segment
195 \def\PATHlabelsnext@@{}%
196 \leave@
197 %  \xy@showthe c{After adjust}%
198 % Set the turn radius
199 \R@=\turnradius@
200 \cirrestrict@@%Adjust the radius to fit the circles
201 % Initialize variables
202 \let\sm@circles=\sm@nil
203 \edef\sm@bestcost{\sm@maxcost}% Best so far is very bad
204 \sm@trycircles  1%Try counter clockwise first
205 \sm@trycircles{-1}%Try clockwise after

206 %

207 % Now check the best

208 %

209 \ifdim\sm@bestcost<\sm@maxcost
210 %    \W@{}\W@{Best: \meaning\sm@bestconn}%
211  \cfromp@
212 %    \xy@showthe p{Source}%
213  \expandafter\sm@conndraw\sm@bestconn
214 \else
215  \xyerror@{Cannot draw the smart connector}{}%
216 \fi

217 }

219 % Compute and examine 5 representatives, for the orientation given
220 % as #1 (1 for counter-clockwise and -1 for clockwise).
221 \xydef@\sm@trycircles#1{%
222 \ifnum #1>0% Compute the opposite orientation
223  \def\sm@CIRorienti{-1}%
224 \else
225  \def\sm@CIRorienti{1}%
226 \fi
227 % Generate lists of triples (IN,ORIENT,OUT) so that OUT_1=IN_2 and
228 % IN=IN_1 and OUT=OUT_2, and such that ORIENT_1=#1m ORIENT_2=-ORIENT_1
229 % Then try each list in turn.
230 %Try one circle first (a singleton list)
231 \edef\tmp@{{{\sm@CIRin}{#1}{\sm@CIRout}}}%
232 \expandafter\sm@trycirclelist\expandafter{\tmp@\sm@nil}%
233 %Now try lists of two circles.
234 %Advance "in" so that it is a multiple of 90 degrees (that is, odd)
235 \count@@=\sm@CIRin\count@@=\the\count@@\count@=\count@@
236 \sm@roundcount@{#1}%
237 \edef\sm@savecount@{\the\count@}%
238 % See if we need to add a 1/8 starting circle
239 \ifnum\the\count@=\the\count@@ \else

240 %

241  \edef\tmp@{{{\sm@CIRin}{#1}{\the\count@}}%
242  {{\the\count@}{\sm@CIRorienti}{\sm@CIRout}}}%
243  \expandafter\sm@trycirclelist\expandafter{\tmp@\sm@nil}%
244 \fi

245 %

246 \count@=\sm@savecount@\count@=\the\count@
247 \sm@advancecount@ 2{#1}\edef\sm@savecount@{\the\count@}% Advance 90 deg.
248 \edef\tmp@{{{\sm@CIRin}{#1}{\the\count@}}%
249  {{\the\count@}{\sm@CIRorienti}{\sm@CIRout}}}%
250 \expandafter\sm@trycirclelist\expandafter{\tmp@\sm@nil}%

251 %

252 \count@=\sm@savecount@\count@=\the\count@
253 \sm@advancecount@ 2{#1}\edef\sm@savecount@{\the\count@}% Advance 90 deg.
254 \edef\tmp@{{{\sm@CIRin}{#1}{\the\count@}}%
255  {{\the\count@}{\sm@CIRorienti}{\sm@CIRout}}}%

256 \expandafter\sm@trycirclelist\expandafter{\tmp@\sm@nil}%

257 %

258 \count@=\sm@savecount@\count@=\the\count@
259 \sm@advancecount@ 2{#1}\edef\sm@savecount@{\the\count@}% Advance 90 deg.
260 \edef\tmp@{{{\sm@CIRin}{#1}{\the\count@}}%
261  {{\the\count@}{\sm@CIRorienti}{\sm@CIRout}}}%
262 \expandafter\sm@trycirclelist\expandafter{\tmp@\sm@nil}%

263 }

265 % Advance the direction in \count@ by #1 (each unit is 45deg) in the
266 % dirction #2, taking care of wrap-around
267 \xydef@\sm@advancecount@#1#2{%
268 %  \W@{Advancing count from \the\count@\space by #1\space
269 %                                                   in \xy@showorient #2}%
270 \ifnum #2>0
271  \edef\tmp@{#1}%
272 \else
273  \edef\tmp@{-#1}%
274 \fi
275 \advance\count@\tmp@\count@=\the\count@
276 \ifnum\the\count@<0 \advance\count@ 8\fi
277 \ifnum\the\count@>7 \advance\count@ -8\fi
278 \count@=\the\count@
279 %  \W@{    Resulting count@=\the\count@}%

280 }

282 % Round counter to the next odd element (multiple of 90deg)
283 % in the given direction
284 \xydef@\sm@roundcount@#1{%
285 \ifcase\the\count@
286  \advance\count@ #1\or
287 \or \advance\count@ #1\or
288 \or \advance\count@ #1\or
289 \or \advance\count@ #1\fi
290 \count@=\the\count@
291 \ifnum\the\count@<0 \advance\count@ 8\fi
292 \ifnum\the\count@>7 \advance\count@ -7\fi
293 \count@=\the\count@

294 }

296 \newif\ifsm@firstseg
297 \newif\ifsm@acceptable
299 % Given a representative described as a list of triplets ending with sm@nil,
300 % verify if is can be extended to the right destination
301 \xydef@\sm@trycirclelist#1{%
302 \R@p=\z@\U@p=\R@p%                Clear the deltas
303 \def\sm@exthp{0}\def\sm@exthm{0}%
304 \def\sm@extvp{0}\def\sm@extvm{0}% Clear the extension points
305 \def\sm@dxp{0pt}\def\sm@dxm{0pt}%
306 \def\sm@dyp{0pt}\def\sm@dym{0pt}% Reset the extensions
307 \def\sm@segs{}%                 % Clear the segment list

308 \sm@firstsegtrue                % Mark the first segment
309 \def\sm@connlen{0pt}%           % Initialize the connector length
310 \let\sm@tryclcont=\sm@trycirclelist@i
311 \sm@trycirclelist@i #1%Strip {} to expose the list elements

312 %

313 % The connector was processed

314 %

315 % Add an extra segment at then end, if ending in a multiple of 90 deg
316 \count@@=\sm@CIRout\count@@=\the\count@\count@=\the\count@
317 \sm@roundcount@{1}% Direction does not matter
318 \ifnum\count@=\count@@
319  \edef\sm@segs{\sm@segs{{\the\count@}{1}{\the\count@}}}%Accum segment
320 \fi
321 %  \W@{After trying CL deltax=\the\R@p, deltay=\the\U@p}%
322 %  \sm@showext{\space}%
323 %  \W@{ \space Segs: \meaning\sm@segs}%
324 %Now see if the connector can be extended enough
325 \A@=\X@p\advance\A@\R@p\advance\A@ -\X@c\A@=-\A@ % A=Dx
326 \B@=\Y@p\advance\B@\U@p\advance\B@ -\Y@c\B@=-\B@ % B=Dy
327 \sm@acceptabletrue
328 %  \W@{ \space Dx=\the\A@, Dy=\the\B@}%
329 \ifdim\A@>0pt
330  \ifnum\sm@exthp>0 \dimen@=\A@ \divide\dimen@\sm@exthp
331  \edef\sm@dxp{\the\dimen@}%
332  \else  \sm@acceptablefalse\fi\fi
333 \ifdim\A@<0pt
334  \ifnum\sm@exthm>0 \dimen@=\A@ \divide\dimen@\sm@exthm
335  \edef\sm@dxm{\the\dimen@}%
336  \else  \sm@acceptablefalse\fi
337  \A@=-\A@%Make it positive
338 \fi
339 \ifdim\B@>0pt
340  \ifnum\sm@extvp>0 \dimen@=\B@ \divide\dimen@\sm@extvp
341  \edef\sm@dyp{\the\dimen@}%
342  \else  \sm@acceptablefalse\fi\fi
343 \ifdim\B@<0pt
344  \ifnum\sm@extvm>0 \dimen@=\B@ \divide\dimen@\sm@extvm
345  \edef\sm@dym{\the\dimen@}%
346  \else  \sm@acceptablefalse\fi
347  \B@=-\B@
348 \fi
349 \ifsm@acceptable
350  %Compute the cost of the connector
351  \dimen@=\sm@connlen\advance\dimen@\A@\advance\dimen@\B@
352 %     \W@{ \space Cost is \the\dimen@}%
353  %See if it is best so far
354  \ifdim\dimen@<\sm@bestcost
355  \edef\sm@bestcost{\the\dimen@}%
356  \edef\sm@bestconn{{\sm@dxp}{\sm@dxm}{\sm@dyp}{\sm@dym}{\sm@segs}}%

357  \fi
358 \fi

359 }

361 \xydef@\sm@showext#1{%
362 \W@{#1\space hp=\sm@exthp,hm=\sm@exthm,vp=\sm@extvp
363  ,vm=\sm@extvm,len=\sm@connlen}}
365 % Process the next element in the list that describes the representative

366 %

367 \xydef@\sm@trycirclelist@i#1{%
368 \def\@tmp{#1}%
369 \ifx \@tmp\sm@nnil \let\sm@tryclcont=\relax\else
370  \expandafter\sm@tryclcar\@tmp \fi
371 \sm@tryclcont}
373 \xydef@\sm@tryclcar#1#2#3{%
374 %  \W@{Trying one turn in #1\space orient #2\space out #3}%
375 %Compute deltax in R@p and deltay in U@p. Move them to center first.
376 \dimen@=\ifnum #2<0 -\fi\R@
377 \count@=#1\count@=\the\count@ \ABfromdiag@
378 \advance\R@p -\B@ \advance\U@p \A@
379 %  \xy@showdim{   After center}%
380 % Move them to exit
381 \count@=#3\count@=\the\count@ \ABfromdiag@
382 \advance\R@p \B@ \advance\U@p -\A@
383 %  \xy@showdim{   After turn}%
384 %  \xy@showthe p{          }%
385 % Now update the extension points
386 \sm@computeext{#1}{#2}{#3}%

387 }
389 %

390 % Compute the extensions

391 %

392 \xydef@\sm@computeext#1#2#3{%
393 %  \W@{Computing extents for turn in #1\space orient #2\space out #3}%
394 \ifsm@firstseg
395  \sm@accumext#1%
396  \sm@firstsegfalse
397 \fi
398 \count@@=#1\count@@=\the\count@@\count@=\count@@
399 \dimen@=\sm@connlen
400 %  \W@{Before rounding count@=\the\count@, count@@=\the\count@@}%
401 \sm@roundcount@{#2}%
402 %  \W@{After rounding count@=\the\count@, count@@=\the\count@@}%
403 \ifnum \count@=\count@@
404  \sm@advancecount@ 1{#2}% Advance by 90 degrees if odd. By 45 first
405  \advance\dimen@ 0.7854\R@% It was incremented with 1/8 circle
406  \ifnum \count@=#3% Check if done
407  \else
408  \sm@advancecount@ 1{#2}% Another 45

409  \advance\dimen@ 0.7854\R@% It was incremented with 1/8 circle
410  \fi
411 \else
412  \advance\dimen@ 0.7854\R@% It was incremented with 1/8 circle
413 \fi
414 \edef\sm@connlen{\the\dimen@}% Save the connector length
415 \sm@accumext{\the\count@}%
416 \edef\sm@segs{\sm@segs{{#1}{#2}{\the\count@}}}%Accum segment
417 \ifnum\the\count@=#3 \else
418  \edef\tmp@{{\the\count@}{#2}{#3}}%Recursive call
419  \expandafter\sm@computeext\tmp@
420 \fi

421 }
423 %

424 % Accumulate the extensions

425 %

426 \xydef@\sm@accumext#1{%
427 % \W@{Accumulating extent for #1}%
428 % \sm@showext{Before accum:}%
429 \ifcase #1%
430  \or    \count@@=\sm@extvm\advance\count@@ by1%
431  \edef\sm@extvm{\the\count@@}% 1 is V-
432  \or\or \count@@=\sm@exthp\advance\count@@ by1%
433  \edef\sm@exthp{\the\count@@}% 3 is H+
434  \or\or \count@@=\sm@extvp\advance\count@@ by1%
435  \edef\sm@extvp{\the\count@@}% 5 is V+
436  \or\or \count@@=\sm@exthm\advance\count@@ by1%
437  \edef\sm@exthm{\the\count@@}% 7 in H-
438 \fi
439 % \sm@showext{After accum:}%

440 }

443 % Draw a computed connector.
444 % 1,2,3,4 - dx+, dx-, dv+, dv- (lengths of straight connectors in each
445 %                              direction)
446 % 5       - a list of segments, each enclosed in a pair of braces.
447 \xydef@\sm@conndraw#1#2#3#4#5{%
448  \def\sm@contlist{\sm@drawseglist}%
449  \edef\sm@dxp{#1}%
450  \edef\sm@dxm{#2}%
451  \edef\sm@dyp{#3}%
452  \edef\sm@dym{#4}%Save deltas
453  \sm@drawseglist #5\sm@nil}
454 \xydef@\sm@drawseglist#1{% Get the first segment
455 \ifx #1\sm@nil \def\sm@contlist{}\else
456  \sm@drawseg #1\fi
457 \sm@contlist}

459 %

460 % Draw a segment

461 %

462 \xydef@\sm@drawseg#1#2#3{% A segment is CIRin+CIRorient+CIRout
463 %  \W@{Drawing segment in=#1\space out=\space #3}\xy@showthe c{Seg start}%
464 \def\CIRin@@{#1}\def\CIRout@@{#3}%
465 \sm@straight%See if a straight line is needed here. Insert it and
466  %reset c if needed
467 \ifnum\CIRin@@=\CIRout@@ \else
468  % Compute the center of the circle
469  \count@=\CIRin@@
470  \dimen@=\ifnum #2<0 -\fi\R@
471  \ABfromdiag@
472  \advance\X@c -\B@ \advance\Y@c \A@
473 %      \xy@showthe c{Center of circle}%
474 %      \xy@showdim{Before center}%
475  \ifnum #2>0 \def\CIRorient@@{\CIRacw@}%
476  \else \def\CIRorient@@{\CIRcw@}\fi
477  \drop@\literal@{\hbox\bgroup\cir@i}% Place the circle
478  % Now move the the end of the arc
479  \dimen@=\ifnum #2<0 -\fi\R@
480  \count@=\CIRout@@\count@=\count@%Wierd. If I remove this last assignm
481 %                                     %\count@ is not set
482  \ABfromdiag@
483 %      \xy@showthe c{Before advance}%
484 %      \xy@showdim{Before advance}%
485  \advance\X@c\B@ \advance\Y@c-\A@
486 %      \xy@showthe c{After circle}%
487 %      \xy@showdim{After circle}%
488 \fi

489 }

491 \xydef@\sm@straight{%
492 \U@c=\z@\D@c=\U@c\L@c=\U@c\R@c=\U@c
493 \pfromc@                    %Set p at the beginning of the segment
494 \ifcase \CIRin@@ \or% 1 is V-
495  \A@=\sm@dym\advance \Y@c\A@ %Wierd. I have to use the temporary A@!!
496 \or\or              % 3 is H+
497  \A@=\sm@dxp\advance \X@c\A@
498 \or\or              % 5 is V+
499  \A@=\sm@dyp\advance \Y@c\A@
500 \or\or              % 7 is H-
501  \A@=\sm@dxm\advance \X@c\A@ \fi
502 \ifdim\X@c=\X@p\ifdim\Y@c=\Y@p\else \sm@stri \fi\else \sm@stri \fi

503 }

505 \xydef@\sm@stri{%
506 %   \W@{Drawing straight connection}\xy@showthe p{StrSrc}\xy@showthec{StrDst}%
507  \edef\tmp@{\expandafter\noexpand\arstemprefix@@\arstem@@}%
508  \expandafter\sm@connect@\tmp@}
509 \xydef@\sm@connect@#1#{%
510  \DN@##1{\connect@{#1}{##1}}\next@}

512 \xydef@\sm@drop@#1#{%
513  \DN@##1{\drop@{#1}{##1}}\next@}
515 % Compute and draw a connector. External interface
516 % 1 - in (for p)
517 % 2 - out (for c)
518 % 3 - suggested radius
519 \xydef@\smconn#1#2#3{%
520 \edef\sm@CIRin{#1}\edef\sm@CIRout{#2}%Memorize the directions
521 \R@=#3\R@=\the\R@
522 \sm@conn}
524 \xyendinput

Bug: This code should probably be merged with the ‘arrow’ feature.

Finally the log.

556 % $Log$
557 % Received from George.

Syntax  Action
\ar ⟨arrow⟩ ⟨path⟩  make ⟨arrow⟩ along ⟨path⟩
⟨arrow⟩ ⟶ ⟨form⟩*  ⟨arrow⟩ has the ⟨form⟩s
⟨form⟩ ⟶ @ ⟨variant⟩ use ⟨variant⟩ of arrow

| @ ⟨variant⟩ { ⟨tip⟩ } build arrow3.3m using ⟨variant⟩ of a standard stem

and ⟨tip⟩ for the head

| @ ⟨variant⟩ { ⟨tip⟩ ⟨conn⟩ ⟨tip⟩ } build arrow3.3m using ⟨variant⟩ of ⟨tip⟩, ⟨conn⟩,

⟨tip⟩ as arrow tail, stem, and head (in that order)

| @ ⟨connchar⟩  change stem to the indicated ⟨connchar⟩
| @!  dash the arrow stem by doubling it
| @/ ⟨direction⟩ ⟨dist⟩ /  curve3.3o arrow the ⟨dist⟩ance towards ⟨direction⟩
| @( ⟨direction⟩ , ⟨direction⟩ )  curve to fit with in-out directions3.3p
| @` { ⟨control point list⟩ }  curve setup3.3q with explicit control points

| @[ ⟨shape⟩ ] add [⟨shape⟩] to object ⟨modifier⟩s3.3r for all ob-

jects

| @* { ⟨modifier⟩* }  add object ⟨modifier⟩s3.3r for all objects
| @< ⟨dimen⟩ >  slide arrow3.3s the ⟨dimen⟩
| | ⟨anchor⟩ ⟨it⟩  break each segment at ⟨anchor⟩ with ⟨it⟩
| ^⟨anchor⟩ ⟨it⟩ | _⟨anchor⟩ ⟨it⟩ label each segment at ⟨anchor⟩ with ⟨it⟩
| @?  reverse meaning of above and below3.3t
⟨variant⟩ ⟶ ⟨empty⟩ | ^| _
| 0 | 1 | 2 | 3  ⟨variant⟩: plain, above, below, double, or triple
⟨tip⟩ ⟶ ⟨tipchar⟩* directional named as the sequence of ⟨tipchar⟩s
| ⟨dir⟩  any ⟨dir⟩ectional3.3n
⟨tipchar⟩ ⟶ < | > | ( | ) | | | ' | ` | + | /  recognised tip characters
| ⟨letter⟩ | ⟨space⟩  more tip characters
⟨conn⟩ ⟶ ⟨connchar⟩* directional named as the sequence of ⟨connchar⟩s
| ⟨dir⟩  any ⟨dir⟩ectional3.3n
⟨connchar⟩ ⟶ - | . | ~ | = | :  recognised connector characters

Figure 3.2: ⟨arrow⟩s.

[figure: f_{3}; f_{4}; f_{5}; A; f_{1}; f_{2}; g_{1}; f_{6}; g_{4}; f_{7}; f_{8}; B; g_{2}; g_{3}]

Figure 3.3: Pasting diagram.

Syntax  Action
⟨twocell⟩ ⟶ ⟨2-cell⟩⟨switches⟩⟨Arrow⟩  typeset ⟨2-cell⟩ with the ⟨switches⟩ and ⟨Arrow⟩
⟨2-cell⟩ ⟶ \..twocell  typeset two curved arrows
| \..uppertwocell  typeset upper curved arrow only
| \..lowertwocell  typeset lower curved arrow only
| \..compositemap  use consecutive straight arrows
⟨Arrow⟩ ⟶ {⟨tok⟩⟨text⟩}  specifies orientation and label
| {⟨nudge⟩⟨text⟩}  adjust position, use default orientation
| {⟨text⟩}  use default position and orientation
| {⟨tok⟩*⟨object⟩}  use ⟨object⟩ as the label
| {⟨nudge⟩*⟨object⟩} | {*⟨object⟩}
⟨tok⟩ ⟶ ^| _| = oriented anti-/clockwise/equality
| \omit  no Arrow, default is clockwise

|

   ` | ' | " | !

no Arrow; tips on two curved arrows as: anti-/clockwise/double-headed/none

⟨switches⟩ ⟶ ⟨switch⟩⟨switches⟩  list of optional modifications
⟨switch⟩ ⟶ ⟨empty⟩  use defaults
| ^⟨label⟩  place ⟨label⟩ on the upper arrow
| _⟨label⟩  place ⟨label⟩ on the lower arrow
| ⟨nudge⟩  set the curvature, based on ⟨nudge⟩ value
| \omit  do not set the curved arrows
| !  place \modmapobject midway along arrows
| ~ ⟨what⟩ { ⟨object⟩ }  use ⟨object⟩ in place specified by ⟨what⟩
⟨what⟩ ⟶ ⟨empty⟩  set curves using the specified ⟨object⟩
| ^| _use ⟨object⟩ with upper/lower curve
| ` | '  use ⟨object⟩ for arrow head/tail
⟨label⟩  ⟶ ⟨text⟩ | ⟨nudge⟩ ⟨text⟩  set ⟨text⟩, displaced by ⟨nudge⟩
| *⟨object⟩ | ⟨nudge⟩*⟨object⟩  set ⟨object⟩, displaced by ⟨nudge⟩

⟨nudge⟩ ⟶ <⟨number⟩> use ⟨number⟩ in an appropriate way, e.g., to posi-

tion object or label along a fixed axis

| <\omit>  do not typeset the object/label

Figure 3.4: ⟨twocell⟩s

Syntax  Action
\xygraph{⟨graph⟩}  typeset ⟨graph⟩
⟨graph⟩ ⟶ ⟨step⟩*  interpret ⟨step⟩s in sequence
⟨step⟩  ⟶ ⟨node⟩  move3.6a to the ⟨node⟩
| -⟨arrow⟩ ⟨node⟩ ⟨labels⟩  draw3.6b line to ⟨node⟩, with ⟨labels⟩
| :⟨arrow⟩ ⟨node⟩ ⟨labels⟩  draw3.6b ⟨arrow⟩ to ⟨node⟩, with ⟨labels⟩
| ( ⟨list⟩ )  map3.6c current node over ⟨list⟩
⟨node⟩ ⟶ [ ⟨move⟩ ]  new node ⟨move⟩d relative to current
| & | \\  new node in next column/row3.6d
| "⟨id⟩"  previously saved3.6e node
| ?  currently mapped3.6c node
| ⟨node⟩ ⟨it⟩  ⟨node⟩ with ⟨it⟩ typeset and saved3.6e there
| ⟨node⟩ = "⟨id⟩"  ⟨node⟩ saved3.6e as "⟨id⟩"
| ⟨node⟩ ! ⟨escape⟩  augment node with material in another mode
⟨move⟩ ⟶ ⟨hop⟩*  ⟨hop⟩s3.6f (dulr) from current node
| ⟨hop⟩* ⟨place⟩ ⟨move⟩  do ⟨hop⟩s3.6f but use its ⟨place⟩ and ⟨move⟩ again
⟨list⟩  ⟶ ⟨graph⟩ , ⟨list⟩ | ⟨graph⟩ list of subgraphs3.6c
⟨escape⟩ ⟶ { ⟨pos⟩ ⟨decor⟩ }  perform ⟨pos⟩ ⟨decor⟩3.6g
| M ⟨matrix⟩  insert ⟨matrix⟩3.6h
| P ⟨polygon⟩  insert ⟨polygon⟩3.6i
| E ⟨ellipse⟩  insert ⟨ellipse⟩3.6i
| ~ ⟨setup⟩  setup parameters3.6j

Figure 3.5: ⟨graph⟩s

n sin \frac{π}{n}  cos \frac{π}{n}  sin \frac{2π}{n}  cos \frac{2π}{n}  sin \frac{3π}{n}  cos \frac{3π}{n}  sin \frac{4π}{n}  cos \frac{4π}{n}  sin \frac{5π}{n}  cos \frac{5π}{n}
0 0  1  0  1  0  1  0  1  0  1
1 0  −1  0  1  0  −1  0  1  0  −1
2 1  0  0  −1  1  0  0  1  1  0
3 .8660254  .5  −.8660254 −.5  0  −1  −.8660254 −.5  −.8660254  .5
4 .70710678 .70710678 1  0  .70710678 −.70710678 0  −1  −.70710678 −.70710678
5 .587785  .809017  .951057  .309017  .951057 −.809017  .587785 −.809017 0  −1
6 .5  .8660254  .8660254  .5  1  0  −.8660254 −.5  .5  −.8660254
7 .433884  .900969  .781831  .62349  .974928  .222521  .974928 −.222521 .781831 −.62349
8 .382683  .92388  .70710678 .70710678 .92388  .382683  1  0  .92388  −.382683
9 .34202  .939693  .642788  .766044  .8660254  .5  .984808  .173648 .984808 −.173648
10 .309017  .951057  .587785  .809017  .309017  .951057  .951057  .309017 1  0
11 .281733  .959493  .540641  .841254  .75575  .654861  .909632  .415415 .989821  .142315
12 .258819  .965926  .5  .8660254  .70710678 .70710678 .8660254 .5  .965926  .258819

Figure 3.6: Trigonometry tables for Polygon vertices.

Syntax  Action
⟨knot-piece⟩ ⟶ ⟨piece⟩⟨scale⟩⟨knot-labels⟩  interpret knot-piece
⟨piece⟩  ⟶ ⟨crossing⟩ | ⟨join⟩  piece is a crossing3.10a or a join3.10l
⟨scale⟩  ⟶ ⟨empty⟩ | - | [⟨num⟩]  invert or scale the knot piece3.10b;
| ~⟨pos⟩⟨pos⟩⟨pos⟩⟨pos⟩  alter size and shape3.10c using the ⟨pos⟩s
⟨knot-labels⟩ ⟶ ⟨empty⟩ | ⟨knot-tips⟩⟨knot-labels⟩ arrowtips at ends, aligned with orientation
| ⟨where⟩⟨what⟩⟨knot-labels⟩  list3.10k of arrowtips, breaks and labels3.10e

| @⟨adjust⟩⟨knot-labels⟩ adjust hole3.10d position for a ⟨crossing⟩; adjust other parameter3.10n for a ⟨join⟩.

⟨knot-tips⟩ ⟶ == | =!  arrowtips3.10k at both/neither end
| =< | =>  arrowtips3.10k also at start/finish

⟨where⟩ ⟶ | | |⟨adjust⟩ ‘over’ string on a ⟨crossing⟩;3.10f

middle3.10m place on a ⟨join⟩.

| < | <⟨adjust⟩ initial portion of ‘under’ string on a ⟨crossing⟩;3.10f

earlier3.10m place on a ⟨join⟩.

| > | >⟨adjust⟩ final portion of ‘under’ string on a ⟨crossing⟩;3.10f later3.10m place on a ⟨join⟩.

⟨adjust⟩  ⟶ (+⟨num⟩) | (-⟨num⟩)  adjustment3.10k from current value of parameter
| (=⟨num⟩) | (⟨num⟩)  set parameter value3.10k
⟨what⟩  ⟶ > | <  arrowhead aligned with/against orientation3.10i
| \knothole | \khole  leave hole in the string3.10j
| {⟨text⟩}  set3.10g ⟨text⟩ as label, using \labelstyle
| {*⟨object⟩}  drop ⟨object⟩3.10h
| {⟨anchor⟩⟨it⟩}  ⟨break⟩ or label3.10h as on an ⟨arrow⟩
| |  null-break3.10k

Figure 3.7: ⟨knot-piece⟩ construction set 460 CHAPTER 3. FEATURES

[figure: y; x; z; x; z; y; y; x; z; y; x; z; x; z; y; y; x; z; \vcross; \vcrossneg; \vuncross; \hcross; \hcrossneg; \huncross; y; x; z; x; z; y; y; x; z; y; x; z; x; z; y; y; x; z; \vtwist; \vtwistneg; \vuntwist; \htwist; \htwistneg; \huntwist; y; x; z; x; z; y; y; x; z; y; x; z; x; z; y; y; x; z; \xoverv; \xunderv; \xunoverv; \xoverh; \xunderh; \xunoverh; y; x; z; x; z; y; y; x; z; y; x; z; x; z; y; y; x; z; \vover; \vunder; \vunover; \hover; \hunder; \hunover]

Figure 3.8: knot crossings with orientations and label positions

[figure: ∘; x; y; z; ∘; x; y; z; ∘; x; y; z; ∘; x; y; z; ∘; x; y; z; ∘; x; y; z; ∘; x; y; z; ∘; x; y; z; \vloop; \vcap; \vcap-; \vloop-; \hloop; \hcap; \hcap-; \hloop-; ∘; x; y; z; ∘; x; y; z; ∘; x; y; z; ∘; x; y; z; ∘; x; y; z; ∘; x; y; z; \xcapv; \sbendv; \zbendv; \sbendh; \zbendh; \xcaph; ∘; x; y; z; ∘; x; y; z; ∘; x; y; z; ∘; x; y; z; \xbendr; \xbendl; \xbendu; \xbendd; ∘; x; y; z; ∘; x; y; z; ∘; x; y; z; ∘; x; y; z; \xbendd-; \xbendu-; \xbendl-; \xbendr-]

Figure 3.9: knot joins, with orientations, labels and shifts

Drivers

This chapter describes the driver options that support customisation of the XY-pic output to particular output devices. The first section describes the actual drivers, the second a set of modifications specially applicable to PostScript printing.

4.1 Support for Specific Drivers

4.2 dvidrv driver

Vers. 3.3 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This driver provides support for the “emtex” \special commands, when using one of the standard dvi-drivers: dvidot, dvihplj, dvimsp, dviscr or dvivik, that come with Eberhard Mattes’ em-TEX distribution.

Header:

1 %% $Id: xydvidrv.doc,v 3.3 1996/12/18 09:12:40 ross Exp $
2 %%
3 %% Xy-pic ``dvidrv-driver'' option.
4 %% Copyright (c) 1995-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,

462 CHAPTER 4. DRIVERS

22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{dvidrv}{dvidrv driver}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}
42 \xydef@\dvidrv@@#1{\dvimessage@{dvidrv}{#1}}
44 \newdriver{%
45 \xyaddsupport{emtex}\dvidrvEmTeX@@
46 \xyaddsupport{line}\dvidrvLine@@

47 }

Driver installation Supported \special effects are...

• em-TEX line-drawing \specials.

58 \xydef@\dvidrvEmTeX@@{\dvidrvEmTeX@}%
59 \xydef@\dvidrvEmTeX@{\setupxyEMTeX@}%

• variable line-widths

66 \xydef@\dvidrvLine@@{\dvidrvLine@}%
67 \xydef@\dvidrvLine@{\xywithoption{emtex}{\installEMline@}}%

The end & Log

79 \xyendinput
81 % $Log: xydvidrv.doc,v $
82 % Revision 3.3  1996/12/18  09:12:40  ross
83 % no changes

84 %

85 % Revision 3.1  1995/09/05 20:28:57  ross
86 % Releasing version 3.1!

87 %
88 %

89 % NEW for version 3.1

4.3 DVIPS driver

Vers. 3.3 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This driver provides support for all extensions when using the dvips driver by Tomas Rokicki [11]. It has been tested with dvips version 5.55a and dvipsk version 5.58f. Header:

1 %% $Id: xydvips.doc,v 3.3 1996/12/18 09:13:14 ross Exp $
2 %%

4.3. DVIPS DRIVER 463

3 %% Xy-pic ``dvips-driver'' option.
4 %% Copyright (c) 1995-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{dvips}{DVIPS driver}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}
42 \xydef@\dvips@@#1{\dvimessage@{dvips}{#1}}
44 \newdriver{%
45 \xyaddsupport{color}\dvipsColor@@
46 \xyaddsupport{crayon}\dvipsCrayola@@
47 \xyaddsupport{ps}\dvipsPS@@
48 \xyaddsupport{rotate}\dvipsRotate@@
49 \xyaddsupport{line}\dvipsLine@@
50 \xyaddsupport{frame}\dvipsFrames@@
51 \xyaddsupport{tile}\dvipsTiles@@
52 \xyaddsupport{tpic}\dvipsTPIC@
53 \xyaddsupport{emtex}\dvipsEM@
54 \xyaddsupport{cmtip}\relax

55 }

Driver installation Supported \special effects are...

• colour, using direct color specials and PostScript.

DVIPS uses the colour-stack method, due to Tomas Rokicki.

71 \xydef@\dvips@Color@{\dvipsPStypes@
72 \let\xylocalColor@=\xystackcolor@
73 \let\xycolor@push\xycolor@push@@
74 \def\xycolor@{\xycolor@@}\let\xycolorwarning@=\relax

75 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
76  \xyinputorelse@{xyps-c}{\xydrivernoload@{ps-c}}\installPScolor@ }%
77 \else\DN@{}\fi \next@
78 \ifx\xycolor@@\xyNoColor@ \let\xycolor@@=\xycolor@raw@@\fi
79 \ifx\xycrayolaloaded\empty \DN@{\xystandardcolors@\dvipsCrayola@{}}%
80 \else \DN@{\xystandardcolors@}\fi \next@
81 \let\dvipsColor@@=\relax
82 \let\UnloadColor@@=\NoDVIPScolor@
83 }%
85 \xydef@\dvipsColor@@{\dvips@Color@}
87 \xydef@\NoDVIPScolor@{%
88 \def\xycolor@{\xycolor@@}%
89 \let\xycolor@@=\xyNoColor@
90 \let\xylocalColor@=\xyNoColor@@
91 \let\xycolorwarning@=\xycolorwarning@@
92 \let\dvipsColor@@=\dvips@Color@
93 \let\UnloadColor@@=\UnloadColor@

94 }

If neither support file colordvi.tex nor colordvi.sty can be found, then the normal colour support will not be available. However the colour support for the PostScript back-end can still be used.

102 \xydef@\NoDVIPScolordvi@{\xywarning@{%
103 Neither  colordvi.tex  nor  colordvi.sty  could be found.}%
104 \xyBEcolorcheck@}%

• crayon colours.

The 68 colours that dvips recognizes by name are not loaded unless the crayon option has been requested.

117 \xydef@\dvipsCrayola@@{\dvipsColor@@\dvipsCrayola@}
119 \xydef@\dvipsCrayola@{%
120 \let\prevxycolor@=\newxycolor@
121 \def\newxyDVIPScolor@##1##2##3{\prevxycolor@{##1}{}{##1}}%
122 \let\newxycolor@=\newxyDVIPScolor@ \dvipsInclude@{color.pro}%
123 %  \xyinputorelse@{colordvi.tex}%
124 %   {\NoDVIPScolordvi@\let\newxycolor@=\prevxycolor@}%
125 \installCrayolaColors@
126 \let\newxycolor@=\prevxycolor@ }%

Although any order of loading options: ps, dvips, color and crayon produces the desired result visually, the PostScript code can be different with different loading order. The most easily readable is obtained when crayon is requested last.

• PostScript back-end.

138 \xydef@\dvipsPS@@{\dvipsPS@}
140 \xydef@\dvipsPS@unload{\UnloadPS@
141 \let\UnloadPS@@=\UnloadPS@
142 \let\dvipsPS@@=\dvipsPS@ }

dvips has three kinds of PostScript \special which can be used. These may be used with

various features other than just the PostScript backend.

151 \xydef@\dvipsPStypes@{%
152 \xyinputorelse@{xyps-ps}{\xydrivernoload@{ps-ps}}%
153 \ifx\PSspecial@@\dvipsSpecial@\else
154 \let\PSspecial@@=\dvipsSpecial@
155 \let\PSmacro@@=\dvipsMacro@
156 \let\PSdict@@=\dvipsDict@
157 \let\PSspecialdict@@=\dvipsDict@
158 \let\PSraw@@=\dvipsRaw@
159 \let\PSinclude@@=\dvipsInclude@
160 \let\xyPSobeylines@@=\obeyDVIPSlines@
161 \let\xyPScurrpt@@=\dvipsCurrpt@@
162 \dvips@@{PostScript}%
163 \fi
164 % \xyinputorelse@{xyps-ps}{\xydrivernoload@{ps-ps}}%
165 \XYpredict@ }
167 \xywarnifdefined\dvipsSpecial@
168 \xywarnifdefined\dvipsMacro@
169 \xywarnifdefined\dvipsDict@
170 \xywarnifdefined\dvipsInclude@
171 \xywarnifdefined\dvipsRaw@
172 {\catcode`\"=11 \catcode`\!=11 \catcode`\:=11
173 \gdef\dvipsSpecial@#1{\special{ps:: SDict begin #1 end}}
174 \gdef\dvipsMacro@#1{\firstPS@@\special{" {#1}xy}}
175 % \gdef\dvipsDict@#1{\special{! mark{#1}stopped cleartomark}}
176 \gdef\dvipsDict@#1{\special{! #1}}
177 \gdef\dvipsInclude@#1{\special{header=#1}}
178 \gdef\dvipsRaw@#1{\special{ps: SDict begin #1 end}}
180 \catcode`\^^M=\active %
181 \gdef\next{\catcode`\^^M=\active \let^^M=\space }}%
182 \xylet@\obeyDVIPSlines@=\next

All the PostScript definitions passed to dvips by reading the dictionary file are stored in a PostScript dictionary which it defines, called SDict. This must be the current dictionary whenever an XY-ps command is to be executed. This will be the case whenever the \special{" commands} or \special{! commands} forms are used, but not when the \special{ps:: commands} form is used. Thus the \dvipsSpecial@ macro includes code to open SDict and close it when finished; so also does the \dvipsRaw@ type, since this is used with XY-pic PostScript operators whose definitions have been placed within SDict. The currentpoint is defined for the “raw” specials.

200 \xydef@\dvipsCurrpt@{\let\xyPScurrpt@@=\dvipsCurrpt@@}%
201 \xydef@\dvipsCurrpt@@{\PSraw@@{xyp}}

The PostScript operator called xyp is defined in xyps-ps for storing the location read from

     currentpoint.

This installs the PostScript backend.

212 \xydef@\dvipsPS@{\dvipsPStypes@

213 \let\dvipsPS@@=\PSspecials@true
214 \let\UnloadPS@@=\dvipsPS@unload
215 \let\installxyps@@=\relax \installxyps@ }

• rotated/scaled diagrams and text, using PostScript.

222 \xydef@\dvipsRotate@@{\dvipsRotate@}
224 \xydef@\dvipsRotate@{\dvipsPStypes@
225 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
226 \xyinputorelse@{xyps-r}{\xydrivernoload@{ps-r}}%
227 \dvipsCurrpt@ \dvipsRotScale@ \installPSrotscale@ }%
228 \else\DN@{\xydriverfail@{rotations are}UnloadRotate@\relax}\fi
229 \next@ }
231 \xydef@\dvipsRotScale@{%
232 \def\xyrot@start(##1){{xyct ##1\space xyrs }}%
233 \def\xyrot@end{}%
234 \def\xyscale@start(##1,##2){{xyct ##1\space##2\space xyss }}%
235 \def\xyscale@end{}}

• variable line-widths and poly-lines, using PostScript.

242 \xydef@\dvipsLine@@{\dvipsLine@}
244 \xydef@\dvipsLine@{\dvipsPStypes@
245 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
246 \xyinputorelse@{xyps-l}{\xydrivernoload@{ps-l}}\installPSline@ }%
247 \else\DN@{\xydriverfail@{line-widths are}\UnloadLine@\relax}\fi
248 \next@ }

• extra frames and fills, using PostScript.

255 \xydef@\dvipsFrames@@{\dvipsFrames@}
257 \xydef@\dvipsFrames@{\dvipsPStypes@
258 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
259 \xyinputorelse@{xyps-f}{\xydrivernoload@{ps-f}}\installPSframes@ }%
260 \else\DN@{\xydriverfail@{frames are}\UnloadFrames@\relax}\fi
261 \next@ }

• patterns and tiles, using PostScript.

268 \xydef@\dvipsTiles@@{\dvipsTiles@}
270 \xydef@\dvipsTiles@{\dvipsPStypes@
271 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
272 \xyinputorelse@{xyps-t}{\xydrivernoload@{ps-t}}\installPSpatterns@ }%
273 \else\DN@{\xydriverfail@{Patterns are}\UnloadPSpatterns@\relax}\fi
274 \next@ }

• tpic drawing commands.

281 \xydef@\dvipsTPIC@@{\dvipsTPIC@}
282 \xydef@\dvipsTPIC@{\setupxyTPIC@}

4.4. DVITOPS DRIVER 467

• em-TEX drawing commands.

289 \xydef@\dvipsEM@@{\dvipsEM@}
290 \xydef@\dvipsEM@{\setupxyEMTeX@}

The end & Log

302 \xyendinput
304 % $Log: xydvips.doc,v $
305 % Revision 3.3  1996/12/18  09:13:14  ross
306 % minor improvements to file-loading commands

307 %

308 % Revision 3.2  1995/09/19  18:20:20  ross
309 % Bug fix release.

310 %

311 % Revision 3.1  1995/09/05  20:36:33  ross
312 % Release!

313 %

314 % Revision 3.0  1995/07/07  20:13:19  ross
315 % Major release w/new User's Guide!

316 %

317 % Revision 2.13  1995/07/04  15:04:51  ross
318 % Ready for release of v3.

319 %

320 % NEW for version 3.

4.4 DVITOPS driver

Vers. 3.3 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This file provides support for the dvitops driver by James Clark. As of September 1995, it has not been fully tested. Header:

1 %% $Id: xydvitops.doc,v 3.3 1996/12/18 09:14:36 ross Exp $
2 %%
3 %% Xy-pic ``DVITOPS-driver'' option.
4 %% Copyright (c) 1995-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but

16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{dvitops}{DVITOPS driver}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

41 \xydef@\dvitops@@#1{\dvimessage@{DVITOPS}{#1}}
43 \newdriver{%
44 \xyaddsupport{color}\dvitopsColor@@
45 \xyaddsupport{crayon}\dvitopsCrayon@@
46 \xyaddsupport{ps}\dvitopsPS@@
47 \xyaddsupport{rotate}\dvitopsRotate@@
48 \xyaddsupport{line}\dvitopsLine@@
49 \xyaddsupport{frame}\dvitopsFrames@@
50 \xyaddsupport{tile}\dvitopsTiles@@
51 % \xyaddsupport{tpic}\dvitopsTPIC@@
52 \xyaddsupport{cmtip}\relax

53 }

Supported \special effects are...

• colour, using direct color specials for gray, rgb and hsb colour models; and PostScript colour within diagrams;

dvitops has a method for using colours locally, however it only colours “regions”, which cannot be nested. To use this within XY-pic diagrams would be just asking for trouble.

72 \xydef@\dvitopsColor@@{\dvitops@Color@}
74 \xydef@\dvitops@Color@{\dvitopsPStypes@
75 \let\xylocalColor@=\xyDVITOPScolor@
76 \let\xycolor@push\xycolor@push@@
77 \def\xycolor@{\xycolor@@}\let\xycolorwarning@=\relax
78 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
79  \xyinputorelse@{xyps-c}{\xydrivernoload@{ps-c}}\xycatcodes
80  \installPScolor@ }\else\DN@{}\fi \next@
81 \ifx\xycolor@@\xyNoColor@ \let\xycolor@@=\xycolor@raw@@\fi
82 \ifx\xycrayolaloaded\empty \DN@{\xystandardcolors@\dvitopsCrayon@{}}%
83 \else\let\next@=\xystandardcolors@
84 \fi \next@
85 \let\dvitops@Color@@=\relax
86 \let\UnloadColor@@=\NoDVITOPScolor@
87 }%
89 \xydef@\NoDVITOPScolor@{%

90 \def\xycolor@{\xycolor@@}%
91 \let\xycolor@@=\xyNoColor@
92 \let\xylocalColor@=\xyNoColor@@
93 \let\xycolorwarning@=\xycolorwarning@@
94 \let\dvitops@Color@@=\dvitops@Color@

95 }

99 \xydef@\xyDVITOPScolor@{\bgroup \DN@##1##2{\egroup}%
100 \ifInvisible@\else\ifHidden@\else\DNii@{\no@@}\ifx\nextii@\Connect@@
101 \else\DN@{\xyDVITOPScolor@i}\fi\fi\fi \next@ }
103 \xydef@\xyDVITOPScolor@i#1#2{\checkXyStyle@
104 \DN@{#2}\ifx\next@\empty
105 \def\tmp@##1{\DN@{\xycolor@begin##1\xycolor@end{#1}}}%
106 \else\DNii@{gray}\ifx\next@\nextii@
107 \def\tmp@##1{\DN@{\xycolor@begin##1\xycolor@end{gray}{#1}}}%
108 \else\DNii@{rgb}\ifx\next@\nextii@
109 \def\tmp@##1{\DN@{\xycolor@begin##1\xycolor@end{rgbcolor}{#1}}}%
110 \else\DNii@{hsb}\ifx\next@\nextii@
111 \def\tmp@##1{\DN@{\xycolor@begin##1\xycolor@end{hsbcolor}{#1}}}%
112 \else \DN@{\xywarning@{DVITOPS cannot support color: #2 #1}}%
113 \fi\fi\fi\fi
114 \toks@={\egroup \let\xy@style@=\relax \def\Drop@@}%
115 \expandafter\tmp@\expandafter{\Drop@@}%
116 \expandafter\addtotoks@\expandafter{\expandafter{\next@}\def\Connect@@}%
117 \expandafter\tmp@\expandafter{\Connect@@}%
118 \expandafter\addtotoks@\expandafter{\expandafter{\next@}}%
119 \the\toks@ }%
121 \xydef@\xycolor@begin{\dvitopsBegin@{color}}
122 \xydef@\xycolor@end{\dvitopsEnd@{color}\dvitopsColor@x}

• crayon colours.

The 68 colours are those that dvips recognizes by name, thanks to Tomas Rokicki.

135 \xydef@\dvitopsCrayon@@{\dvitopsColor@@\dvitopsCrayon@}
136 \xydef@\dvitopsCrayon@{\installCrayolaColors@}%

• PostScript back-end.

143 \xydef@\dvitopsPS@@{\dvipsPS@}
145 \xydef@\dvitopsPS@unload{\UnloadPS@
146 \let\UnloadPS@@=\UnloadPS@
147 \let\dvitopsPS@@=\dvitopsPS@ }

dvitops has two kinds of \special which can be used; ‘inline’ and ‘prolog’ for including header files. Also there are the ‘begin’ and ‘end’ types for defining regions.

157 \xydef@\dvitopsPStypes@{%
158 \xyinputorelse@{xyps-ps}{\xydrivernoload@{ps-ps}}%
159 \ifx\PSspecial@@\dvitopsSpecial@\else
160 \let\PSspecial@@=\dvitopsSpecial@
161 \let\PSmacro@@=\dvitopsMacro@

162 \let\PSdict@@=\dvitopsDict@
163 \let\PSspecialdict@@=\dvitopsDict@
164 \let\PSraw@@=\dvitopsRaw@
165 \let\PSinclude@@=\dvitopsInclude@
166 \let\xyPSobeylines@@=\obeyDVIPSlines@
167 \let\xyPScurrpt@@=\dvitopsCurrpt@@
168 \dvitops@@{PostScript}%
169 \fi
170 % \xyinputorelse@{xyps-ps}{\xydrivernoload@{ps-ps}}%
171 \XYpredict@ }
173 \xywarnifdefined\dvitopsSpecial@
174 \xywarnifdefined\dvitopsMacro@
175 \xywarnifdefined\dvitopsDict@
176 \xywarnifdefined\dvitopsInclude@
177 \xywarnifdefined\dvitopsRaw@
178 \xywarnifdefined\dvitopsOrigin@
179 \xywarnifdefined\dvitopsBegin@
180 \xywarnifdefined\dvitopsEnd@
181 \xywarnifdefined\dvitopsRotate@x
182 \xywarnifdefined\dvitopsTransform@x
183 \xywarnifdefined\dvitopsColor@x
184 {\catcode`\:=11
185 \gdef\dvitopsSpecial@#1{\special{dvitops: inline #1}}
186 \gdef\dvitopsMacro@#1{\special{dvitops: inline {#1}xy}}
187 \gdef\dvitopsDict@#1{\special{dvitops: inline #1}}
188 \gdef\dvitopsInclude@#1{\special{dvitops: prolog #1}}
189 \gdef\dvitopsRaw@#1{\special{dvitops: inline #1}}

190 %

191 \gdef\dvitopsOrigin@#1{\special{dvitops: origin #1}}
192 \gdef\dvitopsBegin@#1{\special{dvitops: begin #1}}
193 \gdef\dvitopsEnd@#1{\special{dvitops: end #1}}
194 \gdef\dvitopsRotate@x#1{\special{dvitops: rotate #1}}
195 \gdef\dvitopsTransform@x#1{\special{dvitops: transform #1}}
196 \gdef\dvitopsColor@x#1#2{\special{dvitops: #1 color #2}}

197 }

199 \catcode`\^^M=\active %
200 \gdef\next{\catcode`\^^M=\active \let^^M=\space }}%
201 \xylet@\obeyDVIPSlines@=\next

Rotations and transformations use a different mechanism, so \xyPScurrpt@@ can be set to

     \relax.

208 \xydef@\dvitopsCurrpt@{\global\let\xyPScurrpt@@=\relax}%

This installs the PostScript backend.

216 \xydef@\dvitopsPS@{\dvitopsPStypes@
217 \let\installxyps@@=\relax \installxyps@ }

• rotated/scaled diagrams and text, using dvitops specials; however these may not be nested.

228 \xydef@\dvitopsRotate@@{\dvitopsRotate@}
230 \xydef@\dvitopsRotate@{\dvitopsPStypes@
231 \expandafter\ifx\csname xyps-psloaded\endcsname\empty
232 \DN@{\xyinputorelse@{xyps-r}{\xydrivernoload@{ps-r}}%
233 \installDVITOPSrotate@ }%
234 \else\DN@{\xydriverfail@{rotations are}\UnloadRotate@\relax}\fi
235 \next@ }
237 \xydef@\dvitopsRotScale@{%
238 \def\xyrot@start{\dvitopsBegin@{rot}\dvitopsOrigin@{rot}}%
239 \def\xyrot@end(##1){\dvitopsEnd@{rot}\dvitopsRotate@x{##1}}%
240 \def\xyscale@start{\dvitopsBegin@{scal}\dvitopsOrigin@{scal}}%
241 \def\xyscale@end(##1,##2){%
242 \dvitopsEnd@{scal}\dvitopsTransform@x{##1 0 ##2 0}}%

243 }

245 \xydef@\installDVITOPSrotate@{\installPSstyle@
246 \let\xyRotate@@=\dvitopsRotate@
247 \let\doSpecialRotate@@=\dvitopsSpecialRotate@
248 \let\xyscale@@=\dvitopsScale@
249 \dvitopsCurrpt@
250 \dvitopsRotScale@ \xyPSshapes@true }
252 \xydef@\UnloadDVITOPSrotate@{\UnloadRotate@\relax}
256 \xydef@\dvitopsRotate@#1{\xyPSsplitPS@
257 {\dvitopsBegin@{rot}\dvitopsOrigin@{rot}}%
258 {\dvitopsEnd@{rot}\dvitopsRotate@x{#1}}}%
260 \xydef@\dvitopsScale@#1#2{\xyPSsplitPS@
261 {\dvitopsBegin@{scal}\dvitopsOrigin@{scal}}%
262 {\dvitopsEnd@{scal}\dvitopsTransform@x{#1 0 #2 0}}}
264 \xydef@\dvitopsSpecialRotate@#1@@{\dvitopsRotate@{#1}}

• variable line-widths and poly-lines, using PostScript.

271 \xydef@\dvitopsLine@@{\dvitopsLine@}
273 \xydef@\dvitopsLine@{\dvitopsPStypes@
274 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
275 \xyinputorelse@{xyps-l}{\xydrivernoload@{ps-l}}\installPSline@ }%
276 \else\DN@{\xydriverfail@{line-widths are}\UnloadLine@\relax}\fi
277 \next@ }

• extra frames and fills, using PostScript.

284 \xydef@\dvitopsFrames@@{\dvitopsFrames@}
286 \xydef@\dvitopsFrames@{\dvitopsPStypes@
287 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
288 \xyinputorelse@{xyps-f}{\xydrivernoload@{ps-f}}\installPSframes@ }%
289 \else\DN@{\xydriverfail@{frames are}\UnloadFrames@\relax}\fi
290 \next@ }

• patterns and tiles, using PostScript

297 \xydef@\dvitopsTiles@{\dvitopsPStypes@
298 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
299 \xyinputorelse@{xyps-t}{\xydrivernoload@{ps-t}}\installPSpatterns@ }%
300 \else\DN@{\xydriverfail@{Patterns are}\UnloadPSpatterns@\relax}\fi
301 \next@ }

• tpic drawing commands.

308 \xydef@\dvitopsTPIC@@{\dvitopsTPIC@}
310 \xydef@\dvitopsTPIC@{\setupxyTPIC@}

The end & Log

322 \xyendinput
324 % $Log: xydvitops.doc,v $
325 % Revision 3.3  1996/12/18  09:14:36  ross
326 % minor improvements to file-loading commands

327 %

328 % Revision 3.2  1995/09/19  18:21:41  ross
329 % Bug fix release.

330 %

331 % Revision 3.1  1995/09/05  20:28:57  ross
332 % Releasing version 3.1!

333 %

334 % NEW for version 3.

4.5 OzTeX driver

Vers. 3.3 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This driver provides the necessary interface to support the PostScript back-end and other Post-Script effects when using the DVI driver of versions 1.8+ of OzTEX by Andrew Trevorrow,^{1} Earlier versions of OzTEX should instead use the driver option \xyoption{17oztex}.

Effects such as colour, line-thickness and rotated or scaled diagrams are only partially supported in that the effects cannot be applied to any text or symbols placed using fonts. This is due to the nature of OzTEX ⟨driver⟩, whose optimization of the placement of font-characters precludes the applicability of such effects. Furthermore the PostScript dictionary must be available in a file called global.ps or appended to the OzTeXdict.pro. However with version 1.8 and later of OzTEX, there is the alternative of using the dvips ⟨driver⟩, which does support all the PostScript effects available in XY-pic.

Note: To use XY-pic effectively with OzTEX requires changing several memory parameters. In particular a ‘Big-TEX’ is needed, along with an increase in the pool_size parameter. Explicit instructions are contained in the file INSTALL.OzTeX of the XY-pic distribution.

Header:

1 %% $Id: xyoztex.doc,v 3.3 1996/12/18 09:26:26 ross Exp $
2 %%

1OzTEX is a shareware implementation of TEX for Macintosh available from many bulletin boards and ftp sites; v1.5 and earlier versions were freeware. Email contact: ⟨akt@kagi.com⟩.

4.5. OZTEX DRIVER 473

3 %% Xy-pic ``OzTeX'' driver interface option.
4 %% Copyright (c) 1995-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{oztex}{OzTeX driver}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}
59 \xydef@\OzTeX@@#1{\dvimessage@{OzTeX}{#1}}
61 \newdriver{%
62 \xyaddsupport{color}\oztexColor@@
63 \xyaddsupport{crayon}\oztexCrayon@@
64 \xyaddsupport{ps}\oztexPS@@
65 \xyaddsupport{rotate}\oztexRotate@@
66 \xyaddsupport{line}\oztexLine@@
67 \xyaddsupport{frame}\oztexFrames@@
68 \xyaddsupport{tile}\oztexTiles@@
69 \xyaddsupport{cmtip}\relax

70 }

Supported \special effects are...

• colour, using PostScript, but not of font-characters.

83 \xydef@\oztexColor@@{\OzTeXColours@}
85 \xydef@\OzTeXColours@{\OzTeXPStypes@
86 \let\xylocalColor@=\xyNoColor@@ \def\xycolor@{\xycolor@@}%
87 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%\XYpredict@
88  \xyinputorelse@{xyps-c}{\xydrivernoload@{ps-c}}%
89  \installPScolor@ }\else\DN@{}\fi \next@
90 \ifx\xycrayolaloaded\empty \DN@{\xystandardcolors@\OzTeXCrayon@@{}}%
91 \else\let\next@=\xystandardcolors@\fi \next@

92 \let\xycolorwarning@=\relax
93 \let\oztexColor@@=\relax
94 \let\UnloadColor@@=\NoOzTeXColor@

95 }

97 \xydef@\NoOzTeXColor@{%
98 \let\xylocalColor@=\xyNoColor@@
99 \let\xycolor@=\xyNoColor@
100 \let\xycolorwarning@=\xycolorwarning@@
101 \let\oztexColor@@=\OzTeXColours@
102 \let\UnloadColor@@=\UnloadColor@

103 }

• crayon colours, similarly restricted.

The 68 colours are those that dvips recognizes by name, thanks to Tomas Rokicki.

116 \xydef@\OzTeXCrayon@@{\installCrayolaColors@}

• PostScript back-end.

126 \xydef@\oztexPS@@{\oztexPS@}
128 \xydef@\oztexPSunload@{\UnloadPS@
129 \def\xyPSdictname{}\UsePSdict@@false
130 \let\installxyps@@=\relax
131 \let\UnloadPS@@=\UnloadPS@
132 \xyPSshapes@true
133 \let\oztexPS@@=\oztexPS@ }
137 \xydef@\OzTeXSpecial@#1{\special{empty.ps {#1}xy}}
138 \xydef@\OzTeXMacro@#1{\special{empty.ps {#1}xy}}
139 \xydef@\OzTeXDict@#1{\special{empty.ps @bxy{#1}stopped pop @exy}}
140 \xydef@\OzTeXinclude@#1{\special{#1}}
141 \xydef@\OzTeXraw@#1{\special{empty.ps @bxy #1 @exy}}%
143 \xydef@\OzTeXPStypes@{%
144 \xyinputorelse@{xyps-ps}{\xydrivernoload@{ps-ps}}%
145 \ifx\PSspecial@@\OzTeXSpecial@\else
146 \let\PSspecial@@=\OzTeXSpecial@
147 \let\PSmacro@@=\OzTeXMacro@
148 \let\PSdict@@=\OzTeXDict@
149 \let\PSraw@@=\OzTeXraw@
150 \let\PSinclude@@=\OzTeXinclude@
151 \let\xyPSobeylines@@=\obeyOzTeXlines@
152 \let\PSspecialdict@@=\OzTeXDict@
153 \OzTeX@@{PostScript}%
154 \fi
155 % \xyinputorelse@{xyps-ps}{\xydrivernoload@{ps-ps}}%
156 \OzTeXCurrpt@ }
158 {\catcode`\^^M=\active %
159 \gdef\next{\catcode`\^^M=\active \let^^M=\space \obeyspaces}}
160 \xylet@\obeyOzTeXlines@=\next

The PostScript operators @bxy and @exy are defined in xyps-ps for bypassing the mechanism used in OzTEX to isolate code passed in \special commands. Although it is possible (albeit difficult) to devise PostScript to deduce the current location for use with the “raw” specials, this information cannot be used to do rotations and scaling as with other ⟨driver⟩s. Hence the value of \xyPScurrpt@@ is taken to be empty.

171 \xydef@\OzTeXCurrpt@{\let\xyPScurrpt@@=\OzTeXCurrpt@@}%
172 \xydef@\OzTeXCurrpt@@{\PSraw@@{xyp}}

This avoids dumping the dictionary into the dvi-file, making sure that instead it goes into a file, specified by \xyPSdictname, which defaults to global.ps.

182 \xydef@\oztexPS@{\OzTeXPStypes@
183 \let\oztexPS@@=\relax
184 \let\UnloadPS@@=\oztexPSunload@
185 \let\installxyps@@=\@OzTeX@PS@
186 \installxyps@ }
188 \xydef@\@OzTeX@PS@{\UsePSdict@@true
189 \let\includePSmessage@=\xyOzTeXheader
190 \ifx\undefined\xyPSdictname\def\xyPSdictname{global.ps}\fi}
192 \xydef@\xyOzTeXheader#1#2#3{\UsePSdict@@true}

The parameters #1#2#3 of \xyOzTeXheader gobble tokens that are unnecessary with OzTEX.

• variable line-widths and poly-lines, using PostScript.

202 \xydef@\oztexLine@@{\oztexLine@}
204 \xydef@\oztexLine@{\OzTeXPStypes@
205 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%\XYpredict@
206 \xyinputorelse@{xyps-l}{\xydrivernoload@{ps-l}}\installPSline@ }%
207 \else\DN@{\xydriverfail@{line-styles are}\UnloadLine@\relax}\fi
208 \next@ }

• extra frames and fills, using PostScript.

215 \xydef@\oztexFrames@@{\OzTeXFrames@}
217 \xydef@\OzTeXFrames@{\OzTeXPStypes@
218 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
219 \xyinputorelse@{xyps-f}{\xydrivernoload@{ps-f}}\installPSframes@ }%
220 \else\DN@{\xydriverfail@{frames are}\UnloadPSFrames@\relax}\fi
221 \next@ }

• patterns and tiles, using PostScript.

228 \xydef@\oztexTiles@@{\OzTeXTiles@}
230 \xydef@\OzTeXTiles@{\OzTeXPStypes@
231 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
232 \xyinputorelse@{xyps-t}{\xydrivernoload@{ps-t}}\installPSpatterns@
233 \xystandardpatterns@ }%
234 \else\DN@{\xydriverfail@{Patterns are}\UnloadPSpatterns@\relax}\fi
235 \next@ }

• rotated/scaled diagrams and text, recognised but not supported.

In fact OzTEX cannot support rotations and scaling. Instead we go through all the motions of providing PostScript support, then set a flag that causes a limited number of warning messages to be generated as requests are made for these effects.

250 \xydef@\oztexRotate@@{\OzTeXRotate@}
252 \xydef@\OzTeXRotate@{\OzTeXPStypes@
253 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
254 \xyinputorelse@{xyps-r}{\xydrivernoload@{ps-r}}%
255 \OzTeXRotScale@ \installPSrotscale@ \xyPSshapes@false }%
256 \else\DN@{\xydriverfail@{rotations are}\UnloadRotate@\relax}\fi
257 \next@ }

This never worked properly. It requires too much hacking at Trevorrow’s code for little gain, since text-rotation can never work anyway. Use the dvips option instead!

265 \xydef@\OzTeXRotScale@{%
266 \def\xyrot@start(##1){%
267 {xyp xyt ##1\space xyr}{OzXy begin gsave}}%
268 \def\xyscale@start(##1,##2){%
269 {xyp xyt ##1\space##2\space xys}{OzXy begin gsave}}%
270 \def\xyrot@end{grestore end}\def\xyscale@end{grestore end}}

The default code will just do nothing as far as the output is concerned...

276 \let\OzTeXRotScale@=\xyRotScale@@

The end & Log

288 \xyendinput
290 % $Log: xyoztex.doc,v $
291 % Revision 3.3  1996/12/18  09:26:26  ross
292 % improvements to file-loading commands
293 % fixed missing @ bug

294 %

295 % Revision 3.2  1995/09/19  18:21:41  ross
296 % Bug fix release.

297 %

298 % Revision 3.1  1995/09/05  20:36:33  ross
299 % Release!

300 %

301 % Revision 3.0  1995/07/07  20:13:19  ross
302 % Major release w/new User's Guide!

303 %

304 % Revision 2.13  1995/07/04  15:04:51  ross
305 % Ready for release of v3.

306 %

307 % NEW for version 3.

4.6 OzTeX v1.7 driver

Vers. 3.3 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This option provides the necessary interface to support the PostScript back-end and other Post-Script effects when using the DVI driver of version 1.7 of OzTEX by Andrew Trevorrow,^{2} Later versions of OzTEX should instead use the driver option \xyoption{oztex}. Upgrading to version 1.9+ ofOzTEX is recommended.

Does not support rotations, scaling and coloured text within diagrams and the PostScript dictionary must be available in a file called global.ps.

Note: To use XY-pic effectively with OzTEX requires changing several memory parameters. In particular a ‘Big-TEX’ is needed, along with an increase in the pool_size parameter. Explicit instructions are contained in the file INSTALL.OzTeX of the XY-pic distribution.

Header:

1 %% $Id: xy17oztex.doc,v 3.3 1996/12/18 14:21:23 ross Exp $
2 %%
3 %% Xy-pic ``OzTeX v1.7'' driver interface option.
4 %% Copyright (c) 1995-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{17oztex}{OzTeX v1.7 driver}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

53 \xydef@\OzTeX@@#1{\dvimessage@{OzTeX v1.7}{#1}}
55 \newdriver{%
56 \xyaddsupport{color}\oldoztexColor@@

2OzTEX is a shareware implementation of TEX for Macintosh available from many bulletin boards and ftp sites; v1.5 and earlier versions were freeware. Email contact: ⟨akt@kagi.com⟩.

57 \xyaddsupport{crayon}\oldoztexCrayon@@
58 \xyaddsupport{ps}\oldoztexPS@@
59 \xyaddsupport{rotate}\oldoztexRotate@@
60 \xyaddsupport{line}\oldoztexLine@@
61 \xyaddsupport{frame}\oldoztexFrames@@
62 \xyaddsupport{tile}\oldoztexTiles@@
63 \xyaddsupport{cmtip}\relax

64 }

Supported \special effects are...

• colour, using PostScript, but not of font-characters.

78 \xydef@\oldoztexColor@@{\oldOzTeXColours@}
80 \xydef@\oldOzTeXColours@{\oldOzTeXPStypes@
81 \let\xylocalColor@=\xyNoColor@@ \def\xycolor@{\xycolor@@}%
82 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%\XYpredict@
83  \xyinputorelse@{xyps-c}{\xydrivernoload@{ps-c}}%
84  \installPScolor@ }\else\DN@{}\fi \next@
85 \ifx\xycrayolaloaded\empty \DN@{\xystandardcolors@\oldOzTeXCrayon@@{}}%
86 \else\let\next@=\xystandardcolors@\fi \next@
87 \let\xycolorwarning@=\relax
88 \let\oldoztexColor@@=\relax
89 \let\UnloadColor@@=\NooldOzTeXColor@

90 }

92 \xydef@\NooldOzTeXColor@{%
93 \let\xylocalColor@=\xyNoColor@@
94 \let\xycolor@=\xyNoColor@
95 \let\xycolorwarning@=\xycolorwarning@@
96 \let\oldoztexColor@@=\oldOzTeXColours@
97 \let\UnloadColor@@=\UnloadColor@

98 }

• crayon colours, similarly restricted.

The 68 colours are those that dvips recognizes by name, thanks to Tomas Rokicki.

111 \xydef@\oldOzTeXCrayon@@{\installCrayolaColors@}

• PostScript back-end.

121 \xydef@\oldoztexPS@@{\oldoztexPS@}
123 \xydef@\oldoztexPSunload@{\UnloadPS@
124 \def\xyPSdictname{}\UsePSdict@@false
125 \let\installxyps@@=\relax
126 \let\UnloadPS@@=\UnloadPS@
127 \xyPSshapes@true
128 \let\oldoztexPS@@=\oldoztexPS@ }
132 \xydef@\oldOzTeXSpecial@#1{\special{empty.ps {#1}xy}}
133 \xydef@\oldOzTeXMacro@#1{\special{empty.ps {#1}xy}}
134 \xydef@\oldOzTeXDict@#1{\special{empty.ps @obxy{#1}stopped pop @eoxy}}
135 \xydef@\oldOzTeXinclude@#1{\special{#1}}

136 \xydef@\oldOzTeXraw@#1{\special{empty.ps @boxy #1 @eoxy}}%
138 \xydef@\oldOzTeXPStypes@{%
139 \xyinputorelse@{xyps-ps}{\xydrivernoload@{ps-ps}}%
140 \ifx\PSspecial@@\oldOzTeXSpecial@\else
141 \let\PSspecial@@=\oldOzTeXSpecial@
142 \let\PSmacro@@=\oldOzTeXMacro@
143 \let\PSdict@@=\oldOzTeXDict@
144 \let\PSraw@@=\oldOzTeXraw@
145 \let\PSinclude@@=\oldOzTeXinclude@
146 \let\xyPSobeylines@@=\obeyoldOzTeXlines@
147 \let\PSspecialdict@@=\oldOzTeXDict@
148 \oldOzTeX@@{PostScript}%
149 \fi
150 % \xyinputorelse@{xyps-ps}{\xydrivernoload@{ps-ps}}%
151 \oldOzTeXCurrpt@ }
153 {\catcode`\^^M=\active %
154 \gdef\next{\catcode`\^^M=\active \let^^M=\space \obeyspaces}}
155 \xylet@\obeyoldOzTeXlines@=\next

The PostScript operators @boxy and @eoxy are defined in xyps-ps for bypassing the mechanism used in OzTEX to isolate code passed in \special commands. Although it is possible (albeit difficult) to devise PostScript to deduce the current location for use with the “raw” specials, this information cannot be used to do rotations and scaling as with other ⟨driver⟩s. Hence the value of \xyPScurrpt@@ is taken to be empty.

166 \xydef@\oldOzTeXCurrpt@{\let\xyPScurrpt@@=\OzTeXCurrpt@@}%
167 \xydef@\oldOzTeXCurrpt@@{}

This avoids dumping the dictionary into the dvi-file, making sure that instead it goes into a file, specified by \xyPSdictname, which defaults to global.ps.

177 \xydef@\oldoztexPS@@{\oldOzTeXPStypes@
178 \let\installxyps@@=\old@OzTeX@PS@
179 \installxyps@ }
181 % The parameter |#1| in this next macro is to gobble the |\dumpPSdict@|
182 % which would otherwise dump the dictionary into the dvi-file. However
183 % if |\xyPSdictname| is defined then this dump must occur into a file.

184 %

185 %\xydef@\old@OzTeX@PS@#1{%
186 % \let\includePSmessage@=\xyoldOzTeXheader
187 % \ifx\undefined\xyPSdictname\DN@{}%
188 % \else\DN@{#1}\fi\next@ \UsePSdict@@true}
190 \xydef@\old@OzTeX@PS@{\UsePSdict@@true
191 \let\includePSmessage@=\xyoldOzTeXheader
192 \ifx\undefined\xyPSdictname\def\xyPSdictname{global.ps}\fi}
194 \xydef@\xyoldOzTeXheader#1#2#3{\UsePSdict@@true}

The parameters #1#2#3 of \xyOzTeXheader gobble tokens that are unnecessary with OzTEX.

• variable line-widths and poly-lines, using PostScript.

204 \xydef@\oldoztexLine@@{\oldoztexLine@}
206 \xydef@\oldoztexLine@{\oldOzTeXPStypes@
207 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
208 \xyinputorelse@{xyps-l}{\xydrivernoload@{ps-l}}\installPSline@ }%
209 \else\DN@{\xydriverfail@{line-styles are}\UnloadLine@\relax}\fi
210 \next@ }

• extra frames and fills, using PostScript.

217 \xydef@\oldoztexFrames@@{\oldOzTeXFrames@}
219 \xydef@\oldOzTeXFrames@{\oldOzTeXPStypes@
220 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
221 \xyinputorelse@{xyps-f}{\xydrivernoload@{ps-f}}\installPSframes@ }%
222 \else\DN@{\xydriverfail@{frames are}\UnloadPSFrames@\relax}\fi
223 \next@ }

• patterns and tiles, using PostScript.

230 \xydef@\oldoztexTiles@@{\oldOzTeXTiles@}
232 \xydef@\oldOzTeXTiles@{\oldOzTeXPStypes@
233 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
234 \xyinputorelse@{xyps-t}{\xydrivernoload@{ps-t}}\installPSpatterns@
235 \xystandardpatterns@ }%
236 \else\DN@{\xydriverfail@{Patterns are}\UnloadPSpatterns@\relax}\fi
237 \next@ }

• rotated/scaled diagrams and text, recognised but not supported.

In fact OzTEX cannot support rotations and scaling. Instead we go through all the motions of providing PostScript support, then set a flag that causes a limited number of warning messages to be generated as requests are made for these effects.

252 \xydef@\oldoztexRotate@@{\oldOzTeXRotate@}
254 \xydef@\oldOzTeXRotate@{\oldOzTeXPStypes@
255 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%\XYpredict@
256 \xyinputorelse@{xyps-r}{\xydrivernoload@{ps-r}}%
257 \xyRotScale@@ \installPSrotscale@ \xyPSshapes@false }%
258 \else\DN@{\xydriverfail@{rotations are}\UnloadRotate@\relax}\fi
259 \next@ }

The end & Log

271 \xyendinput
273 % $Log: xy17oztex.doc,v $
274 % Revision 3.3  1996/12/18 14:21:23  ross
275 % Ross's version

276 %

277 % Revision 3.3.1.1  1996/12/18  08:47:45  ross
278 % *** empty log message ***

279 %

280 % Revision 3.2  1995/09/19  18:20:20  ross

281 % Bug fix release.

282 %

283 % Revision 3.1  1995/09/05  20:36:33  ross
284 % Release!

285 %

286 % Revision 3.0  1995/07/07  20:13:19  ross
287 % Major release w/new User's Guide!

288 %

289 % Revision 2.13  1995/07/04  15:04:51  ross
290 % Ready for release of v3.

291 %

292 % NEW for version 3.

4.7 Textures driver

Vers. 3.3 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This driver provides support for version 1.7+ of Blue Sky Research’s Textures application for Macintosh^{3}. It incorporates support for colour and all of XY-pic’s PostScript effects. Earlier versions of Textures should instead use the driver option \xyoption{16textures}.

Notice that version 1.7 suffers from a printing bug which may cause a PostScript error. A fix is kludged by making sure the first page has been shown in the viewer before any pages with diagrams are sent to the printer.

Header:

1 %% $Id: xytextures.doc,v 3.3 1996/12/18 09:41:45 ross Exp $
2 %%
3 %% Xy-pic ``Textures'' driver interface option.
4 %% Copyright (c) 1995-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.

3Macintosh is a trademark of Apple Computer Inc.

482 CHAPTER 4. DRIVERS

23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{textures}{Textures driver}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}
47 \xydef@\Textures@@#1{\dvimessage@{Textures}{#1}}
49 \newdriver{%
50 \xyaddsupport{color}\texturesColor@@
51 \xyaddsupport{crayon}\texturesCrayon@@
52 \xyaddsupport{ps}\texturesPS@@
53 \xyaddsupport{rotate}\texturesRotate@@
54 \xyaddsupport{line}\texturesLine@@
55 \xyaddsupport{frame}\texturesFrames@@
56 \xyaddsupport{tile}\texturesTiles@@
57 \xyaddsupport{cmtip}\relax

58 }

Supported \special effects are...

• colour, both on-screen and with PostScript Textures uses the colour-stack method, but it requires a separate \special to set the new colour after having pushed the previous colour onto the stack.

76 \xydef@\TexturesColor@push#1{\special{color push}\special{color #1}}
78 \xydef@\TexturesColours@{\texturesPStypes@
79 \let\xylocalColor@=\xystackcolor@
80 \let\xycolor@push=\TexturesColor@push
81 \def\xycolor@{\xycolor@@}%
82 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
83  \xyinputorelse@{xyps-c}{\xydrivernoload@{ps-c}}%
84  \installPScolor@ }\else\DN@{}\fi \next@
85 \ifx\xycolor@@\xyNoColor@ \let\xycolor@@=\xycolor@raw@@\fi
86 \ifx\xycrayolaloaded\empty \DN@{\xystandardcolors@\texturesCrayon@@{}}%
87 \else\let\next@=\xystandardcolors@ \fi \next@
88 \let\xycolorwarning@=\relax \Textures@@{color}%
89 \let\texturesColor@@=\relax
90 \let\UnloadColor@@=\NoTexturesColor@

91 }

93 \xydef@\texturesColor@@{\TexturesColours@}
95 \xydef@\NoTexturesColor@{%
96 \let\xylocalColor@=\xyNoColor@@
97 \let\xycolor@=\xyNoColor@
98 \let\xycolorwarning@=\xycolorwarning@@
99 \let\texturesColor@@=\TexturesColours@
100 \let\UnloadColor@@=\UnloadColor@

101 }

• crayon colours.

The 68 colours are those that dvips recognizes by name, thanks to Tomas Rokicki.

114 \xydef@\texturesCrayon@@{\texturesColor@@\texturesCrayon@}
115 \xydef@\texturesCrayon@{\installCrayolaColors@}%

• PostScript back-end.

123 \xydef@\texturesPS@@{\texturesPS@}
124 \xydef@\texturesPSunload@{\UnloadPS@
125 \let\UnloadPS@@=\UnloadPS@
126 \let\texturesPS@@=\texturesPS@ }

Versions 1.7 and later of Textures have the following kinds of \special, the first two executing in the environment defined by the dictionary userdict. In particular these versions of Textures now allow the PostScript dictionary to be loaded into the main working dictionary.

– \special{rawpostscript #1} puts code directly into the PostScript file.

– \special{postscript #1} wraps the code within sps...eps, which involves a basis change

         within a save/restore pair.

– \special{prePostScript #1} places the PostScript code within the header dictionary,

         called TeXdict.

Each of these has a corresponding version for reading the PostScript commands from a file.

147 \xydef@\texturesPStypes@{%
148 \xyinputorelse@{xyps-ps}{\xydrivernoload@{ps-ps}}%
149 \ifx\PSspecial@@\TexturesSpecial@\else
150 \let\PSspecial@@=\TexturesSpecial@
151 \let\PSmacro@@=\TexturesMacro@
152 \let\PSdict@@=\TexturesDict@
153 \let\PSraw@@=\TexturesRaw@
154 \let\PSinclude@@=\TexturesInclude@
155 \let\PSspecialdict@@=\TexturesSpecialDict@
156 \let\xyPSobeylines@@=\obeyTextureslines@
157 \Textures@@{PostScript}%
158 \fi \texturesCurrpt@ \XYpredict@ }
160 \xydef@\TexturesSpecial@#1{\firstPS@@\special{postscript #1}}
161 \xydef@\TexturesMacro@#1{\special{postscript {#1}xy}}
162 \xydef@\TexturesDict@#1{\special{prePostScript #1}}
163 \xydef@\TexturesSpecialDict@#1{\special{prePostScript #1}}
164 \xydef@\TexturesInclude@#1{\firstPS@@\special{prePostScriptfile #1}}
165 \xydef@\TexturesRaw@#1{\firstPS@@\special{rawpostscript #1}}%
167 {\catcode`\^^M=\active%
168 \gdef\next{\catcode`\^^M=\active \let^^M=\par%
169 \let\PSspecial@@=\TexturesDict@ \obeyspaces}}
170 \xylet@\obeyTextureslines@=\next

The currentpoint is defined for the “raw” specials. For Textures this is the same as \xyPScurrpt@@@,

     in xyps-ps.doc.

177 \xydef@\texturesCurrpt@{\let\xyPScurrpt@@=\texturesCurrpt@@}%
178 \xydef@\texturesCurrpt@@{\PSspecial@@{xyi}\PSraw@@{userdict begin xyx end}}

180 %\xydef@\texturesCurrpt@@{\PSspecial@@{%
181 % 0 0 transform grestore gsave itransform }%
182 % \PSraw@@{userdict begin /xyYpos exch def /xyXpos exch def end}}

The PostScript operator called xyx is defined in xyps-ps for storing the location placed on the stack by xyi.

This installs the PostScript backend.

193 \xydef@\texturesPS@{\texturesPStypes@
194 \let\texturesPS@@=\relax
195 \let\UnloadPS@@=\texturesPSunload@
196 \let\installxyps@@=\relax \installxyps@ }

• rotated/scaled diagrams and text, using PostScript.

203 \xydef@\texturesRotate@@{\texturesRotate@}
205 \xydef@\texturesRotate@{\texturesPStypes@
206 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
207 \xyinputorelse@{xyps-r}{\xydrivernoload@{ps-r}}%
208 \xyRotScale@@ \installPSrotscale@ }%
209 \else\DN@{\xydriverfail@{rotations are}\UnloadRotate@\relax}\fi
210 \next@}

• variable line-widths and poly-lines, using PostScript.

217 \xydef@\texturesLine@@{\texturesLine@}
219 \xydef@\texturesLine@{\texturesPStypes@
220 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
221 \xyinputorelse@{xyps-l}{\xydrivernoload@{ps-l}}%
222 \installPSline@ }%
223 \else\DN@{\xydriverfail@{line-widths are}\UnloadLine@\relax}\fi
224 \next@ }

• extra frames and fills, using PostScript.

231 \xydef@\texturesFrames@@{\texturesFrames@}
233 \xydef@\texturesFrames@{\texturesPStypes@
234 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
235 \xyinputorelse@{xyps-f}{\xydrivernoload@{ps-f}}%
236 \installPSframes@ }%
237 \else\DN@{\xydriverfail@{frames are}\UnloadPSFrames@\relax}\fi
238 \next@ }

• patterns and tiles, using PostScript.

245 \xydef@\texturesTiles@@{\texturesTiles@}
247 \xydef@\texturesTiles@{\texturesPStypes@
248 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
249 \xyinputorelse@{xyps-t}{\xydrivernoload@{ps-t}}%
250 \installPSpatterns@ \xystandardpatterns@}%
251 \else\DN@{\xydriverfail@{Patterns are}\UnloadPSpatterns@\relax}\fi

252 \next@ }

The end & Log

264 \xyendinput
266 % $Log: xytextures.doc,v $
267 % Revision 3.3  1996/12/18  09:41:45  ross
268 % minor improvements to file-loading commands

269 %

270 % Revision 3.2  1995/09/19  18:21:41  ross
271 % Bug fix release.

272 %

273 % Revision 3.1  1995/09/05  20:36:33  ross
274 % Release!

275 %

276 % Revision 3.0  1995/07/07  20:13:19  ross
277 % Major release w/new User's Guide!

278 %

279 % Revision 2.13  1995/07/04  15:04:51  ross
280 % Ready for release of v3.

281 %

282 % NEW for version 3.

4.8 Textures v1.6 driver

Vers. 3.3 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This driver provides support for versions 1.5b and 1.6 of Blue Sky Research’s Textures application for Macintosh^{4}. It incorporates support for PostScript colour and the XY-ps PostScript back-end. This will not work with versions 1.7 and later; these require the ⟨driver⟩ option \xyoption{textures}.

Header:

1 %% $Id: xy16textures.doc,v 3.3 1996/12/18 14:21:23 ross Exp $
2 %%
3 %% Xy-pic ``Textures v1.6'' driver interface option.
4 %% Copyright (c) 1995-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but

4Macintosh is a trademark of Apple Computer Inc.

486 CHAPTER 4. DRIVERS

16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{16textures}{Textures v1.6 driver}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}
43 \xydef@\oldTextures@@#1{\dvimessage@{Textures v1.6}{#1}}
45 \newdriver{%
46 \xyaddsupport{color}\oldtexturesColor@@
47 \xyaddsupport{crayon}\oldtexturesCrayon@@
48 \xyaddsupport{ps}\oldtexturesPS@@
49 \xyaddsupport{rotate}\oldtexturesRotate@@
50 \xyaddsupport{line}\oldtexturesLine@@
51 \xyaddsupport{frame}\oldtexturesFrames@@
52 \xyaddsupport{tile}\oldtexturesTiles@@
53 \xyaddsupport{cmtip}\relax

54 }

Supported \special effects are...

• colour, using PostScript Textures v1.6 cannot manage colours, except within imported graphics. It can put colours into the PostScript output.

71 \xydef@\oldTexturesColours@{\oldtexturesPStypes@
72 \let\xylocalColor@=\xyNoColor@@ \def\xycolor@{\xycolor@@}%
73 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
74  \xyinputorelse@{xyps-c}{\xydrivernoload@{ps-c}}%
75  \installPScolor@ }\else\DN@{}\fi \next@
76 \ifx\xycolor@@\xyNoColor@ \let\xycolor@@=\xycolor@raw@@\fi
77 \ifx\xycrayolaloaded\empty \DN@{\xystandardcolors@\oldtexturesCrayon@@{}}%
78 \else\let\next@=\xystandardcolors@ \fi \next@
79 \let\xycolorwarning@=\relax
80 \let\oldtexturesColor@@=\relax
81 \let\UnloadColor@@=\NooldTexturesColor@

82 }

84 \xydef@\oldtexturesColor@@{\oldTexturesColours@}
86 \xydef@\NooldTexturesColor@{%
87 \let\xylocalColor@=\xyNoColor@@
88 \let\xycolor@=\xyNoColor@
89 \let\xycolorwarning@=\xycolorwarning@@
90 \let\oldtexturesColor@@=\oldTexturesColours@

91 \let\UnloadColor@@=\UnloadColor@

92 }

• crayon colours.

The 68 colours are those that dvips recognizes by name, thanks to Tomas Rokicki.

105 \xydef@\oldtexturesCrayon@@{\oldtexturesColor@@\oldtexturesCrayon@}
106 \xydef@\oldtexturesCrayon@{\installCrayolaColors@}%

• PostScript back-end.

113 \xydef@\oldtexturesPS@@{\oldtexturesPS@}
115 \xydef@\oldtexturesPSunload@{\UnloadPS@
116 \ifx\xyrealshipout@\undefined\else
117 \ifx\shipout\xyrealshipout@
118 \else \let\shipout=\xyrealshipout@\fi\fi
119 \let\installxyps@@=\relax
120 \let\UnloadPS@@=\UnloadPS@
121 \let\oldtexturesPS@@=\oldtexturesPS@ }

We must return the binding of \shipout to its initial value.

Early versions (1.5–1.6) of Textures have two kinds of \special, for inserting PostScript code into the dvi-file and two more for reading such code from a file:

– \special{rawpostscript #1} puts code directly into the PostScript file.

– \special{postscript #1} wraps the code within sps...eps, which involves graphics state changes within a gsave/grestore pair.

Each of these has a corresponding version for reading the PostScript commands from a file.

143 \xydef@\oldTexturesSpecial@#1{\firstPS@@\special{postscript #1}}
144 \xydef@\oldTexturesMacro@#1{\special{postscript {#1}xy}}
145 \xydef@\oldTexturesInclude@#1{\firstPS@@\special{rawpostscriptfile #1}}
146 \xydef@\oldTexturesRaw@#1{\firstPS@@\special{rawpostscript #1}}
148 \xydef@\oldtexturesPStypes@{%
149 \xyinputorelse@{xyps-ps}{\xydrivernoload@{ps-ps}}%
150 \ifx\PSspecial@@\oldTexturesSpecial@\else
151 \let\PSspecial@@=\oldTexturesSpecial@
152 \let\PSmacro@@=\oldTexturesMacro@
153 \let\PSdict@@=\oldTexturesRaw@
154 \let\PSraw@@=\oldTexturesRaw@
155 \let\PSinclude@@=\oldTexturesInclude@
156 \let\PSspecialdict@@=\oldTexturesRaw@
157 \let\xyPSobeylines@@=\obeyoldTextureslines@
158 \oldTextures@@{PostScript}%
159 \fi
160 % \xyinputorelse@{xyps-ps}{\xydrivernoload@{ps-ps}}%
161 \oldtexturesCurrpt@ \@PSshipout }
163 {\catcode`\^^M=\active %
164 \gdef\next{\catcode`\^^M=\active \let^^M=\par \obeyspaces}}

165 \xylet@\obeyoldTextureslines@=\next

The currentpoint is defined for the “raw” specials. For Textures this is the same as \xyPScurrpt@@@,

     in xyps-ps.doc.

172 \xydef@\oldtexturesCurrpt@{\let\xyPScurrpt@@=\oldtexturesCurrpt@@}%
173 \xydef@\oldtexturesCurrpt@@{\PSspecial@@{xyi}\PSraw@@{userdict begin xyx end}}

The PostScript operator called xyx is defined in xyps-ps for storing the location placed on the stack by xyi.

Textures v1.6 requires the PostScript dictionary to be shipped-out with every page. To achieve this efficiently we rebind \shipout, as described in xyps-ps.doc. Next set the flag \UsePSdict@@true after having rebound \includePSmessage@ to gobble the attempt to load the dictionary directly into the dvi-file.

This installs the PostScript backend.

190 \xydef@\oldtexturesPS@{\oldtexturesPStypes@
191 \let\oldtexturesPS@@=\relax
192 \let\UnloadPS@@=\oldtexturesPSunload@
193 \let\installxyps@@=\@PSshipout \installxyps@ }

• rotated/scaled diagrams and text, using PostScript.

201 \xydef@\oldtexturesRotate@@{\oldtexturesRotate@}
203 \xydef@\oldtexturesRotate@{\oldtexturesPStypes@
204 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
205 \xyinputorelse@{xyps-r}{\xydrivernoload@{ps-r}}%
206 \xyRotScale@@ \installPSrotscale@ }%
207 \else\DN@{\xydriverfail@{rotations are}\UnloadRotate@\relax}\fi
208 \next@ }

• variable line-widths and poly-lines, using PostScript.

215 \xydef@\oldtexturesLine@@{\oldtexturesLine@}
217 \xydef@\oldtexturesLine@{\oldtexturesPStypes@
218 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
219 \xyinputorelse@{xyps-l}{\xydrivernoload@{ps-l}}%
220 \installPSline@ }%
221 \else\DN@{\xydriverfail@{line-styles are}\UnloadLine@\relax}\fi
222 \next@ }

• extra frames and fills, using PostScript.

229 \xydef@\oldtexturesFrames@@{\oldtexturesFrames@}
231 \xydef@\oldtexturesFrames@{\oldtexturesPStypes@
232 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
233 \xyinputorelse@{xyps-f}{\xydrivernoload@{ps-f}}%
234 \installPSframes@ }%
235 \else\DN@{\xydriverfail@{frames are}\UnloadPSFrames@\relax}\fi
236 \next@ }

• patterns and tiles, using PostScript.

243 \xydef@\oldtexturesTiles@@{\oldtexturesTiles@}
245 \xydef@\oldtexturesTiles@{\oldtexturesPStypes@
246 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
247 \xyinputorelse@{xyps-t}{\xydrivernoload@{ps-t}}%
248 \installPSpatterns@ \xystandardpatterns@}%
249 \else\DN@{\xydriverfail@{Patterns are}\UnloadPSpatterns@\relax}\fi
250 \next@ }

The end & Log

262 \xyendinput
264 % $Log: xy16textures.doc,v $
265 % Revision 3.3  1996/12/18 14:21:23  ross
266 % Ross's version

267 %

268 % Revision 3.3.1.1  1996/12/18  08:45:28  ross
269 % *** empty log message ***

270 %

271 % Revision 3.2  1995/09/19  18:20:20  ross
272 % Bug fix release.

273 %

274 % Revision 3.1  1995/09/05  20:36:33  ross
275 % Release!

276 %

277 % Revision 3.0  1995/07/07  20:13:19  ross
278 % Major release w/new User's Guide!

279 %

280 % Revision 2.13  1995/07/04  15:04:51  ross
281 % Ready for release of v3.

282 %

283 % NEW for version 3.

4.9 XDVI driver

Vers. 3.3 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

This driver provides support for extensions when using variants of the xdvi driver, by Eric Cooper, Bob Scheifler, Mark Eichin and others. It has been used successfully with xdvi patchlevel 20, by Paul Vojta, and xdvik version 18f, by Karl Berry.

Some of the supported features assume that the implementation of xdvi is linked to a PostScript renderer; e.g. Ghostscript or Display PostScript. If such support is not available, then invoking xdvi using the command xdvi -hushspecials will suppress warning messages that might otherwise be produced. One drawback of such a setup is that much of the PostScript is not rendered until after all of the font characters, etc. have been placed on the page. Thus text that was meant to be placed on top of a filled or patterned region may appear to be obscured by it. However when printed, using a PostScript printer, the correct placement is obtained.

Header:

1 %% $Id: xyxdvi.doc,v 3.3 1996/12/18 09:53:22 ross Exp $
2 %%
3 %% Xy-pic ``xdvi-driver'' option.
4 %% Copyright (c) 1995-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{xdvi}{XDVI driver}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

56 \xydef@\xdvi@@#1{\dvimessage@{xdvi}{#1}}
58 \newdriver{%
59 \xyaddsupport{color}\xdviColor@@
60 \xyaddsupport{crayon}\xdviCrayola@@
61 \xyaddsupport{ps}\xdviPS@@
62 \xyaddsupport{rotate}\xdviRotate@@
63 \xyaddsupport{line}\xdviLine@@
64 \xyaddsupport{frame}\xdviFrames@@
65 \xyaddsupport{tile}\xdviTiles@@
66 \xyaddsupport{tpic}\xdviTPIC@

67 }

Driver installation Supported \special effects are...

• colour, using PostScript. Not all versions of xdvi support color \specials, so there is no direct support for colour. However parts of pictures rendered using PostScript may appear coloured, due to interpretation of colour commands within the PostScript. Disable the \xylocalColor@ but enable the \xycolor@ for use by PostScript.

87 \xydef@\xdvi@Color@{\xdviPStypes@
88 \let\xylocalColor@=\xyNoColor@@
89 % \let\xylocalColor@=\xystackcolor@
90 % \let\xycolor@push\xycolor@push@@
91 \def\xycolor@{\xycolor@@}\let\xycolorwarning@=\relax
92 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
93  \xyinputorelse@{xyps-c}{\xydrivernoload@{ps-c}}\installPScolor@ }%
94 \else\DN@{}\fi \next@
95 \ifx\xycolor@@\xyNoColor@ \let\xycolor@@=\xycolor@raw@@\fi
96 \ifx\xycrayolaloaded\empty \DN@{\xystandardcolors@\xdviCrayola@{}}%
97 \else \DN@{\xystandardcolors@}\fi \next@
98 \let\xdviColor@@=\relax
99 \let\UnloadColor@@=\NoXDVIcolor@

100 }%

102 \xydef@\xdviColor@@{\xdvi@Color@}
104 \xydef@\NoXDVIcolor@{%
105 \def\xycolor@{\xycolor@@}%
106 \let\xycolor@@=\xyNoColor@
107 \let\xylocalColor@=\xyNoColor@@
108 \let\xycolorwarning@=\xycolorwarning@@
109 \let\xdviColor@@=\xdvi@Color@
110 \let\UnloadColor@@=\UnloadColor@

111 }

If neither support file colordvi.tex nor colordvi.sty can be found, then the normal colour support will not be available. However the colour support for the PostScript back-end can still be used.

119 \xydef@\NoXDVIcolordvi@{\xywarning@{%
120 Neither  colordvi.tex  nor  colordvi.sty  could be found.}%
121 \xyBEcolorcheck@}%

• crayon colours.

The 68 colours that xdvi recognizes by name are not loaded unless the crayon option has been requested.

134 \xydef@\xdviCrayola@@{\xdviColor@@\xdviCrayola@}
136 \xydef@\xdviCrayola@{%
137 \let\prevxycolor@=\newxycolor@
138 \def\newxyXDVIcolor@##1##2##3{\prevxycolor@{##1}{}{##1}}%
139 \let\newxycolor@=\newxyXDVIcolor@
140 \installCrayolaColors@
141 \let\newxycolor@=\prevxycolor@ }%

Although any order of loading options: ps, xdvi, color and crayon produces the desired result visually, the PostScript code can be different with different loading order. The most easily readable is obtained when crayon is requested last.

• PostScript back-end.

153 \xydef@\xdviPS@@{\xdviPS@}

155 \xydef@\xdviPS@unload{\UnloadPS@
156 \let\UnloadPS@@=\UnloadPS@
157 \let\xdviPS@@=\xdviPS@ }

The latest versions of xdvi recognise most forms of \special command that are recognised by

dvips; these are used to support PostScript effects.

166 \xydef@\xdviPStypes@{%
167 \xyinputorelse@{xyps-ps}{\xydrivernoload@{ps-ps}}%
168 \ifx\PSspecial@@\xdviSpecial@\else
169 \let\PSspecial@@=\xdviSpecial@
170 \let\PSmacro@@=\xdviMacro@
171 \let\PSdict@@=\xdviDict@
172 \let\PSspecialdict@@=\xdviDict@
173 \let\PSraw@@=\xdviRaw@
174 \let\PSinclude@@=\xdviInclude@
175 \let\xyPSobeylines@@=\obeyXDVIlines@
176 \let\xyPScurrpt@@=\xdviCurrpt@@
177 \xdvi@@{PostScript}%
178 \fi \XYpredict@ }
180 \xywarnifdefined\xdviSpecial@
181 \xywarnifdefined\xdviMacro@
182 \xywarnifdefined\xdviDict@
183 \xywarnifdefined\xdviInclude@
184 \xywarnifdefined\xdviRaw@
185 {\catcode`\"=11 \catcode`\!=11 \catcode`\:=11
186 \gdef\xdviSpecial@#1{\special{ps:: SDict begin #1 end}}
187 \gdef\xdviMacro@#1{\firstPS@@\special{" {#1}xy}}
188 % \gdef\xdviDict@#1{\special{! mark{#1}stopped cleartomark}}
189 \gdef\xdviDict@#1{\special{! #1}}
190 \gdef\xdviInclude@#1{\special{header=#1}}
191 \gdef\xdviRaw@#1{\special{ps: SDict begin #1 end}}
193 \catcode`\^^M=\active %
194 \gdef\next{\catcode`\^^M=\active \let^^M=\space }}%
195 \xylet@\obeyXDVIlines@=\next

All the PostScript definitions passed to xdvi by reading the dictionary file are stored in a PostScript dictionary which it defines, called SDict. This must be the current dictionary whenever an XY-ps command is to be executed. This will be the case whenever the \special{" commands} or \special{! commands} forms are used, but not when the \special{ps:: commands} form is used. Thus the \xdviSpecial@ macro includes code to open SDict and close it when finished; so also does the \xdviRaw@ type, since this is used with XY-pic PostScript operators whose definitions have been placed within SDict.

The currentpoint is defined for the “raw” specials.

213 \xydef@\xdviCurrpt@{\let\xyPScurrpt@@=\xdviCurrpt@@}%
214 \xydef@\xdviCurrpt@@{\PSraw@@{xyp}}

The PostScript operator called xyp is defined in xyps-ps for storing the location read from

     currentpoint.

4.9. XDVI DRIVER 493

This installs the PostScript backend.

225 \xydef@\xdviPS@{\xdviPStypes@
226 \let\xdviPS@@=\PSspecials@true
227 \let\UnloadPS@@=\xdviPS@unload
228 \let\installxyps@@=\relax \installxyps@ }

• rotated/scaled diagrams and text, using PostScript.

235 \xydef@\xdviRotate@@{\xdviRotate@}
237 \xydef@\xdviRotate@{\xdviPStypes@
238 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
239 \xyinputorelse@{xyps-r}{\xydrivernoload@{ps-r}}%
240 \xdviCurrpt@ \xdviRotScale@ \installPSrotscale@ }%
241 \else\DN@{\xydriverfail@{rotations are}UnloadRotate@\relax}\fi
242 \next@ }
244 \xydef@\xdviRotScale@{%
245 \def\xyrot@start(##1){{xyct ##1\space xyrs }}%
246 \def\xyrot@end{}%
247 \def\xyscale@start(##1,##2){{xyct ##1\space##2\space xyss }}%
248 \def\xyscale@end{}}

• variable line-widths and poly-lines, using PostScript.

255 \xydef@\xdviLine@@{\xdviLine@}
257 \xydef@\xdviLine@{\xdviPStypes@
258 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
259 \xyinputorelse@{xyps-l}{\xydrivernoload@{ps-l}}\installPSline@ }%
260 \else\DN@{\xydriverfail@{line-widths are}\UnloadLine@\relax}\fi
261 \next@ }

• extra frames and fills, using PostScript.

268 \xydef@\xdviFrames@@{\xdviFrames@}
270 \xydef@\xdviFrames@{\xdviPStypes@
271 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
272 \xyinputorelse@{xyps-f}{\xydrivernoload@{ps-f}}\installPSframes@ }%
273 \else\DN@{\xydriverfail@{frames are}\UnloadFrames@\relax}\fi
274 \next@ }

• patterns and tiles, using PostScript.

281 \xydef@\xdviTiles@@{\xdviTiles@}
283 \xydef@\xdviTiles@{\xdviPStypes@
284 \expandafter\ifx\csname xyps-psloaded\endcsname\empty\DN@{%
285 \xyinputorelse@{xyps-t}{\xydrivernoload@{ps-t}}\installPSpatterns@ }%
286 \else\DN@{\xydriverfail@{Patterns are}\UnloadPSpatterns@\relax}\fi
287 \next@ }

• tpic drawing commands.

294 \xydef@\xdviTPIC@@{\xdviTPIC@}

494 CHAPTER 4. DRIVERS

296 \xydef@\xdviTPIC@{\setupxyTPIC@}

The end & Log

308 \xyendinput
310 % $Log: xyxdvi.doc,v $
311 % Revision 3.3  1996/12/18  09:53:22  ross
312 % minor improvements to file-loading commands

313 %

314 % Revision 3.2  1995/09/19  18:21:41  ross
315 % Bug fix release.

316 %

317 % Revision 3.1  1995/09/05  20:28:57  ross
318 % Releasing version 3.1!

319 %

320 % Revision 3.0  1995/07/07  20:13:19  ross
321 % Major release w/new User's Guide!

322 %

323 % Revision 2.13  1995/07/04  15:04:51  ross
324 % Ready for release of v3.

325 %

326 % NEW for version 3.

4.10 CMacTeX driver

Vers. 3.3 by Ross Moore ⟨ross@mpce.mq.edu.au⟩

Thomas Kiffe’s CMacTEX application uses dvips as its dvi-driver. Header:

1 %% $Id: xycmactex.doc,v 3.3 1996/12/18 08:54:25 ross Exp $
2 %%
3 %% Xy-pic ``CMacTeX'' driver interface option.
4 %% Copyright (c) 1995-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.

19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{cmactex}{CMacTeX driver}{\stripRCS$Revision: 3.3 $}%
27 {Ross Moore}{ross@mpce.mq.edu.au}%
28 {Mathematics Department, Macquarie University, NSW~2109, Australia}

39 \xyrequire{dvips}

The end & Log

47 \xyendinput
49 % $Log: xycmactex.doc,v $
50 % Revision 3.3  1996/12/18  08:54:25  ross
51 % no changes

52 %

53 % Revision 3.1  1995/09/05 20:28:57  ross
54 % Releasing version 3.1!

55 %

56 % Revision 3.0  1995/07/07  20:13:19  ross
57 % Major release w/new User's Guide!

58 %

59 % Revision 2.13  1995/07/04  15:04:51  ross
60 % Ready for release of v3.

61 %

62 % NEW for version 3.

4.11 Extra features with PostScript support

4.11.1 xyps-ps.doc

The included file xyps-ps.tex (version3.7) provides support for PostScript \special commands used by the ps backend extension as well as PostScript-based options, to produce special effects not available directly with TEX.

Header:

1 %% $Id: xyps-ps.doc,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %%
3 %% Xy-pic ``PS-PS'' PostScript support.
4 %% Copyright (c) 1993-1997      Ross Moore      <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997      Kristoffer H. Rose  <krisrose@ens-lyon.fr>

496 CHAPTER 4. DRIVERS

9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 %% As a special exception, you may use this file and all files derived
25 %% from it without restrictions.  This special exception was added with
26 %% version 3.7 of Xy-pic.
27 %%
28 \expandafter\ifx\csname xyps-psloaded\endcsname\empty
29 \message{not reloaded}\endinput \fi
30 \expandafter\let\csname xyps-psloaded\endcsname=\empty \xycatcodes

PostScript \special commands The PostScript \specials which are used by XY-ps fall into four broad classes:

1. execute a piece of code, e.g. to draw some graphic object;

2. add a new PostScript definition to the existing dictionary of commands;

3. change the value of some parameters, storing them for later use; and

4. read PostScript commands from a pre-existing file.

Since different drivers may provide different syntax for these classes of command, XY-ps has different macros to optimize to interface to the different drivers. Initially these control-sequence names are bound to macros that do nothing. Upon specifying a driver, they will be bound to a macro appropriate for that driver.

62 \xylet@\PSmacro@@=\eat@
63 \xylet@\PSdict@@=\eat@
64 \xylet@\PSspecial@@=\eat@
65 \xylet@\PSread@@=\eat@
66 \xylet@\PSinclude@@=\eat@
67 \xylet@\PSraw@@=\eat@
68 \xylet@\xyPSobeylines@@=\relax
69 \xylet@\PSspecialdict@@=\eat@
71 \xydef@\UnloadPSps@{%
72 \let\PSmacro@@=\eat@
73 \let\PSdict@@=\eat@

74 \let\PSspecial@@=\eat@
75 \let\PSread@@=\eat@
76 \let\PSinclude@@=\eat@
77 \let\PSraw@@=\eat@
78 \let\xyPSobeylines@@=\relax
79 \let\PSspecialdict@@=\eat@

80 }

Unloading PostScript requires also turning off the PostScript-backend, if it has been loaded.

87 \xydef@\UnloadPS@{\UnloadPSps@
88 \expandafter\ifx\csname xypsloaded\endcsname\unknown\PSspecials@false
89 \else\expandafter\NoPSspecials\fi}
90 \xylet@\UnloadPS@@=\UnloadPS@
92 %\xyaddunsupport{ps}\UnloadPS@@
96 \ifx\undefined\dvitype@\xydef@\dvitype@{null}\fi

Some drivers, in particular versions of Textures earlier than 1.7, require the PostScript dictionary to be included with every page shipped out. We do this by providing a routine which rebinds the \shipout primitive to a macro \xyPSshipout@ which prepends the XY-ps PostScript dictionary to the box being shipped-out. This routine \@PSshipout is called, if necessary, when the driver has been specified.

109 \xylet@\xyrealshipout@=\shipout
110 \xydef@\xyPSshipout@{\setbox9=\copy\voidb@x
111 \afterassignment\xyPSshipout@i\setbox9=}
112 \xydef@\xyPSshipout@i{\ifvoid9 \expandafter\aftergroup\fi\xyPSshipout@ii}
113 \xydef@\xyPSshipout@ii{\xyrealshipout@\vbox{\XYpredict@@\box9}}
115 \xydef@\@PSshipout{\global\let\shipout=\xyPSshipout@ }

The box register \box9 is assumed to be a scratch register, used globally according to TEX conventions.

When the PostScript backend is loaded then we need to rebind \shipout to include the full dictionary.

125 \xydef@\xyPSshipout@PSii{%
126 \ifUsePSdict@@\let\XYshipdict@=\includeXYPSdict@@
127 \else\def\XYshipdict@{\XYpredict@@\XYdict@@}\fi
128 \xyrealshipout@\vbox{\XYshipdict@\box9}}

These two control sequences are used in the DVI-driver files to control when the PostScript ⟨driver⟩ can be altered.

137 \xydef@\firstPS@{%\fixedxydriver@
138 \global\let\firstPS@@=\relax \global\let\firstPS@=\relax}
139 \xylet@\firstPS@@=\firstPS@

4.11.2 Installation

To install use of PostScript requires loading the PostScript dictionary. However this can only be done when a ⟨driver⟩ is known to be able to support it. Hence the \installxyps@ command should be called only from within a ⟨driver⟩-file.

Furthermore, the ⟨driver⟩-file should define a value for \installxyps@@ to including anything specific to that ⟨driver⟩; even if only \let\installxyps@@=\relax. If \dumpPSdict has been specified, then the dictionary must be written first, so it can be used with the subsequent processing (see the subsection below).

158 \ifx\undefined\dumpPSdict@@ \xylet@\dumpPSdict@@=\relax \fi
160 \xydef@\installxyps@{%
161 \xyinputorelse@{xyps-ps}{\xydrivernoload@{ps-ps}}\xycatcodes
162 \installxyps@@ \installxyps@x }
164 \xylet@\installxyps@@=\relax
165 \xylet@\setupxyPS@@=\relax
166 \xywithoption{ps}{\let\setupxyPS@@=\setupxyPS@}
168 \xydef@\installxyps@x{\dumpPSdict@@
169 \ifx\xyrealshipout@\undefined \let\xyrealshipout@=\shipout\fi
170 \ifx \shipout \xyrealshipout@
171 \ifUsePSdict@@ \DN@{\includePSmessage@\includeXYPSdict@\message{>}}%
172 \else \DN@{\XYdict@\endXYdict@}\fi
173 \else \DN@{\let\xyPSshipout@ii=\xyPSshipout@PSii \@PSshipout}\fi
174 \let\firstPS@=\relax \next@
175 \let\XYpredict@=\relax
176 \setupxyPS@@ }
178 \let\realinstallxyps@x=\installxyps@x
179 \ifx\undefined\AfterBeginDocument
180 \def\installxyps@x{\xysetup@@{\realinstallxyps@x}}%
181 \else
182 \def\installxyps@x{\AfterBeginDocument{\realinstallxyps@x}}%
183 \fi

In case no ⟨driver⟩ was known when a call to the \installxyps@ method was queued, e.g. by \dumpPSdict{} before any \xyoption{⟨driver⟩}, then a check is made to see there is now a known ⟨driver⟩ which supports PostScript. If so then this installation is cancelled since another should follow, otherwise the default ⟨driver⟩ of dvips is assumed. The command \xyPSdriver#1 is provided to allow users to change this default ⟨driver⟩. This may be necessary when multiple ⟨driver⟩s are required and the final one specified does not support PostScript.

196 \xydef@\xydefaultdriver@{dvips}
197 \xydef@\xyPSdriver#1{\def\xydefaultdriver@{#1}}
199 \xydef@\installxyps@orig{\DN@{}%
200 \ifx\xydriversselected@@\empty
201 \DN@{\expandafter\defaultinstallps@\expandafter{\xydefaultdriver@}}%
202 \else \def\do##1{%
203  \expandafter\ifx\csname##1@xy@ps\endcsname\relax
204  \DN@{\defaultinstallps@{##1}}}%
205 \xydriversselected@@
206 \else \DN@##1{}\fi\fi \next@ }
208 %\xylet@\installxyps@@=\installxyps@orig
210 \xydef@\defaultinstallps@#1#2{%
211 \xywarning@{no driver specified, using #1 }%
212 \xyrequire{#1}\csname #1@xy@ps\endcsname{}}

214 \xydef@\null@xy@ps{\installxyps@}

PostScript escape

An extra ⟨shape⟩ modifier key allows arbitrary PostScript code to be applied to the current ⟨object⟩.

[!⟨postscript code⟩] for special effects
[psxy]  stores current location.

231 \xydefcsname@{shape [!...]}#1{%\tracingall%
232 \expandafter\ifx\csname xyps-sloaded\endcsname\empty \DN@{\xyPSescapestyle@{#1}@@}%
233 \else\ifxyPSshapes@\DN@{\xyPSshapechar@{#1}@@}%
234 \else \DN@{\xyPScharwarning@}\fi\fi \next@ }
235 \xydefcsname@{shape [psxy]}{\ifxyPSshapes@\DN@{\xyPSpsxy@}%
236 \else \DN@{\xyPScharwarning@}\fi \next@ }

Normally the ⟨postscript code⟩ will be a simple command to alter the PostScript graphics state: e.g. [!1 0 0 setrgbcolor] changes the colour used to render parts of the ⟨object⟩. Any number of such ⟨shape⟩ modifiers is allowable, however it is more efficient to combine them into a single modifier, whenever possible.

It is very important that braces { and } do not appear explicitly in any ⟨postscript code⟩, as this may upset the XY-pic ⟨object⟩ parsing. However it is acceptable to have a control sequence name here, expanding into more intricate PostScript code. This will not be expanded until a later (safe) time.

Due to differences within the DVI-drivers, such simple PostScript commands need not affect every part of an ⟨object⟩. In particular the lines, curves and arrowheads generated by XY-pic use a different mechanism, which should give the same result with all drivers. This involves redefining some PostScript procedures which are always read prior to rendering one of these objects. One simple way to specify a red line is as follows; the xycolor extension provides more sophisticated support for colour. The ⟨shape⟩ modifiers described in the previous section also use this mechanism, so should work correctly with all drivers.

\def\colorxy(#1){%
 /xycolor{#1 setrgbcolor}def}
...
\connect[!\colorxy(1 0 0)]\dir{-}
...

Note how the braces are inserted within the expansion of the control sequence \colorxy, which happens after parsing of the ⟨connection⟩. The following table shows which graphics parameters are treated in this way, their default settings, and the type of PostScript code needed to change them.

                colour  /xycolor{0 setgray}def
                line-width /xywidth{.4 setlinewidth}def
                dashing /xydash{[] 0 setdash}def
                line-cap /xycap{1 setlinecap}def
                line-join /xyjoin{1 setlinejoin}def

This feature is meant primarily for modifying the rendering of objects specified in TEX and XY-pic, not for drawing new objects within PostScript. No guarantee can be given of the current location, or scale, which may be different with different drivers. However a good PostScript programmer will be able to overcome such difficulties and do much more. To aid in this the special modifier [psxy] is provided to record the location where the reference point of the current ⟨object⟩ will be placed. Its coordinates are stored with keys xyXpos and xyYpos.

When the \special is placed the following registers contain important values: \L@p = horizontal displacement of XY-pic reference point from the TEX reference point (i.e. left-hand end of the box) of the initial object; \D@p = vertical displacement of XY-pic reference point from the TEX reference point (i.e. the baseline) of the initial object; \R@p = horizontal offset, resulting from ⟨shape⟩ modifiers; \U@p = vertical offset, initially -\D@p but alterable by ⟨shape⟩ modifiers.

320 \xydef@\xyPSpsxy@{%
321 \setboxz@h{\dimen@=\L@p \advance\dimen@-\R@p
322 \dimen@ii=-\U@p \raise\dimen@ii\hbox to\z@{%
323 \kern\dimen@\xyPScurrpt@\kern-\dimen@}\boxz@}}%
325 \xydef@\xyPScurrpt@{\ifxyPSshapes@\expandafter\xyPScurrpt@@\fi}

It is necessary to know the current PostScript location. Unfortunately the currentpoint operator frequently has no value. The following code overcomes this difficulty.

Some drivers may need to define this differently...

335 \xydef@\xyPScurrpt@@@{\PSspecial@@{xyi}\PSraw@@{userdict begin xyx end}}
336 \ifx\undefined\xyPScurrpt@@ \xylet@\xyPScurrpt@@=\xyPScurrpt@@@ \fi
338 %\xydef@\xyPScurrpt@@@{\PSspecial@@{userdict begin
339 % 0 0 transform grestore gsave itransform
340 % /xyYpos exch def /xyXpos exch def end}}
342 %\xydef@\xyPScurrpt@@@{%
343 % \PSspecial@@{0 0 transform grestore gsave itransform }%
344 % \PSraw@@{userdict begin /xyYpos exch def /xyXpos exch def end}}

The PostScript operator called xyx is defined below, for storing the location placed on the stack

by xyi.

Technical Note

: The scoping is achieved by using two \specials so that the resulting PostScript file should ultimately look like:

... { special code before} ⟨object⟩ {special code after} ...

The “code after” is to cancel the effect, returning the graphics state to what it was prior to the “code before”. Not all DVI-drivers can achieve this sequencing. In particular OzTEX collects all \specials in the DVI-file and places their contents at the beginning of the PostScript file: any effect would be cancelled immediately after it has been established.

The user can add code to both parts by expressing the ⟨shape⟩ modifier as follows:

*… !⟨code before⟩<>⟨code after⟩]….

Further Technical Note

: The “code before” does two things in addition to that code given explicitly by the user. Firstly it issues a gsave then it opens a new dictionary on the dictionary stack. The “code after” contains the matching grestore after closing the new dictionary.

Since objects can be built as \composites and diagrams can be nested, there is the possibility of generating long chains of nested PostScript dictionaries. For this reason the dictionary is kept small, allowing only 8 key-value pairs to be defined within it. If more are required, the user should define a private dictionary to hold the extra key-value pairs, making sure that it is open when its entries need to be accessed.

391 \xywarnifdefined\xyPSshapechar@
392 \xywarnifdefined\xyPSsplitshape@
394 {\xyuncatcodes \catcode`@=11
395 \gdef\xyPSshapechar@#1@@{\xyPSsplitshape@#1<><>@@}%
396 \gdef\xyPSsplitshape@#1<>#2<>#3@@{\xyPSsplitPS@{#1}{#2}}}
398 %\xydef@\xyPSsplitPS@#1#2{%\aftergroup\show\aftergroup\relax
399 % \def\xyPSpre@{#1}\def\xyPSpost@{#2}\modPSboxz@ }
401 \xydef@\xyPSrawA@#1{\expandafter\xyPSrawAA@ #1{}}%
402 \xydef@\xyPSrawAA@#1#2{\PSraw@@{{pu #1}xyg #2}%
403 \PSmessage{{pu #1}xyg #2}}%
404 \xydef@\xyPSrawZ@#1{\PSraw@@{{#1 pp}xyf}\PSmessage{{#1 pp}xyf}}%

The PostScript operators pu, pp, xyg and xyf are defined below, for push/pop of the XYddict stack, preceded/followed by a gsave/grestore of the PostScript graphics state.

412 \xydef@\modPSboxz@{%
413 \expandafter\DN@\expandafter{\xyPSpre@{}}\ifx\next@\empty\else
414 \setboxz@h{\expandafter\xyPSrawA@\expandafter{\xyPSpre@{}}\boxz@
415 \expandafter\xyPSrawZ@\expandafter{\xyPSpost@}}\DN@{}\fi}%
417 \xydef@\modPSdrop@{%
418 \expandafter\DNii@\expandafter{%
419 \expandafter\xyPSrawA@\expandafter{\xyPSpre@{}}}%
420 \DN@##1{\expandafter\def\expandafter\tmp@\expandafter{\nextii@ ##1}}%
421 \expandafter\next@\expandafter{\Drop@@}%
422 \expandafter\DNii@\expandafter{%
423 \expandafter\xyPSrawZ@\expandafter{\xyPSpost@}}%
424 \DN@##1{\expandafter\def\expandafter\Drop@@\expandafter{\tmp@ ##1}}%
425 \expandafter\next@\expandafter{\nextii@}}%
427 \xydef@\modPSconnect@{%
428 \expandafter\DNii@\expandafter{%
429 \expandafter\xyPSrawA@\expandafter{\xyPSpre@{}}}%
430 \DN@##1{\expandafter\def\expandafter\tmp@\expandafter{\nextii@ ##1}}%
431 \expandafter\next@\expandafter{\Connect@@}%
432 \expandafter\DNii@\expandafter{%
433 \expandafter\xyPSrawZ@\expandafter{\xyPSpost@}}%
434 \DN@##1{\expandafter\def\expandafter\Connect@@\expandafter{\tmp@ ##1}}%
435 \expandafter\next@\expandafter{\nextii@}}%
437 \xydef@\xyPSpre@{{}{}}
438 \xydef@\xyPSpost@{}

Some utility macros for controlling writing to the log-file.

446 \xydef@\PSmessage@#1{\W@{PS: #1, direction=\the\Direction}}
447 \xydef@\PSignore@#1{}%

448 \xydef@\showPSmessages{\let\PSmessage=\PSmessage@}
449 \xydef@\hidePSmessages{\let\PSmessage=\PSignore@}
450 \xylet@\PStracing=\showPSmessages
451 \hidePSmessages
453 \xydef@\PSmacro@#1{\PSmacro@@{#1}\PSmessage{#1}}

PostScript Header file

This creates a flag to indicate whether the user wishes to get the PostScript dictionary from an external header file.

464 \xydef@\includeXYPSdict@@{%
465 \expandafter\PSinclude@@\expandafter{\xyPSdictname}}
466 \xydef@\includeXYPSdict@r{\message{PS: includeXYPSdict}\includeXYPSdict@@
467 \let\includeXYPSdict@=\relax}
468 \xylet@\includeXYPSdict@\includeXYPSdict@r
470 \xydef@\endXYdict@{}
472 \xydef@\includePSmessage@@{\message{<xyps: including \xyPSdictname}}
473 \xylet@\includePSmessage@=\includePSmessage@@
475 \xydef@\xyPSdictknown@{%
476 % \immediate\closein\xyPSdictread@
477 \immediate\closein\xyread@
478 \xywarning@{File \xyPSdictname\space already exists}
479 \message{ Do you wish to overwrite it \string?  y/n }%
480 \read16 to \next
481 \DNii@{\xywarning@{You did not type Y or N -- try again please}%
482 \xyPSdictknown@}%
483 \DN@{Y }\ifx\next@\next \DNii@{\writePSdict@@}%
484 \else\DN@{y }\ifx\next@\next \DNii@{\writePSdict@@}%
485 \else\DN@{n }\ifx\next@\next \DNii@{\cancelPSdict@}%
486 \else\DN@{N }\ifx\next@\next \DNii@{\cancelPSdict@}%
487 \fi\fi\fi\fi \nextii@ }
489 \xydef@\cancelPSdict@{%
490 \xywarning@{cancelling dump of PostScript dictionary}}
492 \xydef@\noDictmessage@{%
493 \xywarning@{\dvitype@\space does not support the use of a header file}}

These macros are also defined in xyps.doc. To avoid warning messages about redefinitions, that mechanism has been disabled.

500 \DN@{\csname newif\endcsname\ifUsePSdict@@\DN@{}}
501 \ifx\undefined\UsePSdict@@true\else\DN@{}\fi \next@
503 \ifx\undefined\xyPSdefaultdict
504 \xydef@\xyPSdefaultdict{%
505 \DN@##1.##2.##3@{\gdef\xyPSdictname{xy##1##2dict.pro}}%
506 \expandafter\next@\xyversion.@}%
507 \fi
509 \ifx\undefined\UsePSheader@
510 \xydef@\UsePSheader@#1{%

511 \DN@{#1}\ifx\next@\empty
512 %  \ifx\xyPSdictname\undefined\xyPSdefaultdict\fi
513 \else \gdef\xyPSdictname{#1}\fi
514 \ifx\xyPSdictname\undefined\xyPSdefaultdict\fi
515 \gdef\xyHeaderMessage@{%
516  It includes a reference to the PostScript file \xyPSdictname.^^J}%
517 \UsePSdict@@true}%
518 \let\UsePSheader=\UsePSheader@
519 \fi

This is used to write the dictionary to a file, suitable for inclusion as a resource within any Post-Script document. It is fully conforming to Adobe’s document structuring guidelines.

527 \xywarnifdefined\xyPS@@
528 \xywarnifdefined\xyPS@@@
529 {\catcode`|=14 \catcode`\%=12 \catcode`\<=1 \catcode`\>=2 |
530 \gdef\xyPS@@<%%>\gdef\xyPS@@@<%!>}
532 %\xydef@\writePSdict@@{\writePSdict@ \let\writePSdict@@=\relax}
533 \xydef@\writePSdict@@{\message{PS: writePSdict@@}\writePSdict@
534 \def\writePSdict@@{\message{write PS relaxed}}}
535 {\catcode`|=14 \catcode`\%=12
536 \gdef\writePSdict@{{\begingroup|
537 \immediate\openout\xywrite@=\xyPSdictname \relax
538 \message{<xyps: dumping \xyPSdictname}|
539  \def\PSdict@@@##1{\immediate\write\xywrite@{##1}}|
540  \let\xyPSobeylines@@=\obeyoutlines@
541  \let\firstPS@@=\relax
542  \let\endXYdict@=\relax
543  \PSdict@@@{\xyPS@@@ PS-Adobe-3.0 Resource-procset}|
544  \PSdict@@@{\xyPS@@ Title: \xyPSdictname}|
545  \PSdict@@@{\xyPS@@ Version: REPLACEWITHVERSION}|
546  \PSdict@@@{\xyPS@@ Creator: Xy-ps backend to Xy-pic}|
547  \PSdict@@@{\xyPS@@ DocumentSuppliedProcSets: XYdict}|
548  \ifx\dvitype@\undefined
549  \PSdict@@@{\xyPS@@ For: use with Xy-pic}\else
550  \PSdict@@@{\xyPS@@ For: \dvitype@ use of Xy-pic}\fi
551  \PSdict@@@{\xyPS@@ BeginResource: procset XYdict}|
552  \def\PSspecialdict@@##1{\PSdict@@@{##1^^J}}|
553  \let\PSdict@@=\PSdict@@@ \let\xy@begindvi=\literal@|
554  \UsePSdict@@false\XYpredict@@|
555  \XYdict@@|
556  \PSdict@@@{\xyPS@@ EndResource}|
557  \immediate\closeout\xywrite@
558 \message{>}|
559 \endgroup}}}

Within the expansion of \XYdict@ the end-of-line tokens are still active. The following expansion seems to work on all systems so far tested.

566 \xywarnifdefined\obeyoutlines@
567 {\catcode`\^^M=\active%
568 \gdef\obeyoutlines@{\catcode`\^^M=\active \def^^M{^^J}%

569 \newlinechar=`\^^J\obeyspaces}}

The dictionary of PostScript commands is split into two pieces according to whether they are relevent to general PostScript effects or only to the PostScript backend. These pieces are generated from code within the files xyps-pro.tex and xypsdict.tex. These files have corresponding .doc versions for documentation.

The following commands cause the parts of the PostScript dictionary to be read from the appropriate files. If \ifUsePSdict@@ gives \iftrue then there may be no need to do anything, since the definitions will be subsequently loaded from the header file. Normally it is only necessary to read these files once, using \XYpredict@. However some ⟨driver⟩s may need it more frequently, so instead call \XYpredict@@ directly.

588 \xydef@\XYpredict@@{\ifUsePSdict@@\DN@{}\else
589 \DN@{\xy@begindvi{\xyinputorelse@{xyps-pro}%
590  {\xyerror@{Could not load xyps-pro}{}}\xyuncatcodes}}%
591 \next@
592 \DN@{\xy@begindvi{\xyinputorelse@{xypspatt}%
593  {\xyerror@{Could not load xypspatt}{}}\xyuncatcodes}}\fi
594 \next@ }
596 \xydef@\XYpredict@r{\XYpredict@@ \let\XYpredict@=\relax \installxyps@}
597 \xylet@\XYpredict@\XYpredict@r
599 \xydef@\XYdict@{\XYdict@@\def\XYdict@{\message{PS relaxed}}}%
600 \xydef@\XYdict@@{\DN@{\xyinputorelse@{xypsdict}%
601  {\xyerror@{Could not load xypsdict}{}}\xyuncatcodes}%
602 \expandafter\xy@begindvi\expandafter{\next@}}

This command is for use in macro-packages, providing an easy way to force the dictionary to load, when it has not done so using the usual mechanisms.

612

613 \xydef@\forceload@XYdict{%
614 \let\includeXYPSdict@=\includeXYPSdict@r
615 \let\XYpredict@=\XYpredict@r
616 \let\XYdict@=\XYdict@@ \expandafter\installxyps@ }

4.11.3 Extensions

Several included files handle standard PostScript implementations of XY-pic extensions.

A conditional \ifxyPSshapes@ is used to indicate whether the special shape effects implemented in xyps-r.tex can actually be fully supported by the current driver. When not available, then an attempt to use these effects simply results in a warning message. After two attempts the warning message “turns itself off”; subsequent attempts are simply ignored cleanly.

636 \xynew@{if}\ifxyPSshapes@ \xyPSshapes@true
638 \xydef@\xyPScharwarning@@{\xyPScharmessage@
639 \gdef\xyPScharwarning@@{\xyPScharmessage@
640 \xywarning@{...no further PostScript warnings will be given}%
641 \global\let\xyPScharwarning@@=\relax }}
643 \xydef@\xyPScharmessage@{\xywarning@{%
644 the current <driver> does not fully support PostScript effects}}%

Allow new PostScript effects to be defined. This section describes how \newxyPSshape is used to define a new effect which is available only in PostScript; i.e. having no analogue elsewhere within XY-pic.

The new effect will be called via [⟨name⟩], which gets interpreted as referring to \csname xyshape@⟨name⟩@\endcsname. Hence a control sequence of this form must first be created, if it does not already exist. Its initial expansion is simply \xyundefinedEffect@{⟨name⟩}{}@@ which produces a warning message.

661 \xydef@\newxyshape#1#2#3{%
662 \DN@{#3}\ifx\next@\empty
663 \xydefcsname@{shape [#1]}{\csname xyshape@#1@\endcsname}%
664 \else \expandafter\def\csname shape [#1]\endcsname{%
665 \csname xyshape@#1@\endcsname}\fi
666 \DN@{#2}\ifx\next@\empty
667 \expandafter\def\csname xyshape@#1@\endcsname{%
668  \xyundefinedEffect@{#1}{}@@}%
669 \else \expandafter\def\csname xyshape@#1@\endcsname{#2}\fi }
671 \xydef@\xyundefinedEffect@#1#2@@{%
672 \xywarning@{The #1 #2 effect is not implemented with the current driver}}%

When an implementation of the effect is available then \csname xyshape@⟨name⟩@\endcsname is rebound to \csname xyPSshape@⟨name⟩@\endcsname, which expands to the contents of #2 in

\newxyPSshape#1#2. If #2 is empty then the expansion is the \xyPSnotimplemented@@`⟨name⟩'@@

warning message, which is especially useful during development.

683 \xydef@\newxyPSshape#1#2{%
684 \expandafter\DN@\expandafter{\csname shape [#1]\endcsname}%
685 \DNii@{\relax}\ifx\next@\nextii@ \newxyshape{#1}{}\relax\fi
686 \expandafter\DNii@\expandafter{\csname xyPSshape@#1@\endcsname}%
687 \expandafter\def\nextii@{#2}%
688 \ifx\nextii@\empty\expandafter\def\next@{\xyPSnotimplemented@@`#1'@@}%
689 \else
690 \edef\tmp@{\noexpand\let\expandafter\noexpand\next@
691  \expandafter\noexpand\nextii@}%
692 \expandafter\tmp@\fi }
694 \xydef@\xyPSnotimplemented@@#1@@{%
695 \xywarning@{This PostScript effect is not implemented yet}}%
697 \xydef@\xyPSnotfinished@@{%
698 \xywarning@{This effect is not reliable yet; box sizes may be wrong}}%

The end & Log

706 \endinput
708 % $Log: xyps-ps.doc,v $
709 % Revision 3.7  1999/02/16 15:12:50  krisrose
710 % Interim release (Y&Y fonts now free).

711 %

712 % Revision 3.6  1998/03/06 01:28:05  krisrose
713 % Releasing (with Y&Y fonts).

714 %

715 % Revision 3.4  1997/05/18 01:13:24  ross

506 CHAPTER 4. DRIVERS

716 % Essential bugfixes.

717 %

718 % Revision 3.3  1996/12/19 03:50:08  ross
719 % Maintenance release.

720 %

721 % Revision 3.3  1996/12/18  09:55:56  ross
722 % improvements to the file-loading commands
723 % more robust installation procedures
724 % shorter tracing messages
725 % dictionary no longer loads multiply

726 %

727 % Revision 3.2  1995/09/19  18:21:41  ross
728 % Bug fix release.

729 %

730 % Revision 3.1  1995/09/05  20:36:33  ross
731 % Release!

732 %

733 % Revision 3.0  1995/07/07  20:13:19  ross
734 % Major release w/new User's Guide!

735 %

736 % Revision 2.13  1995/07/04  15:04:51  ross
737 % Ready for release of v3.

738 %
739 %

740 % NEW for version 3.1 by by Ross Moore.

4.11.4 xyps-c.doc

Header:

1 %% $Id: xyps-c.doc,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %%
3 %% Xy-pic ``Colour extension'' PostScript backend support.
4 %% Copyright (c) 1993-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along

21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 %% As a special exception, you may use this file and all files derived
25 %% from it without restrictions.  This special exception was added with
26 %% version 3.7 of Xy-pic.
27 %%
28 \expandafter\ifx\csname xyps-cloaded\endcsname\empty
29 \message{not reloaded}\endinput \fi
30 \expandafter\let\csname xyps-cloaded\endcsname=\empty \xycatcodes

4.11.5 Colour

The included file xyps-c.tex (version 3.7) provides PostScript support for the effects defined in the color extension in §2.6.

The PostScript style methods are required, so ensure that they are loaded.

49 \expandafter\ifx \csname xyps-sloaded\endcsname\empty\else
50 \xyinputorelse@{xyps-s}{\xyerror@{Could not load xyps-s}{}}%
51 \xycatcodes\fi

This file is loaded and its effects are activated automatically whenever \xyoption{color} is requested and the current ⟨driver⟩ supports colours using PostScript. Should there be any need to turn off this support, the following commands are available; they obey usual TEX groupings.

\NoPScolor remove PostScript support
\UsePScolor reinstate PostScript.

Without PostScript support some drivers may still be able to provide some support for colours. These commands are not guaranteed to work adequately with all drivers. They are provided primarily for testing and trouble-shooting; e.g. with ⟨driver⟩ configurations untested by the authors of XY-pic, who should be notified of any difficulties.

73 \xydef@\UsePScolor{\installPScolor@}
74 \xydef@\NoPScolor{\UnloadColor@}

Installation Installation consists of rebinding the macros \xycolor@ and \newxycolor@ and of reloading the standard colours to include a description for PostScript. This installation should be delayed till after color and ps themselves have been installed.

87 \xydef@\installPScolor@{\installPSstyle@
88 \let\xymath@=\xyPSmath@ \let\xynomath@=\xyPSnomath@
89 \let\checkxyPScolor@=\checkxyPScolor@@
90 \let\xycolor@@=\xyPScolor@@
91 \xystandardcolors@
92 \xyuncatcodes }

All effects defined in the color extension can be implemented using the PostScript dictionary, loaded by xyps-ps. This file provides “generic” PostScript code which is known to work correctly with most drivers. No attempt is made to provide special code for particular drivers; for driver-specific variations, consult the appropriate xy⟨driver⟩.doc file.

105 \xydef@\xyPSmath@{\hbox\bgroup\dimen@=.55ex \checkxyPScolor@ \xyinside@}

106 \xydef@\xyPSnomath@{\hbox\bgroup\dimen@=\z@ \checkxyPScolor@ \xyinside@}
108 \xydef@\checkxyPScolor@@{\xycolor@raw@@{}\let\checkxyPScolor@=\relax}
109 \xylet@\checkxyPScolor@=\relax
113 \xydef@\xyPSnewcolor@#1#2#3#4#5{%
114 \expandafter\DN@\expandafter{\csname shape [#1]\endcsname}%
115 \DNii@{\relax}\ifx\next@\nextii@\newxycolor{#1}{}\relax\fi
116 \DNii@{#4}\ifx\nextii@\empty
117 \expandafter\DNii@\expandafter{\csname xyPSshape@#1@\endcsname}%
118 \expandafter\def\nextii@{\xyPScolor@{#2 #3}}\else
119 \expandafter\DNii@\expandafter{\csname xyPSshape@#1@\endcsname}%
120 \expandafter\def\nextii@{\xyPScolor@{#4}}\fi
121 \ifx\nextii@\empty\expandafter\def\next@{\xyPSnotimplemented@@`#1'@@}%
122 \else
123 \edef\tmp@{\noexpand\let\expandafter\noexpand\next@
124  \expandafter\noexpand\nextii@}\expandafter\tmp@\fi }
126 \xydef@\xyPScolor@{\ifPSspecials@\expandafter\xyPScolor@@
127 \else\expandafter\eat@\fi}
128 \xydef@\xyPScolor@@#1{\bgroup \checkXyStyle@
129 \def\preStyle@@{\expandafter\addtostyletoks@\expandafter{\xyPSpre@}}%
130 \def\postStyle@@{\expandafter\addtostyletoks@\expandafter{\xyPSpost@}}%
131 \let\modPSboxz@=\modXYstyle@ \xyPS@color@@{#1}%
132 \toks@={\egroup\let\xy@style@=\relax \def\Drop@@}%
133 \expandafter\addtotoks@\expandafter{\expandafter{\Drop@@}\def\Connect@@}%
134 \expandafter\addtotoks@\expandafter{\expandafter{\Connect@@}}%
135 \the\toks@ }
137 %\xydef@\xyPS@color@@#1{#1 /xycolor{#1}def }
138 \xydef@\xyPS@color@@#1{\xyPSsplitPS@{{#1}cc}{}}
139 \xydef@\xycolor@raw@@#1{\PSraw@@{xyc}}

The end & Log

147 \endinput
149 % $Log: xyps-c.doc,v $
150 % Revision 3.7  1999/02/16 15:12:50  krisrose
151 % Interim release (Y&Y fonts now free).

152 %

153 % Revision 3.3  1996/12/18  10:05:50  ross
154 % minor improvements to file-loading commands

155 %

156 % Revision 3.1  1995/09/05  20:36:33  ross
157 % Release!

158 %

159 % Revision 3.0  1995/07/07  20:13:19  ross
160 % Major release w/new User's Guide!

161 %

162 % Revision 2.13  1995/07/04  15:04:51  ross
163 % Ready for release of v3.

4.11. EXTRA FEATURES WITH PostScript SUPPORT 509

164 %

165 % Revision 2.9  1994/06/09  14:38:56  ross
166 % Release 3beta.
167 % Includes support for special effects: Rotations, Scaling, Line-width, Colour.
168 % Back-ends are separated into separate files.
169 % More back-ends are supported, experimentally --- needs testing.

170 %

171 % Revision 2.9  1994/06/09  14:38:56  ross
172 % Release 3beta.
173 % Includes support for special effects: Rotations, Scaling, Line-width, Colour.
174 % Back-ends are separated into separate files.
175 % More back-ends are supported, experimentally --- needs testing.

176 %

177 % NEW for version 2.9 by by Ross Moore.

4.11.6 xyps-f.doc

Header:

1 %% $Id: xyps-f.doc,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %%
3 %% Xy-pic ``Frame extension'' PostScript backend support.
4 %% Copyright (c) 1995-1997 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 %% As a special exception, you may use this file and all files derived
25 %% from it without restrictions.  This special exception was added with
26 %% version 3.7 of Xy-pic.
27 %%
28 \expandafter\ifx\csname xyps-floaded\endcsname\empty
29 \message{not reloaded}\endinput \fi
30 \expandafter\let\csname xyps-floaded\endcsname=\empty \xycatcodes

4.11.7 Frames

The included file xyps-f.tex (version 3.7) provides PostScript support for the effects defined in the frame extension described in §2.2. It implements some effects otherwise unattainable.

This file is loaded and its effects are activated automatically whenever \xyoption{frame} is requested and the current ⟨driver⟩ supports PostScript effects for frames. Should there be any need to turn off this support, the following commands are available; they obey usual TEX groupings.

\NoPSframes remove PostScript support
\UsePSframes reinstate PostScript.

Without PostScript support ellipses may be shown as circles and all filled regions may be represented as black rectangles. These commands are provided primarily for testing and trouble-shooting; e.g. with ⟨driver⟩ configurations untested by the authors of XY-pic, who should be notified of any difficulties.

Installation The ⟨driver⟩-file must call the following macro to rebind control sequences defined in xyframe, thereby allowing the PostScript methods to be used.

67 \xydef@\installPSframes@{%
68 \let\framed@body@@=\xyPSframed@body@
69 \let\circled@x@@=\xyPScircled@x@
70 \let\ellipsed@x@@=\xyPSellipsed@x@
71 \installPSfills@
72 \xyuncatcodes}
74 \xydef@\UsePSframes{\installPSframes@}
75 \xydef@\NoPSframes{\UnloadFrames@}

Frames: solid, dotted and dashed For solid frames use PostScript ovals, otherwise adjust the spacing between dashes or dots according to the lengths, both vertical and horizontal.

86 \xydef@\xyPSframed@body@{\DN@{\framed@body@}%
87 \ifx\framehfill\frm@solidh@@
88  \DN@{\xyPSframed@oval@\xyPSoval@Special}%
89 % \else\ifdim\frmradius@@=\z@\else
90 \else\ifdim\R@=\z@\else
91  \ifx\framehfill\frm@dashh@@
92  \DN@{\xyPSframed@oval@\xyPSdashoval@Special}%
93  \else\ifx\framehfill\frm@doth@@
94  \DN@{\xyPSframed@oval@\xyPSdotoval@Special}%
95  \fi\fi
96 \fi\fi \next@ }
98 \xydef@\xyPSframed@oval@#1{\vglue\U@c
99  \hbox{\hglue\L@c\xypsoval@#1\hglue\R@c}\vglue\D@c}
102 \xydef@\xyPScircled@x@{\DN@{\xyPScircled@x@@\xyPScirc@Special}%
103 \ifx\framehfill\frm@doth@@
104 \DN@{\xyPScircled@x@@\xyPSdotcirc@Special}%
105 \else\ifx\framehfill\frm@dashh@@
106 \DN@{\xyPScircled@x@@\xyPSdashcirc@Special}%
107 \fi\fi \next@ }

109 \xydef@\xyPScircled@x@@#1{\vglue2\R@
110 \hbox{\hglue2\R@\xypscircle@#1\hglue2\R@}%
111 \vglue2\R@}

In practice the parameters #1 and #2 will hold ⟨dimen⟩s.

117 \xydef@\xyPSellipsed@x@#1#2{%
118 \DN@{\xyPSellipsed@x@@\xyPScirc@Special}%
119 \ifx\framehfill\frm@doth@@
120 \DN@{\xyPSellipsed@x@@\xyPSdotcirc@Special}%
121 \else\ifx\framehfill\frm@dashh@@
122 \DN@{\xyPSellipsed@x@@\xyPSdashcirc@Special}%
123 \fi\fi \next@{#1}{#2}}
125 \xydef@\xyPSellipsed@x@@#1#2#3{\vglue #3\vglue #3\relax
126 \hbox{\L@c = #2\relax \R@c=\L@c \D@c = #3\relax \U@c=\D@c
127 \hglue#2\hglue#2\relax\xypsellipse@#1\hglue#2\hglue#2\relax}%
128 \vglue #3\vglue #3\relax}

These may be used for dashed frames.

135 \xydef@\xyPSdashhfill@{{\SemiDirectionChar=95 \Direction=3072 \xyPSdash@}}
136 \xydef@\xyPSdashvfill@{{\SemiDirection=31 \Direction=1023 \xyPSdash@}}

ovals and circles The width, height, corner-radius are available as \dimen@i, \dimen@ii and \R@ respectively; we only need \R@ here, since the extents hold the real information that we need.

148 \xydef@\xypsoval@#1{%
149 \dimen@=\L@c \advance\dimen@\R@c
150 \dimen@ii=\U@c \advance\dimen@ii\D@c
151 \ifdim\dimen@ii<\dimen@ \relax \dimen@=\dimen@ii\fi \divide\dimen@\tw@
152 % \R@=\frmradius@@
153 \ifdim\R@>\dimen@ \relax \R@=\dimen@ \fi
154 \D@c=-\D@c \L@c=-\L@c
155 \edef\tmp@{\expandafter\removePT@\the\R@
156 \space\expandafter\removePT@\the\R@c
157 \space\expandafter\removePT@\the\D@c
158 \space\expandafter\removePT@\the\L@c
159 \space\expandafter\removePT@\the\U@c }%
160 \expandafter#1\expandafter{\tmp@}}
162 \xydef@\xypscircle@#1{\dimen@=\R@
163 \edef\tmp@{\expandafter\removePT@\the\dimen@}%
164 \expandafter#1\expandafter{\tmp@}}
166 \xydef@\xypsellipse@#1{\edef\tmp@{%
167 \expandafter\removePT@\the\U@c \space
168 \expandafter\removePT@\the\D@c \space
169 \expandafter\removePT@\the\L@c \space
170 \expandafter\removePT@\the\R@c }%
171 \expandafter#1\expandafter{\tmp@}}
173 \xydef@\xyPSoval@Special#1{\PSmacro@{#1 ov}}
174 \xydef@\xyPScirc@Special#1{\PSmacro@{#1 ox}}
175 \xydef@\xyPSdotcirc@Special#1{\PSmacro@{#1 ot}}

176 \xydef@\xyPSdashcirc@Special#1{\PSmacro@{#1 od}}
177 \xydef@\xyPSdotoval@Special#1{\PSmacro@{#1 vt}}
178 \xydef@\xyPSdashoval@Special#1{\PSmacro@{#1 vd}}

The PostScript operators ov, ox etc. are defined within xyps-pro, having scope limited to XYdict and sub-dictionaries.

189 \xydef@\xyPSfilledRegion#1#2{\setboxz@h{\lower\D@c\vbox{%
190 \vglue\U@c\hbox{#1#2\empty\hglue\L@c\hglue\R@c}\vglue\D@c}}%
191 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}
193 \xydef@\filledRectangle@PS{%
194 \xyPSfilledRegion{\xypsoval@\xyPSfilloval@Special}}
195 \xydef@\filledCircle@PS#1{{\R@c=\R@ \L@c=\R@ \U@c=\R@ \D@c=\R@
196 \xyPSfilledRegion{\xypscircle@\xyPSfillcirc@Special}#1}}
197 \xydef@\filledEllipse@PS{%
198 \xyPSfilledRegion{\xypsellipse@\xyPSfillellipse@Special}}
199 \xydef@\filledOval@PS{%
200 \xyPSfilledRegion{\xypsoval@\xyPSfilloval@Special}}
202 \xydef@\frame@emph@PS#1{\filled@{#1}\relax}
204 \xydef@\installPSfills@{%
205 \let\frame@emph@@=\frame@emph@PS
206 \let\filledRectangle@@=\filledRectangle@PS
207 \let\filledOval@@=\filledOval@PS
208 \let\filledCircle@@=\filledCircle@PS
209 \let\filledEllipse@@=\filledEllipse@PS

210 }

Filled regions Rectangles are treated as a special case of ovals. The #2 parameter signifies whether the outline of the object should also be stroked (#2=\relax) after being filled. Such a stroke is always in black.

219 %\xydef@\xyPSfillrect@Special#1#2{%
220 % \ifx#2\relax\PSmacro@{#1 sfr}%
221 % \else\PSmacro@{#1 fr}\fi}
222 \xydef@\xyPSfilloval@Special#1#2{%
223 \ifx#2\relax\PSmacro@{#1 sfo}%
224 \else\PSmacro@{#1 fo}\fi}
225 \xydef@\xyPSfillcirc@Special#1#2{%
226 \ifx#2\relax\PSmacro@{#1 sfc}%
227 \else\PSmacro@{#1 fc}\fi}
228 \xydef@\xyPSfillellipse@Special#1#2{%
229 \ifx#2\relax\PSmacro@{#1 sfe}%
230 \else\PSmacro@{#1 fe}\fi}

The end & Log

238 \endinput
240 % $Log: xyps-f.doc,v $
241 % Revision 3.7  1999/02/16 15:12:50  krisrose
242 % Interim release (Y&Y fonts now free).

4.11. EXTRA FEATURES WITH PostScript SUPPORT 513

243 %

244 % Revision 3.4  1997/05/18 01:13:24  ross
245 % Essential bugfixes.

246 %

247 % Revision 3.3  1996/12/18  10:07:22  ross
248 % cosmetic changes to macro-names

249 %

250 % Revision 3.1  1995/09/05  20:36:33  ross
251 % Release!

252 %

253 % Revision 3.0  1995/07/07  20:13:19  ross
254 % Major release w/new User's Guide!

255 %

256 % Revision 2.13  1995/07/04  15:04:51  ross
257 % Ready for release of v3.

258 %
259 %

260 % NEW for version 3.0 by by Ross Moore.

4.11.8 xyps-l.doc

Header:

1 %% $Id: xyps-l.doc,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %%
3 %% Xy-pic ``Line extension'' PostScript backend support.
4 %% Copyright (c) 1993-1997 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 %% As a special exception, you may use this file and all files derived
25 %% from it without restrictions.  This special exception was added with
26 %% version 3.7 of Xy-pic.
27 %%

28 \expandafter\ifx\csname xyps-lloaded\endcsname\empty
29 \message{not reloaded}\endinput \fi
30 \expandafter\let\csname xyps-lloaded\endcsname=\empty \xycatcodes

4.11.9 Line-styles

The included file xyps-l.tex (version 3.7) provides PostScript support for the effects defined in the line extension described in §2.4.

The PostScript style methods are required, so ensure that they are loaded.

49 \expandafter\ifx\csname xyps-sloaded\endcsname\empty\else
50 \xyinputorelse@{xyps-s}{\xyerror@{Could not load xyps-s}{}}%
51 \xycatcodes\fi

This file is loaded and its effects are activated automatically whenever \xyoption{line} is requested and the current ⟨driver⟩ supports PostScript line styles. Should there be any need to turn off this support, the following commands are available; they obey usual TEX groupings.

\NoPSlines remove PostScript support
\UsePSlines reinstate PostScript.

Without PostScript support lines can be expected to be displayed in the default style, having thickness of .4pt. These commands are provided primarily for testing and trouble-shooting; e.g. with ⟨driver⟩ configurations untested by the authors of XY-pic, who should be notified of any difficulties.

Installation The ⟨driver⟩-file must call the following macro to rebind a control sequence defined in xyline, thereby allowing the PostScript method to be used. The purpose of the \xyPSlinew@ hook is to allow the PostScript style sequencing method to be used with other back-ends, changing just the contents of the \specials actually placed.

83 \xydef@\installPSline@{\installPSstyle@
84 \installPSlinestyles@ \installPSpolylines@ }
86 \xydef@\UsePSlines{\installPSline@}
87 \xydef@\NoPSlines{\UnloadLine@\relax}

widths, joins and caps This, and the rebindings below, is all that is needed for the cleaner, more sophisticated way.

98 \xydef@\xyPSlineSpecial@#1{\addtostyletoks@{ #1 lw}}
99 \xydef@\xyPScapSpecial@#1{\addtostyletoks@{ #1 lc}}
100 \xydef@\xyPSjoinSpecial@#1{\addtostyletoks@{ #1 lj}}
101 \xydef@\xyPSmiterSpecial@#1{\addtostyletoks@{ #1 ml}}
103 \xydef@\installPSlinestyles@{%
104 \let\xylinewidth@@=\xylinewidth@
105 \let\transxyline@@=\transxyline@
106 \let\xylineSpecial@@=\xyPSlineSpecial@
107 \let\resetxyline@@=\resetxyline@i

108 %

109 \let\xy@linecap@@=\xy@linecap@
110 \let\xycapSpecial@@=\xyPScapSpecial@

111 \let\resetxylinecap@@=\resetxylinecap@i

112 %

113 \let\xy@linejoin@@=\xy@linejoin@
114 \let\xyjoinSpecial@@=\xyPSjoinSpecial@
115 \let\resetxylinejoin@@=\resetxylinejoin@i

116 %

117 \let\xy@linemiter@@=\xy@linemiter@
118 \let\xymiterSpecial@@=\xyPSmiterSpecial@
119 \let\resetxylinemiter@@=\resetxylinemiter@i

120 }

The PostScript operators lw, lc, lj, ml are defined in xyps-ps to set the linewidth, linecap, linejoin, miterlimit graphics-state parameters, respectively.

132 \xydef@\xypolylinePS@Special#1{\PSmacro@{#1 pl}}
133 \xydef@\xypolydotPS@Special#1{\PSmacro@{#1 pt}}
134 \xydef@\xypolydashPS@Special#1{\PSmacro@{#1 pd}}
135 \xydef@\xypolyfillPS@Special#1{\PSmacro@{#1 pf}}
136 \xydef@\xypolyeofillPS@Special#1{\PSmacro@{#1 pe}}
138 \xydef@\installPSpolylines@{%
139 \let\xypolyline@Special=\xypolylinePS@Special
140 \let\xypolydot@Special=\xypolydotPS@Special
141 \let\xypolydash@Special=\xypolydashPS@Special
142 \let\xypolyfill@Special=\xypolyfillPS@Special
143 \let\xypolyeofill@Special=\xypolyeofillPS@Special
144 \let\xy@polystyle@@=\xy@polystyle@ }

Poly-lines

The end & Log

152 \endinput
154 % $Log: xyps-l.doc,v $
155 % Revision 3.7  1999/02/16 15:12:50  krisrose
156 % Interim release (Y&Y fonts now free).

157 %

158 % Revision 3.4  1997/05/18 01:13:24  ross
159 % Essential bugfixes.

160 %

161 % Revision 3.3  1996/12/18  10:05:50  ross
162 % minor improvements to file-loading commands

163 %

164 % Revision 3.1  1995/09/05  20:36:33  ross
165 % Release!

166 %

167 % Revision 3.0  1995/07/07  20:13:19  ross
168 % Major release w/new User's Guide!

169 %

170 % Revision 2.13  1995/07/04  15:04:51  ross
171 % Ready for release of v3.

516 CHAPTER 4. DRIVERS

172 %

173 % Revision 2.9  1994/06/09  14:38:56  ross
174 % Release 3beta.
175 % Includes support for special effects: Rotations, Scaling, Line-width, Colour.
176 % Back-ends are separated into separate files.
177 % More back-ends are supported, experimentally --- needs testing.

178 %

179 % Revision 2.9  1994/06/09  14:38:56  ross
180 % Release 3beta.
181 % Includes support for special effects: Rotations, Scaling, Line-width, Colour.
182 % Back-ends are separated into separate files.
183 % More back-ends are supported, experimentally --- needs testing.

184 %

185 % NEW for version 2.9 by by Ross Moore.

4.11.10 xyps-r.doc

Header:

1 %% $Id: xyps-r.doc,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %%
3 %% Xy-pic ``PostScript Rotations and Scaling''.
4 %% Copyright (c) 1993-1996 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 %% As a special exception, you may use this file and all files derived
25 %% from it without restrictions.  This special exception was added with
26 %% version 3.7 of Xy-pic.
27 %%
28 \expandafter\ifx\csname xyps-rloaded\endcsname\empty
29 \message{not reloaded}\endinput \fi
30 \expandafter\let\csname xyps-rloaded\endcsname=\empty \xycatcodes

4.11.11 Rotations and scaling

The included file xyps-r.tex (version 3.7) provides PostScript support for the effects defined in the rotate extension described in §2.5.

The PostScript style methods are required, so ensure that they are loaded.

49 \expandafter\ifx\csname xyps-sloaded\endcsname\empty\else
50 \xyinputorelse@{xyps-s}{\xyerror@{Could not load xyps-s}{}}%
51 \xycatcodes\fi

This file is loaded and its effects are activated automatically whenever \xyoption{rotate} is requested and the current ⟨driver⟩ supports PostScript rotations. Should there be any need to turn off this support, the following commands are available; they obey usual TEX groupings.

\NoPSrotate remove PostScript support
\UsePSrotate reinstate PostScript.

Without PostScript support diagrams can be expected to be displayed unrotated and unscaled. These commands are provided primarily for testing and trouble-shooting; e.g. with ⟨driver⟩ configurations untested by the authors of XY-pic, who should be notified of persistent difficulties.

Installation Call the following macro to allow the PostScript mechanisms to be used.

79 \xydef@\installPSrotscale@{\installPSstyle@
80 \let\xyRotate@@=\xyPSrotate@@
81 % \let\xySpecialRotate@@=\xyPSspecialRotate@
82 \let\doSpecialRotate@@=\doPSspecialRotate@@
83 % \let\xyRotnamed@=\xyPSpsxy@
84 % \let\xyRot@named@=\xyPSrot@named@@
85 \let\xyscale@@=\xyPSscale@@
86 \xyPSshapes@true
87 \xyuncatcodes }
89 \xydef@\UsePSrotate{\installPSrotscale@}
90 \xydef@\NoPSrotate{\UnloadRotate@\relax}

All effects defined in the rotate extension can be implemented using a PostScript ⟨driver⟩. However different ⟨driver⟩s need not handle things in the same way; different PostScript code may be required to match the specific environment used by the ⟨driver⟩.

This file provides generic PostScript code which is known to work correctly with most drivers. It is written so as to indicate where modifications may be made to accomodate specific ⟨driver⟩s. For such driver-specific variations, consult the appropriate ⟨driver⟩-file, called xy⟨driver⟩.doc.

110 \xydef@\xyPSpretransform@{\xyPSrawA@{\preXYtransform@@}}
111 \xydef@\xyPSposttransform@{\xyPSrawZ@{\postXYtransform@@}}
113 \let\preXYtransform@=\xyPSpretransform@
114 \let\postXYtransform@=\xyPSposttransform@
116 \xydef@\xyPSrotSplit@{%
117 \expandafter\def\expandafter\preShape@@\expandafter{\xyPSpre@}%
118 \expandafter\def\expandafter\postShape@@\expandafter{\xyPSpost@}}

Transform lists

126 \xydef@\xyPSscale@@#1#2{%
127 \xyPSsplitPS@{\xyscale@start(#1,#2)}{\xyscale@end}%
128 \xyPSrotSplit@\xyPSpsxy@ }

Rescaling

136 \xydef@\xyPSrotate@@#1{%
137 \xyPSsplitPS@{\xyrot@start(#1 xyd)}{\xyrot@end}%
138 \xyPSrotSplit@\xyPSpsxy@ }
140 \xydef@\xyPSspecialRotate@#1{%
141 \xyPSsplitPS@{\xyrot@start(#1)}{\xyrot@end}\xyPSrotSplit@\xyPSpsxy@ }
143 \xydef@\doPSspecialRotate@@#1@@{\xyPSspecialRotate@{#1}}

Rotations The PostScript operator xyr is defined in xyps-ps.doc, to store the given parameter as a rotation angle.

Shearing This feature is not implemented yet.

PostScript commands The PostScript codes to start the rotation or scaling are given as functions, xyrot@start and xyscale@start with arguments to include a specification of the rotation-angle or scaling factors.

164 \xydef@\xyRotScale@@{%
165 \def\xyrot@start(##1){{xyt ##1\space xyr}}%
166 \def\xyscale@start(##1,##2){{xyt ##1\space##2\space xys}}%
167 \def\xyrot@end{}\def\xyscale@end{}}

These strings are placed using \xyPSsplitPS@ so as to correctly occur before and after the code for the actual ⟨object⟩ being typeset. This is always followed by \xyPSpsxy@, which results in Post-Script code to identify the current position, storing it with keys xyXpos and xyYpos so as to be accessible to the code for the rotation or scaling.

A specific ⟨driver⟩ must either call \xyRotScale@@ to use this default mechanism, or define its own macro to be called at installation time, which sets alternative expansions to \xyrot@start(#1),

\xyscale@start(#1,#2), \xyrot@end and \xyscale@end.

The end & Log

186 \endinput
188 % $Log: xyps-r.doc,v $
189 % Revision 3.7  1999/02/16 15:12:50  krisrose
190 % Interim release (Y&Y fonts now free).

191 %

192 % Revision 3.3  1996/12/18  10:05:50  ross
193 % minor improvements to file-loading commands

194 %

195 % Revision 3.1  1995/09/05  20:36:33  ross
196 % Release!

197 %

198 % Revision 3.0  1995/07/07  20:13:19  ross
199 % Major release w/new User's Guide!

4.11. EXTRA FEATURES WITH PostScript SUPPORT 519

201 % Revision 2.13  1995/07/04  15:04:51  ross
202 % Ready for release of v3.

203 %

204 % Revision 2.9  1994/06/09  14:38:56  ross
205 % Release 3beta.
206 % Includes support for special effects: Rotations, Scaling, Line-width, Colour.
207 % Back-ends are separated into separate files.
208 % More back-ends are supported, experimentally --- needs testing.

209 %

210 % Revision 2.9  1994/06/09  14:38:56  ross
211 % Release 3beta.
212 % Includes support for special effects: Rotations, Scaling, Line-width, Colour.
213 % Back-ends are separated into separate files.
214 % More back-ends are supported, experimentally --- needs testing.

215 %

216 % NEW for version 2.9 by by Ross Moore.

4.11.12 xyps-t.doc

Header:

1 %% $Id: xyps-t.doc,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %%
3 %% Xy-pic ``Pattern and Tile extension'' PostScript support.
4 %% Copyright (c) 1993-1997 Ross Moore <ross@mpce.mq.edu.au>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1997 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 %% As a special exception, you may use this file and all files derived
25 %% from it without restrictions.  This special exception was added with
26 %% version 3.7 of Xy-pic.
27 %%
28 \expandafter\ifx\csname xyps-tloaded\endcsname\empty
29 \message{not reloaded}\endinput \fi

30 \expandafter\let\csname xyps-tloaded\endcsname=\empty \xycatcodes

4.11.13 Patterns and tiles

The included file xyps-t.tex (version 3.7) provides PostScript support for the effects defined in the tile extension described in §2.7.

The PostScript style methods are required, so ensure that they are loaded.

49 \expandafter\ifx\csname xyps-sloaded\endcsname\empty\else
50 \xyinputorelse@{xyps-s}{\xyerror@{Could not load xyps-s}{}}%
51 \xycatcodes\fi

This file is loaded and its effects are activated automatically whenever \xyoption{tile} is requested and the current ⟨driver⟩ supports PostScript patterns. Should there be any need to turn off this support, the following commands are available; they obey usual TEX groupings.

\NoPStiles remove PostScript support
\UsePStiles reinstate PostScript.

Without PostScript support tile patterns can be expected to be displayed as solid black. These commands are provided primarily for testing and trouble-shooting; e.g. with ⟨driver⟩ configurations untested by the authors of XY-pic, who should be notified of any difficulties.

Installation Installation consists of rebinding the macros \xypattern@ and \newxypattern@ and of reloading the standard patterns to include a description for PostScript. This installation should be delayed till after pattern and the PostScript ⟨driver⟩ have been installed.

82 \xydef@\installPSpatterns@{\installPSstyle@
83 \let\xypattern@=\xyPSpattern@@
84 \let\xypatternwarning@=\relax
85 \xystandardpatterns@
86 \xyuncatcodes }
88 \xylet@\UnloadPSpatterns@=\Unloadpattern@
90 \xydef@\UsePStiles{\installPSpatterns@}
91 \xydef@\NoPStiles{\UnloadPSpatterns@\relax}

All effects defined in the tile extension can be implemented using the PostScript dictionary, loaded by xyps-ps. This file provides “generic” PostScript code which is known to work correctly with most drivers. No attempt is made to provide special code for particular drivers; for driver-specific variations, consult the appropriate xy⟨driver⟩.doc file.

104 \xydef@\xyPSnewpattern@#1#2#3#4#5{%
105 \expandafter\DN@\expandafter{\csname shape [#1]\endcsname}%
106 \DNii@{\relax}\ifx\next@\nextii@\newxypattern{#1}{}\relax\fi
107 \DNii@{#4}\ifx\nextii@\empty
108 \expandafter\DNii@\expandafter{\csname xyPSshape@#1@\endcsname}%
109 \expandafter\def\nextii@{\xyPSpattern@{#2 #3}}\else
110 \expandafter\DNii@\expandafter{\csname xyPSshape@#1@\endcsname}%
111 \expandafter\def\nextii@{\xyPSpattern@{#4}}\fi
112 \ifx\nextii@\empty\expandafter\def\next@{\xyPSnotimplemented@@`#1'@@}%
113 \else

114 \edef\tmp@{\noexpand\let\expandafter\noexpand\next@
115  \expandafter\noexpand\nextii@}\expandafter\tmp@\fi }
117 \xydef@\xyPSpattern@{\ifPSspecials@\expandafter\xyPSpattern@@
118 \else\expandafter\eat@\fi}%\xyPSpattern@@}
120 \xydef@\xyPSpattern@@#1{\bgroup \checkXyStyle@
121 \def\preStyle@@{\expandafter\addtostyletoks@\expandafter{\xyPSpre@}}%
122 \def\postStyle@@{\expandafter\addtostyletoks@\expandafter{\xyPSpost@}}%
123 \let\modPSboxz@=\modXYstyle@ \xyPS@pattern@@{#1}%
124 \toks@={\egroup\let\xy@style@=\relax \def\Drop@@}%
125 \expandafter\addtotoks@\expandafter{\expandafter{\Drop@@}\def\Connect@@}%
126 \expandafter\addtotoks@\expandafter{\expandafter{\Connect@@}}%
127 \the\toks@ }
129 \xydef@\xyPS@pattern@@#1{\xyPSsplitPS@{{#1}sp}{}}

The end & Log

137 \endinput
139 % $Log: xyps-t.doc,v $
140 % Revision 3.7  1999/02/16 15:12:50  krisrose
141 % Interim release (Y&Y fonts now free).

142 %

143 % Revision 3.4  1997/05/18 01:13:24  ross
144 % Essential bugfixes.

145 %

146 % Revision 3.3  1996/12/18  10:05:50  ross
147 % minor improvements to file-loading commands

148 %

149 % Revision 3.1  1995/09/05  20:36:33  ross
150 % Release!

151 %

152 % Revision 3.0  1995/07/07  20:13:19  ross
153 % Major release w/new User's Guide!

154 %

155 % Revision 2.13  1995/07/04  15:04:51  ross
156 % Ready for release of v3.

157 %

158 % NEW for version 3.0 by by Ross Moore.

522 CHAPTER 4. DRIVERS

Standard Fonts

This chapter presents the sources of the XY-pic standard fonts used by the kernel for computations and as the default way to draw lines and frames in the DVI output.

To Do: Rewrite the code to mft format with font tables.

5.1 Semidirectional font

These are fonts with symmetric characters in 64 directions created using the driver file xyd2.mf. The standard repertoire includes only one such font: xydash10.

5.1.1 xyd2.mf

1 % $Id: xyd2.mf,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %
3 % XYD2: generate characters of `Xy-pic SemiDirectional' font.
4 % Copyright (c) 1992  Kristoffer H. Rose  <krisrose@brics.dk>
5 %
6 % This file is part of the Xy-pic macro package.
7 %
8 % The Xy-pic macro package is free software; you can redistribute it and/or
9 % modify it under the terms of the GNU General Public License as published by
10 % the Free Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.

12 %

13 % The Xy-pic macro package is distributed in the hope that it will be
14 % useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16 % Public License for more details.

17 %

18 % You should have received a copy of the GNU General Public License along
19 % with this macro package; if not, write to the Free Software Foundation,
20 % Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

21 %

22 % As a special exception, you may use this file and all files derived
23 % from it without restriction.  This special exception was added with
24 % version 3.7 of Xy-pic.
25 % _________________________________________________________________________

26 %

27 % CONTENTS: Generate `semidirectional' characters from 0..127 by calling
28 % `chartowards(Code, Dx, Dy)' with

29 %

30 % Code:         0       30       31       63       95      127
31 % Dx,Dy:   31/32,1  1/32,1      0,-1     1,-1     1,0      1,1
32 %                /      |                                    /
33 % Direction:    o       o        o        o        o-       o
34 %                                |         \

35 %

36 % where the intervening codes are got by interpolating either Dx or Dy as
37 % appropriate.
38 % _________________________________________________________________________

39 %

40 % Parameters:

41 %

42 font_coding_scheme:="Xy-pic semidirectional";

43 %

44 font_x_height   segx#;
45 font_quad       segl#;
46 fontdimen 8:    segw#;                  % default_rule_thickness

47 %

48 % Characters:

49 %

50 for cc =  0 step 1 until  30: chartowards(cc,(31-cc)/32,         1); endfor;
51 for cc = 31 step 1 until  63: chartowards(cc,(cc-31)/32,        -1); endfor;
52 for cc = 64 step 1 until 127: chartowards(cc,         1,(cc-95)/32); endfor;

53 %

54 % $Log: xyd2.mf,v $
55 % Revision 3.7  1999/02/16 15:12:50  krisrose
56 % Interim release (Y&Y fonts now free).

57 %

58 % Revision 3.3  1996/12/19 03:31:56  krisrose
59 % Maintenance release

60 %

61 % Revision 3.0  1995/07/07 20:14:21  kris
62 % Major release w/new User's Guide!

63 %

64 % Revision 2.13  1995/07/04  15:11:17  kris
65 % Ready to release v3?

66 %

67 % Revision 2.12  1994/10/25  11:34:25  kris
68 % Interim release just before v3 [works with AMS-LaTeX 1.2]...

69 %

70 % Revision 2.7  1992/12/14  01:41:26  kris
71 % Generate all Xy-pic `semidirectionsl' characters.

72 %

73 % Extracted from xyline10.mf [Revision 2.1 1992/01/02 14:54:07 kris]

5.1. SEMIDIRECTIONAL FONT 525

´ 0 ´ 1 ´ 2 ´ 3 ´ 4 ´ 5 ´ 6 ´ 7
[figure: ´ 00x]

                                                                              ˝ 0x

[figure: ´ 01x]
[figure: ´ 02x]

                                                                              ˝ 1x

[figure: ´ 03x]
[figure: ´ 04x]

                                                                              ˝ 2x

[figure: ´ 05x]
[figure: ´ 06x]

                                                                              ˝ 3x

[figure: ´ 07x]
[figure: ´ 10x]

                                                                              ˝ 4x

[figure: ´ 11x]
[figure: ´ 12x]

                                                                              ˝ 5x

[figure: ´ 13x]
[figure: ´ 14x]

                                                                              ˝ 6x

[figure: ´ 15x]
[figure: ´ 16x]

                                                                              ˝ 7x

[figure: ´ 17x]

             ˝ 8      ˝ 9      ˝ A      ˝ B      ˝ C      ˝ D      ˝ E      ˝ F

Figure 5.1: Font table for xydash10.

5.1.2 xydash10

1 % $Id: xydash10.mf,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %
3 % XYDASH10: dashes for Xy-pic at 10 point.
4 % Copyright (c) 1991,1992  Kristoffer H. Rose  <krisrose@brics.dk>
5 %
6 % This file is part of the Xy-pic macro package.
7 %
8 % The Xy-pic macro package is free software; you can redistribute it and/or
9 % modify it under the terms of the GNU General Public License as published by
10 % the Free Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.

12 %

13 % The Xy-pic macro package is distributed in the hope that it will be
14 % useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16 % Public License for more details.

17 %

18 % You should have received a copy of the GNU General Public License along
19 % with this macro package; if not, write to the Free Software Foundation,
20 % Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

21 %

22 % As a special exception, you may use this file and all files derived
23 % from it without restriction.  This special exception was added with

24 % version 3.7 of Xy-pic.
25 % _________________________________________________________________________

26 %

27 % CONTENTS: Line segments going segl# in all rightward directions...each
28 % character has  (width + italic correction) = cos(direction) * segl#.
29 % _________________________________________________________________________

30 %

31 % SETUP:

32 %

33 font_identifier "XYDASH"; font_size 10pt#;
34 mode_setup;
36 % METANESS...

37 %

38 segl# = 1/2 designsize; define_pixels(segl);            % segment length
39 segx# = 1/5 designsize; define_pixels(segx);            % segment height
40 segw# = .4pt#; define_whole_blacker_pixels(segw);       % segment thickness

41 %

42 pickup pencircle scaled segw; char_pen := savepen;

43 %

44 % chartowards makes char cc with length segl line from (0,0) towards (dx,dy)...

45 %

46 def chartowards(expr cc,dx,dy) =
47 beginchar(cc, abs(dx)*segl#, 0, 0);
48  a := angle(dx,dy);
49  z0 = (0,0); z1 = z0 + dir a scaled segl;
50  pickup char_pen; draw z0--z1;
51  charic := abs ((cosd a)*segl#) - charwd;
52  penlabels(0,1);
53 endchar
54 enddef;
56 % TESTING...we redefine openit because the characters extend far to the
57 % left of the bounding box!

58 %

59 def openit = openwindow currentwindow
60 from origin to (screen_cols,screen_rows) at (-200,300) enddef;
62 % GENERATE...

63 %

64 input xyd2
66 bye.

67 %

68 % $Log: xydash10.mf,v $
69 % Revision 3.7  1999/02/16 15:12:50  krisrose
70 % Interim release (Y&Y fonts now free).

71 %

72 % Revision 3.3  1996/12/19 03:31:56  krisrose
73 % Maintenance release

74 %

75 % Revision 3.0  1995/07/07 20:14:21  kris

5.2. DIRECTIONAL FONT 527

76 % Major release w/new User's Guide!

77 %

78 % Revision 2.13  1995/07/04  15:11:17  kris
79 % Ready to release v3?

80 %

81 % Revision 2.7  1992/12/14  01:41:26  kris
82 % Now uses xyd2.mf.

83 %

84 % Based on obsolete xyline10.mf  2.1  1992/01/02  14:54:07  kris

5.2 Directional font

These are fonts with characters in 128 directions created using the driver file xyd.mf. The standard repertoire includes several such fonts.

5.2.1 xyd.mf

1 % $Id: xyd.mf,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %
3 % XYD: generate characters of `Xy-pic Directional' font.
4 % Copyright (c) 1992  Kristoffer H. Rose  <krisrose@brics.dk>
5 %
6 % This file is part of the Xy-pic macro package.
7 %
8 % The Xy-pic macro package is free software; you can redistribute it and/or
9 % modify it under the terms of the GNU General Public License as published by
10 % the Free Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.

12 %

13 % The Xy-pic macro package is distributed in the hope that it will be
14 % useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16 % Public License for more details.

17 %

18 % You should have received a copy of the GNU General Public License along
19 % with this macro package; if not, write to the Free Software Foundation,
20 % Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

21 %

22 % As a special exception, you may use this file and all files derived
23 % from it without restriction.  This special exception was added with
24 % version 3.7 of Xy-pic.
25 % _________________________________________________________________________

26 %

27 % CONTENTS: Generate `directional' characters from 0..127 by calling
28 % `chartowards(Code, Dx, Dy)' with

29 %

30 % Code:         0     15    31    47    63    79    95   111   127
31 % Dx,Dy:  -15/16,-1  0,-1  1,-1  1,0   1,1   0,1  -1,1  -1,0  -1,-1
32 %                                        /    |    \
33 % Direction:    o     o     o     o-    o     o     o    -o     o

34 %              /      |      \                                 /

35 %

36 % where the intervening codes are got by interpolating either Dx or Dy as
37 % appropriate.
38 % _________________________________________________________________________

39 %

40 % Parameters:

41 %

42 font_coding_scheme:="Xy-pic directional";

43 %

44 font_x_height   segx#;
45 font_quad       segl#;
46 fontdimen 8:    segw#;                  % default_rule_thickness

47 %

48 % Characters:

49 %

50 for cc =  0 step 1 until  31: chartowards(cc,(cc-15)/16,       -1); endfor;
51 for cc = 32 step 1 until  63: chartowards(cc,         1, (cc-47)/16); endfor;
52 for cc = 64 step 1 until  95: chartowards(cc,(79-cc)/16,        1); endfor;
53 for cc = 96 step 1 until 127: chartowards(cc,        -1,(111-cc)/16); endfor;

54 %

55 % $Log: xyd.mf,v $
56 % Revision 3.7  1999/02/16 15:12:50  krisrose
57 % Interim release (Y&Y fonts now free).

58 %

59 % Revision 3.3  1996/12/19 03:31:56  krisrose
60 % Maintenance release

61 %

62 % Revision 3.0  1995/07/07 20:14:21  kris
63 % Major release w/new User's Guide!

64 %

65 % Revision 2.13  1995/07/04  15:11:17  kris
66 % Ready to release v3?

67 %

68 % Revision 2.7  1992/12/14  01:41:26  kris
69 % Generate all Xy-pic `directional' characters.

70 %

71 % Extracted from xyatip10.mf [Revision 2.1 1992/01/02 14:54:07 kris]

5.2.2 xyatip10

1 % $Id: xyatip10.mf,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %
3 % XYATIP10: upper arrow tips for Xy-pic at 10 point "technical style".
4 % Copyright (c) 1991-1998  Kristoffer H. Rose  <krisrose@ens-lyon.fr>
5 %
6 % This file is part of the Xy-pic macro package.
7 %
8 % The Xy-pic macro package is free software; you can redistribute it and/or
9 % modify it under the terms of the GNU General Public License as published by

´ 0  ´ 1  ´ 2  ´ 3  ´ 4  ´ 5  ´ 6  ´ 7
[figure: ´ 00x]

                                                                              ˝ 0x

[figure: ´ 01x]
[figure: ´ 02x]

                                                                              ˝ 1x

[figure: ´ 03x]
[figure: ´ 04x]

                                                                              ˝ 2x

[figure: ´ 05x]
[figure: ´ 06x]

                                                                              ˝ 3x

[figure: ´ 07x]
[figure: ´ 10x]

                                                                              ˝ 4x

[figure: ´ 11x]
[figure: ´ 12x]

                                                                              ˝ 5x

[figure: ´ 13x]
[figure: ´ 14x]

                                                                              ˝ 6x

[figure: ´ 15x]
[figure: ´ 16x]

                                                                              ˝ 7x

[figure: ´ 17x]

             ˝ 8      ˝ 9      ˝ A      ˝ B      ˝ C      ˝ D      ˝ E      ˝ F

Figure 5.2: Font table for xyatip10.

10 % the Free Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.

12 %

13 % The Xy-pic macro package is distributed in the hope that it will be
14 % useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16 % Public License for more details.

17 %

18 % You should have received a copy of the GNU General Public License along
19 % with this macro package; if not, write to the Free Software Foundation,
20 % Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

21 %

22 % As a special exception, you may use this file and all files derived
23 % from it without restrictions.  This special exception was added with
24 % version 3.7 of Xy-pic.

25 %

26 font_identifier "XYATIP"; font_size 10pt#;
27 mode_setup;
29 input xytech
30 input xyatip
32 % $Log: xyatip10.mf,v $
33 % Revision 3.7  1999/02/16 15:12:50  krisrose
34 % Interim release (Y&Y fonts now free).

´ 0  ´ 1  ´ 2  ´ 3  ´ 4  ´ 5  ´ 6  ´ 7
[figure: ´ 00x]

                                                                              ˝ 0x

[figure: ´ 01x]
[figure: ´ 02x]

                                                                              ˝ 1x

[figure: ´ 03x]
[figure: ´ 04x]

                                                                              ˝ 2x

[figure: ´ 05x]
[figure: ´ 06x]

                                                                              ˝ 3x

[figure: ´ 07x]
[figure: ´ 10x]

                                                                              ˝ 4x

[figure: ´ 11x]
[figure: ´ 12x]

                                                                              ˝ 5x

[figure: ´ 13x]
[figure: ´ 14x]

                                                                              ˝ 6x

[figure: ´ 15x]
[figure: ´ 16x]

                                                                              ˝ 7x

[figure: ´ 17x]

             ˝ 8      ˝ 9      ˝ A      ˝ B      ˝ C      ˝ D      ˝ E      ˝ F

Figure 5.3: Font table for xybtip10.

36 % Revision 3.3  1996/12/19 03:31:56  krisrose
37 % Maintenance release

38 %

39 % Revision 3.0  1995/07/07  20:14:21  kris
40 % Major release w/new User's Guide!

41 %

42 % Revision 2.13  1995/07/04  15:11:17  kris
43 % Ready to release v3?

44 %

45 % Revision 2.7  1992/12/14  01:41:26  kris
46 % Now uses xyd.mf.

47 %

48 % Revision 2.1  1992/01/02  14:54:07  kris
49 % Release version.

50 %

51 % Revision 1.1  1991/11/27  06:40:24  kris
52 % Initial: \beta-test on DIKU.

53 %

54 % Based on obsolete xytip10.mf v.1.4.

5.2.3 xybtip10

1 % $Id: xybtip10.mf,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %
3 % XYBTIP10: lower arrow tips for Xy-pic at 10 point "technical style".

4 % Copyright (c) 1991,1992  Kristoffer H. Rose  <krisrose@brics.dk>
5 %
6 % This file is part of the Xy-pic macro package.
7 %
8 % The Xy-pic macro package is free software; you can redistribute it and/or
9 % modify it under the terms of the GNU General Public License as published by
10 % the Free Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.

12 %

13 % The Xy-pic macro package is distributed in the hope that it will be
14 % useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16 % Public License for more details.

17 %

18 % You should have received a copy of the GNU General Public License along
19 % with this macro package; if not, write to the Free Software Foundation,
20 % Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

21 %

22 % As a special exception, you may use this file and all files derived
23 % from it without restriction.  This special exception was added with
24 % version 3.7 of Xy-pic.

25 %

26 font_identifier "XYBTIP"; font_size 10pt#;
27 mode_setup;
29 input xytech
30 input xybtip
32 % $Log: xybtip10.mf,v $
33 % Revision 3.7  1999/02/16 15:12:50  krisrose
34 % Interim release (Y&Y fonts now free).

35 %

36 % Revision 3.3  1996/12/19 03:31:56  krisrose
37 % Maintenance release

38 %

39 % Revision 3.0  1995/07/07  20:14:21  kris
40 % Major release w/new User's Guide!

41 %

42 % Revision 2.13  1995/07/04  15:11:17  kris
43 % Ready to release v3?

44 %

45 % Revision 2.7  1992/12/14  01:41:26  kris
46 % Now uses xyd.mf.

47 %

48 % Revision 2.1  1992/01/02  14:54:07  kris
49 % Release version.

50 %

51 % Revision 1.1  1991/11/27  06:41:03  kris
52 % Initial: \beta-test on DIKU.

53 %

54 % Based on obsolete xytip10.mf v.1.4.

532 CHAPTER 5. STANDARD FONTS

´ 0 ´ 1 ´ 2 ´ 3 ´ 4 ´ 5 ´ 6 ´ 7
[figure: ´ 00x]

                                                                              ˝ 0x

[figure: ´ 01x]
[figure: ´ 02x]

                                                                              ˝ 1x

[figure: ´ 03x]
[figure: ´ 04x]

                                                                              ˝ 2x

[figure: ´ 05x]
[figure: ´ 06x]

                                                                              ˝ 3x

[figure: ´ 07x]
[figure: ´ 10x]

                                                                              ˝ 4x

[figure: ´ 11x]
[figure: ´ 12x]

                                                                              ˝ 5x

[figure: ´ 13x]
[figure: ´ 14x]

                                                                              ˝ 6x

[figure: ´ 15x]
[figure: ´ 16x]

                                                                              ˝ 7x

[figure: ´ 17x]

             ˝ 8      ˝ 9      ˝ A      ˝ B      ˝ C      ˝ D      ˝ E      ˝ F

Figure 5.4: Font table for xybsql10.

5.2.4 xybsql10

1 % $Id: xybsql10.mf,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %
3 % XYBSQL10: lower squiggles/quarter circles for Xy-pic at 10 point.
4 % Copyright (c) 1992  Kristoffer H. Rose  <krisrose@brics.dk>
5 %
6 % This file is part of the Xy-pic macro package.
7 %
8 % The Xy-pic macro package is free software; you can redistribute it and/or
9 % modify it under the terms of the GNU General Public License as published by
10 % the Free Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.

12 %

13 % The Xy-pic macro package is distributed in the hope that it will be
14 % useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16 % Public License for more details.

17 %

18 % You should have received a copy of the GNU General Public License along
19 % with this macro package; if not, write to the Free Software Foundation,
20 % Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

21 %

22 % As a special exception, you may use this file and all files derived
23 % from it without restriction.  This special exception was added with

24 % version 3.7 of Xy-pic.
25 % _________________________________________________________________________

26 %

27 % CONTENTS: Squiggles are quarter circles with secant in all directions.
28 % Each has zero bounding box around the start point, i.e., from which the
29 % quarter circle `turns letf' ... this can be illustrated as follows:

30 %

31 % Code:    [-1]   15   31   47   63   79   95   111  127
32 %                                          _
33 %                                 |   )     |   /\
34 %           _o    o    o    o    o-   o     o     o   _o
35 %          |     (     |_\/                      |
36 % _________________________________________________________________________

37 %

38 font_identifier "XYBSQL"; font_size 10pt#;
39 mode_setup;
41 % METANESS...

42 %

43 segl# = sqrt 2 * 1/4 designsize; define_pixels(segl);   % segment length
44 segx# = (sqrt 2 - 1)*segl#; define_pixels(segx);        % segment height
45 segw# = .4pt#; define_whole_blacker_pixels(segw);       % segment thickness

46 %

47 pickup pencircle scaled segw; char_pen := savepen;

48 %

49 % chartowards makes char cc with quarter circle that is secant to line
50 % from (0,0) to (dx,dy), turning left.

51 %

52 def chartowards(expr cc,dx,dy) =
53 beginchar(cc,0,0,0);
54  a := angle (dx,dy);
55  z0 = (0,0); z1 = segl * dir a;
56  pickup char_pen; draw z0{dir(a-45)}..{dir(a+45)}z1;
57 endchar
58 enddef;
60 % GENERATE...

61 %

62 input xyd
64 bye.

65 %

66 % $Log: xybsql10.mf,v $
67 % Revision 3.7  1999/02/16 15:12:50  krisrose
68 % Interim release (Y&Y fonts now free).

69 %

70 % Revision 3.3  1996/12/19 03:31:56  krisrose
71 % Maintenance release

72 %

73 % Revision 3.0  1995/07/07 20:14:21  kris
74 % Major release w/new User's Guide!

534 CHAPTER 5. STANDARD FONTS

75 %

76 % Revision 2.13  1995/07/04  15:11:17  kris
77 % Ready to release v3?

78 %

79 % Revision 2.7  1992/12/14  01:41:26  kris
80 % Now uses xyd.mf.

81 %

82 % Based on obsolete xyqc10.mf [Revision 2.6  1992/06/24  01:23:34  kris]

5.3 Special fonts

The kernel circle construction uses the following special font with 1/8 circle segments at various sizes:

5.3.1 xycirc10

1 % $Id: xycirc10.mf,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %
3 % XYCIRC10: 1/8 circles with varying radii for Xy-pic at 10 point.
4 % Copyright (c) 1992,1993  Kristoffer H. Rose  <krisrose@brics.dk>
5 %
6 % This file is part of the Xy-pic macro package.
7 %
8 % The Xy-pic macro package is free software; you can redistribute it and/or
9 % modify it under the terms of the GNU General Public License as published by
10 % the Free Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.

12 %

13 % The Xy-pic macro package is distributed in the hope that it will be
14 % useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16 % Public License for more details.

17 %

18 % You should have received a copy of the GNU General Public License along
19 % with this macro package; if not, write to the Free Software Foundation, Inc.,
20 % 675 Mass Ave, Cambridge, MA 02139, USA.

21 %

22 % As a special exception, you may use this file and all files derived
23 % from it without restriction.  This special exception was added with
24 % version 3.7 of Xy-pic.
25 % _________________________________________________________________________

26 %

27 % CONTENTS: 1/8 circles with radii from 1 to 32pt dissected into the 1/8
28 % circle segments shown below
29 %                                   6     5
30 %                                   .......         _
31 %                              7  ..   |   ..  4    |
32 %                                : |   |   | :      | radius
33 %                               :  |   |   |  :     |
34 %       Reference point ---> ___:__|___|___|__:_____|
35 %                               :  |   |   |  :

´ 0  ´ 1  ´ 2  ´ 3  ´ 4  ´ 5  ´ 6  ´ 7
[figure: ´ 00x]

                                                                            ˝ 0x

[figure: ´ 01x]
[figure: ´ 02x]

                                                                            ˝ 1x

[figure: ´ 03x]
[figure: ´ 04x]

                                                                            ˝ 2x

[figure: ´ 05x]
[figure: ´ 06x]

                                                                            ˝ 3x

[figure: ´ 07x]
[figure: ´ 10x]

                                                                            ˝ 4x

[figure: ´ 11x]
[figure: ´ 12x]

                                                                            ˝ 5x

[figure: ´ 13x]

[figure: ´ 14x]

                                                                            ˝ 6x

[figure: ´ 15x]

[figure: ´ 16x]

                                                                            ˝ 7x

[figure: ´ 17x]

         ˝ 8      ˝ 9       ˝ A      ˝ B     ˝ C      ˝ D       ˝ E      ˝ F

Figure 5.5: Font table for xycirc10.

36 %                                : |   |   | :
37 %                              0  .!   |   !.  3
38 %                                   ...|...
39 %                                   1     2

40 %

41 % such that each group of 8 characters cc+0 to cc+7 constitute a full circle
42 % with the given radius when typeset on the same baseline (as shown).

43 %

44 % The bounding box of each segment is the vertical slice of the unit square
45 % around the circle.

46 %

47 % The radius is given for each character group g = cc mod 8 by the formula

48 %

49 %  radius [pt] = g+1,           if  0 <= g < 8
50 %                2(g-8) + 10,   if  8 <= g < 12         [= 2g-6]
51 %                4(g-12) + 20,  if 12 <= g < 16         [= 4g-28]

52 %

53 % The bounding box of each segment is the smallest box enclosing it (not
54 % including the rule width) with reference point on the horizontal line
55 % through the center of the circle---so segment 1256 have either height or
56 % depth negative.
57 % _________________________________________________________________________

58 %

59 font_identifier "XYCIRC"; font_size 10pt#;
60 mode_setup;
62 % METANESS...

63 %

64 rulew# = .4pt#; define_whole_blacker_pixels(rulew); % line thickness

65 %

66 pickup pencircle scaled rulew; char_pen := savepen;
68 % TESTING...we redefine openit because the characters extend far to the
69 % left of the bounding box!

70 %

71 def openit = %let echar = endchar; def endchar = echar; stop ". " enddef;
72 openwindow currentwindow from origin to (1000,800) at (-200,300)
73 enddef;
75 % FONT.

76 %

77 % Font dimension 8 is the rule thickness (cf. The TeXbook, app.G)

78 %

79 font_coding_scheme:="Xy-pic 1/8 circles";
80 fontdimen 8:    rulew#;                 % default_rule_thickness
82 % Use the following macro that generates an entire group from character cc
83 % to cc+7 with radius:

84 %

85 def makeg(expr g,radius) =
87 minor# := (1 - sqrt 1/2) * radius;
88 major# := radius - minor#;

89 full#  := radius;
90 define_pixels(minor,major,full);
92 beginchar(8g  ,minor#,full#,full#); pickup char_pen;
93  z0=(0,0); z1=(minor,-major); draw z0{0,-1}..{1,-1}z1;
94  penlabels(0,1); endchar;
96 beginchar(8g+1,major#,full#,full#); pickup char_pen;
97  z0=(0,-major); z1=(major,-full ); draw z0{1,-1}..{1,0}z1;
98  penlabels(0,1); endchar;
100 beginchar(8g+2,major#,full#,full#); pickup char_pen;
101 z0=(0,-full); z1=(major,-major); draw z0{1,0}..{1, 1}z1;
102 penlabels(0,1); endchar;
104 beginchar(8g+3,minor#,full#,full#); pickup char_pen;
105 z0=(0,-major); z1=(minor,0); draw z0{1, 1}..{0, 1}z1;
106 penlabels(0,1); endchar;
108 beginchar(8g+4,minor#,full#,full#); pickup char_pen;
109 z0=(0, major); z1=(minor,0); draw z0{1,-1}..{0,-1}z1;
110 penlabels(0,1); endchar;
112 beginchar(8g+5,major#,full#,full#); pickup char_pen;
113 z0=(0, full); z1=(major, major); draw z0{1,0}..{1,-1}z1;
114 penlabels(0,1); endchar;
116 beginchar(8g+6,major#,full#,full#); pickup char_pen;
117 z0=(0, major); z1=(major, full); draw z0{1, 1}..{1,0}z1;
118 penlabels(0,1); endchar;
120 beginchar(8g+7,minor#,full#,full#); pickup char_pen;
121 z0=(0,0); z1=(minor, major); draw z0{0, 1}..{1, 1}z1;
122 penlabels(0,1); endchar
124 enddef;
126 % Make groups:

127 %

128 for g =  0 step 1 until  7: makeg(g,  (g+1)*pt#); endfor;
129 for g =  8 step 1 until 11: makeg(g, (2g-6)*pt#); endfor;
130 for g = 12 step 1 until 15: makeg(g,(4g-28)*pt#); endfor;
132 bye.
134 % $Log: xycirc10.mf,v $
135 % Revision 3.7  1999/02/16 15:12:50  krisrose
136 % Interim release (Y&Y fonts now free).

137 %

138 % Revision 3.3  1996/12/19 03:31:56  krisrose
139 % Maintenance release

140 %

141 % Revision 3.0  1995/07/07 20:14:21  kris
142 % Major release w/new User's Guide!

143 %

144 % Revision 2.13  1995/07/04  15:11:17  kris
145 % Ready to release v3?

´ 0  ´ 1  ´ 2  ´ 3  ´ 4  ´ 5  ´ 6  ´ 7
[figure: ´ 00x]

                                                                              ˝ 0x

[figure: ´ 01x]
[figure: ´ 02x]

                                                                              ˝ 1x

[figure: ´ 03x]
[figure: ´ 04x]

                                                                              ˝ 2x

[figure: ´ 05x]
[figure: ´ 06x]

                                                                              ˝ 3x

[figure: ´ 07x]
[figure: ´ 10x]

                                                                              ˝ 4x

[figure: ´ 11x]
[figure: ´ 12x]

                                                                              ˝ 5x

[figure: ´ 13x]
[figure: ´ 14x]

                                                                              ˝ 6x

[figure: ´ 15x]
[figure: ´ 16x]

                                                                              ˝ 7x

[figure: ´ 17x]

             ˝ 8      ˝ 9      ˝ A      ˝ B      ˝ C      ˝ D      ˝ E      ˝ F

Figure 5.6: Font table for xycmat10.

146 %

147 % Revision 2.7  1994/03/08  02:09:27  kris
148 % Release 3alpha.

149 %

150 % Revision 2.6.9.1  1994/03/07  04:22:46  kris
151 % Last internal 3alpha and pre-2.7 release.

152 %

153 % NEW file to go in version 2.7!
154 % Based on xymisc10.mf [Revision 2.6  1992/06/24  01:23:34  kris]

5.4 Optional fonts

The “tips” extension uses the following two fonts by default.

5.4.1 xycmat10

1 % $Id: xycmat10.mf,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %
3 % XYCMAT10: upper arrow tips for Xy-pic at 10 point "Computer Modern style".
4 % Copyright (c) 1994-1996  Kristoffer H. Rose  <krisrose@brics.dk>
5 %
6 % This file is part of the Xy-pic macro package.
7 %
8 % The Xy-pic macro package is free software; you can redistribute it and/or
9 % modify it under the terms of the GNU General Public License as published by

10 % the Free Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.

12 %

13 % The Xy-pic macro package is distributed in the hope that it will be
14 % useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16 % Public License for more details.

17 %

18 % You should have received a copy of the GNU General Public License along
19 % with this macro package; if not, write to the Free Software Foundation,
20 % Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

21 %

22 % As a special exception, you may use this file and all files derived
23 % from it without restriction.  This special exception was added with
24 % version 3.7 of Xy-pic.

25 %

26 font_identifier "XYCMAT"; font_size 10pt#;
27 mode_setup;
29 input xycm
30 input xyatip
32 % $Log: xycmat10.mf,v $
33 % Revision 3.7  1999/02/16 15:12:50  krisrose
34 % Interim release (Y&Y fonts now free).

35 %

36 % Revision 3.3  1996/12/19 03:31:56  krisrose
37 % Maintenance release

38 %

39 % Revision 3.0  1995/07/07  20:14:21  kris
40 % Major release w/new User's Guide!

41 %

42 % Revision 2.13  1995/07/04  15:11:17  kris
43 % Ready to release v3?

44 %

45 % Revision 2.12  1994/10/25  11:34:25  kris
46 % Interim release just before v3 [works with AMS-LaTeX 1.2]...

47 %

48 % Recreated from xyatip10.mf (Revision 2.7 1992/12/14 01:41:26 kris).

49 %

50 % Revision 2.6  1993/10/21  21:21:24  kris
51 % NEW for 2.7...

52 %

53 % Based on xyatip10.mf [2.6] and Knuth's SYMBOL.MF.

5.4.2 xycmbt10

1 % $Id: xycmbt10.mf,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %
3 % XYCMBT10: lower arrow tips for Xy-pic at 10 point "Computer Modern style".
4 % Copyright (c) 1994-1996  Kristoffer H. Rose  <krisrose@brics.dk>

´ 0  ´ 1  ´ 2  ´ 3  ´ 4  ´ 5  ´ 6  ´ 7
[figure: ´ 00x]

                                                                              ˝ 0x

[figure: ´ 01x]
[figure: ´ 02x]

                                                                              ˝ 1x

[figure: ´ 03x]
[figure: ´ 04x]

                                                                              ˝ 2x

[figure: ´ 05x]
[figure: ´ 06x]

                                                                              ˝ 3x

[figure: ´ 07x]
[figure: ´ 10x]

                                                                              ˝ 4x

[figure: ´ 11x]
[figure: ´ 12x]

                                                                              ˝ 5x

[figure: ´ 13x]
[figure: ´ 14x]

                                                                              ˝ 6x

[figure: ´ 15x]
[figure: ´ 16x]

                                                                              ˝ 7x

[figure: ´ 17x]

             ˝ 8      ˝ 9      ˝ A      ˝ B      ˝ C      ˝ D      ˝ E      ˝ F

Figure 5.7: Font table for xycmbt10.

5 %
6 % This file is part of the Xy-pic macro package.
7 %
8 % The Xy-pic macro package is free software; you can redistribute it and/or
9 % modify it under the terms of the GNU General Public License as published by
10 % the Free Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.

12 %

13 % The Xy-pic macro package is distributed in the hope that it will be
14 % useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16 % Public License for more details.

17 %

18 % You should have received a copy of the GNU General Public License along
19 % with this macro package; if not, write to the Free Software Foundation,
20 % Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

21 %

22 % As a special exception, you may use this file and all files derived
23 % from it without restriction.  This special exception was added with
24 % version 3.7 of Xy-pic.

25 %

26 font_identifier "XYCMBT"; font_size 10pt#;
27 mode_setup;
29 input xycm
30 input xybtip

5.4. OPTIONAL FONTS 541

32 % $Log: xycmbt10.mf,v $
33 % Revision 3.7  1999/02/16 15:12:50  krisrose
34 % Interim release (Y&Y fonts now free).

35 %

36 % Revision 3.3  1996/12/19 03:31:56  krisrose
37 % Maintenance release

38 %

39 % Revision 3.0  1995/07/07  20:14:21  kris
40 % Major release w/new User's Guide!

41 %

42 % Revision 2.13  1995/07/04  15:11:17  kris
43 % Ready to release v3?

44 %

45 % Revision 2.12  1994/10/25  11:34:25  kris
46 % Interim release just before v3 [works with AMS-LaTeX 1.2]...

47 %

48 % Recreated from xybtip10.mf (Revision 2.7 1992/12/14 01:41:26 kris).

49 %

50 % Revision 2.6  1993/10/21  21:21:24  kris
51 % NEW for 2.7...

52 %

53 % Based on xyatip10.mf [2.6] and Knuth's SYMBOL.MF.

The following fonts are made to match with the Euler math fonts.

5.4.3 xyeuat10

1 % $Id: xyeuat10.mf,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %
3 % XYEUAT10: upper arrow tips for Xy-pic at 10 point "Euler style".
4 % Copyright (c) 1994-1996  Kristoffer H. Rose  <kris@diku.dk>
5 %
6 % This file is part of the Xy-pic macro package.
7 %
8 % The Xy-pic macro package is free software; you can redistribute it and/or
9 % modify it under the terms of the GNU General Public License as published by
10 % the Free Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.

12 %

13 % The Xy-pic macro package is distributed in the hope that it will be
14 % useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16 % Public License for more details.

17 %

18 % You should have received a copy of the GNU General Public License along
19 % with this macro package; if not, write to the Free Software Foundation,
20 % Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

21 %

22 % As a special exception, you may use this file and all files derived
23 % from it without restriction.  This special exception was added with

´ 0  ´ 1  ´ 2  ´ 3  ´ 4  ´ 5  ´ 6  ´ 7
[figure: ´ 00x]

                                                                              ˝ 0x

[figure: ´ 01x]
[figure: ´ 02x]

                                                                              ˝ 1x

[figure: ´ 03x]
[figure: ´ 04x]

                                                                              ˝ 2x

[figure: ´ 05x]
[figure: ´ 06x]

                                                                              ˝ 3x

[figure: ´ 07x]
[figure: ´ 10x]

                                                                              ˝ 4x

[figure: ´ 11x]
[figure: ´ 12x]

                                                                              ˝ 5x

[figure: ´ 13x]
[figure: ´ 14x]

                                                                              ˝ 6x

[figure: ´ 15x]
[figure: ´ 16x]

                                                                              ˝ 7x

[figure: ´ 17x]

             ˝ 8      ˝ 9      ˝ A      ˝ B      ˝ C      ˝ D      ˝ E      ˝ F

Figure 5.8: Font table for xyeuat10.

24 % version 3.7 of Xy-pic.

25 %

26 font_identifier "XYEUAT"; font_size 10pt#;
27 mode_setup;
29 input xyeuler
30 input xyatip
32 % $Log: xyeuat10.mf,v $
33 % Revision 3.7  1999/02/16 15:12:50  krisrose
34 % Interim release (Y&Y fonts now free).

35 %

36 % Revision 3.3  1996/12/19 04:12:13  krisrose
37 % New for this maintenance release.

38 %

39 % Based on xycmat10.mf,v 3.0 1995/07/07 20:14:21 kris Exp

5.4.4 xyeubt10

1 % $Id: xyeubt10.mf,v 3.7 1999/02/16 15:12:50 krisrose Exp $
2 %
3 % XYEUBT10: lower arrow tips for Xy-pic at 10 point "Euler style".
4 % Copyright (c) 1994-1996  Kristoffer H. Rose  <kris@diku.dk>
5 %
6 % This file is part of the Xy-pic macro package.
7 %
8 % The Xy-pic macro package is free software; you can redistribute it and/or

´ 0  ´ 1  ´ 2  ´ 3  ´ 4  ´ 5  ´ 6  ´ 7
[figure: ´ 00x]

                                                                              ˝ 0x

[figure: ´ 01x]
[figure: ´ 02x]

                                                                              ˝ 1x

[figure: ´ 03x]
[figure: ´ 04x]

                                                                              ˝ 2x

[figure: ´ 05x]
[figure: ´ 06x]

                                                                              ˝ 3x

[figure: ´ 07x]
[figure: ´ 10x]

                                                                              ˝ 4x

[figure: ´ 11x]
[figure: ´ 12x]

                                                                              ˝ 5x

[figure: ´ 13x]
[figure: ´ 14x]

                                                                              ˝ 6x

[figure: ´ 15x]
[figure: ´ 16x]

                                                                              ˝ 7x

[figure: ´ 17x]

             ˝ 8      ˝ 9      ˝ A      ˝ B      ˝ C      ˝ D      ˝ E      ˝ F

Figure 5.9: Font table for xyeubt10.

9 % modify it under the terms of the GNU General Public License as published by
10 % the Free Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.

12 %

13 % The Xy-pic macro package is distributed in the hope that it will be
14 % useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16 % Public License for more details.

17 %

18 % You should have received a copy of the GNU General Public License along
19 % with this macro package; if not, write to the Free Software Foundation,
20 % Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

21 %

22 % As a special exception, you may use this font file and all files derived
23 % from it without restriction.  This special exception was added with
24 % version 3.7 of Xy-pic.

25 %

26 font_identifier "XYEUBT"; font_size 10pt#;
27 mode_setup;
29 input xyeuler
30 input xybtip
32 % $Log: xyeubt10.mf,v $
33 % Revision 3.7  1999/02/16 15:12:50  krisrose
34 % Interim release (Y&Y fonts now free).

35 %

36 % Revision 3.3  1996/12/19 04:12:13  krisrose
37 % New for this maintenance release.

38 %

39 % Based on xycmbt10.mf,v 3.0 1995/07/07 20:14:21 kris Exp

Appendix A

Answers to all exercises

Answer to exercise 1.1 (p.22): In the default setup they are all denote the reference point of the XY-picture but the cartesian coordinate ⟨pos⟩ (0,0) denotes the point origo that may be changed to something else using the : operator.

Answer to exercise 1.2 (p.28): Use the ⟨pos⟩ition <X,Y >+"ob".

Answer to exercise 1.3 (p.29): It first sets c according to “… ”. Then it changes c to the point right of c at the same distance from the right edge of c as its width, w, i.e.,

The … w  × w

Answer to exercise 1.4 (p.38): The ⟨coord⟩ “{"A";"B": "C";"D", x}” returns the cross point. Here is how the author typeset the diagram in the exercise:

\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

A ?!… ⟨place⟩ could also have been used.

Answer to exercise 1.5 (p.40): To copy the p value to c, i.e., equivalent to “p”.

Answer to exercise 1.6 (p.40): When using the kernel connections that are all straight there is no difference, e.g., **{}?< 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.

Answer to exercise 1.7 (p.40): The code typesets the picture

Box •

Answer to exercise 1.8 (p.41): This does the job, saving each point to make the previous point available for the next piece:

\xy
 @={(0,-10),(10,3),(20,-5)},
 s0="prev" @@{;"prev";**@{-}="prev"}
\endxy

Notice how we close the line by first saving s0, the last point visited, such that the first point will be connected to it.

Answer to exercise 1.9 (p.44): The author used

\xy ={.{+DL(2)}.{+UR(2)}}"dbl",
 *+<3pc,2pc>{+}*\frm{.}, "dbl"*\frm{--}
\endxy

to typeset the figure in the exercise.

Answer to exercise 1.10 (p.51): 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: + a and + a .

Answer to exercise 1.11 (p.52): They have the outlines

∑ + and ∑ +

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.

Answer to exercise 1.12 (p.64): 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.

Answer to exercise 1.13 (p.64): None in both cases.

Answer to exercise 1.14 (p.79): One way is

$$\xy
 *{+}; p+(6,3)*{+} **{} ?(1)
 *@{-} *!/-5pt/^\dir{-}
 *^\dir{-} *!/^-5pt/\dir{-}
\endxy$$

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.

Answer to exercise 1.15 (p.88): One way is to add extra half circles skewed such that they create the illusion of a shade:

$$\xy
 *\cir<5pt>{}
 *!<-.2pt,.2pt>\cir<5pt>{dr^ul}
 *!<-.4pt,.4pt>\cir<5pt>{dr^ul}
 *!<-.6pt,.6pt>\cir<5pt>{dr^ul}
\endxy$$

Answer to exercise 2.1 (p.121): This is the code that was actually used:

\xy (0,20)*[o]+{A};(60,0)*[o]+{B}="B"
**\crv{} \POS?(.4)*_+!UR{0},"B"
**\crv{(30,30)} \POS?*^+!D{1},"B"
**\crv{(20,40)&(40,40)} \POS?*^+!D{2},"B"
**\crv{(10,20)&(30,20)&(50,-20)&(60,-10)}
\POS?*+^!UR{4} \endxy

Answer to exercise 2.2 (p.121): This is the code that was used to typeset the picture:

\xy (0,20)*+{A};(60,0)*+{B}
**\crv{(10,20)&(30,20)&(50,-20)&(60,-10)}
 ?<*\dir{<} ?>*\dir{>}
 ?(.65)*{\oplus} *!LD!/^-5pt/{x}
 ?(.65)/12pt/*{\oplus} *!LD!/^-5pt/{x'}
 ?(.28)*=0{\otimes}-/40pt/*+{Q}="q"
 +/100pt/*+{P};"q" **\dir{-}
\endxy

Answer to exercise 2.3 (p.122): Here is the code that was used to typeset the picture:

\def\ssz#1{\hbox{$_{^{#1}}$}}
\xy (0,0)*+{A};(30,-10)*+{B}="B",**\dir{-},
"B"**\crv{(5,20)&(20,25)&(35,20)}
 ?<(0)*\dir{<}="a" ?>(1)*\dir{>}="h"
 ?(.1)*\dir{<}="b" ?(.9)*\dir{>}="i"
 ?(.2)*\dir{<}="c" ?(.8)*\dir{>}="j"
 ?(.3)*\dir{<}="d" ?(.7)*\dir{>}="k"
 ?(.4)*\dir{<}="e" ?(.6)*\dir{>}="l"
 ?(.5)*\dir{|}="f",
 "a"*!RC\txt{\ssz{(\lt)}};
  "h"*!LC\txt{\ssz{\;(\gt)}},**\dir{.},
 "b"*!RD{\ssz{.1}};
  "i"*!L{\ssz{\;.9}},**\dir{-},

 "c"*!RD{\ssz{.2}};
  "j"*!L{\ssz{\;.8}},**\dir{-},
 "d"*!RD{\ssz{.3}};
  "k"*!L{\ssz{\;.7}},**\dir{-},
 "e"*!RD{\ssz{.4}};
  "l"*!LD{\ssz{.6}},**\dir{-},
 "f"*!D!/^-3pt/{\ssz{.5}}
\endxy

Answer to exercise 2.4 (p.200): Here is how:

\xy
 (0,0)  *++={A} *\frm{o} ;
 (10,7) *++={B} *\frm{o} **\frm{.}
\endxy

Answer to exercise 2.5 (p.203): The *\cir {} operation changes c to be round whereas *\frm {o} does not change c at all.

Answer to exercise 2.6 (p.206): Here is how:

\xy
 (0,0)  *+++{A} ;
 (10,7) *+++{B} **\frm{.}
 **\frm{^\}} ; **\frm{_\}}
\endxy

The trick in the last line is to ensure that the reference point of the merged object to be braced is the right one in each case.

Answer to exercise 2.7 (p.233): This is how the author specified the diagram:

\UseCrayolaColors
\xy\drop[*1.25]\xybox{\POS
(0,0)*{A};(100,40)*{B}**{}
 ?<<*[@_][red][o]=<5pt>{\heartsuit};
 ?>>>*[@_][Plum][o]=<3pt>{\clubsuit}
 **[|*][|.5pt][thicker]\dir{-},
?(.1)*[left]!RD\txt{label 1}*[red]\frm{.}
?(.2)*[!gsave newpath
  xyXpos xyYpos moveto 50 dup rlineto
  20 setlinewidth 0 0 1 setrgbcolor stroke
  grestore][psxy]{.},
?(.2)*[@]\txt{label 2}*[red]\frm{.},
?(.2)*[BurntOrange]{*},
?(.3)*[halfsize]\txt{label 3}*[red]\frm{.}
?(.375)*[flip]\txt{label 4}*[red]\frm{.}
?(.5)*[dblsize]\txt{label 5}*[red]\frm{.}
?(.5)*[WildStrawberry]{*},
?(.7)*[hflip]\txt{label 6}*[red]\frm{.}
?(.8)*[vflip]\txt{label 7}*[red]\frm{.}

?(.9)*[right]!LD\txt{label 8}*[red]\frm{.}
?(.5)*[@][*.66667]!/^30pt/
 \txt{special effect: aligned text}
 *[red]\frm{.}
}\endxy

Answer to exercise 3.1 (p.305): Here is what the author did:

\xy *+{A}*\cir<10pt>{}="me"
 \PATH `ul^ur,"me" "me" |>*:(1,-.25)\dir{>}
\endxy

The trick is getting the arrow head right: the : modifier to the explicit \dir ⟨object⟩ does that.

Answer to exercise 3.2 (p.306): The author did

\xy(0,0)
 \ar @{-->} (30,7) ^A="a"
 \POS(10,12)*+\txt{label} \ar "a"
\endxy

Answer to exercise 3.3 (p.312): Here is the entire XY-picture of the exercise:

\xy ;<1pc,0pc>:
 \POS(0,0)*+{A}
 \ar    +(-2,3)*+{A'}*\cir{}
 \ar @2 +( 0,3)*+{A''}*\cir{}
 \ar @3 +( 2,3)*+{A'''}*\cir{}
 \POS(6,0)*+{B}
 \ar @1{||.>>} +(-2,3)*+{B'}*\cir{}
 \ar @2{||.>>} +( 0,3)*+{B''}*\cir{}
 \ar @3{||.>>} +( 2,3)*+{B'''}*\cir{}
\endxy

The first batch use the default {->} specification.

Answer to exercise 3.4 (p.312): The author used

\newdir{ >}{{}*!/-5pt/\dir{>}}

Answer to exercise 3.5 (p.313): The author used

\xy
 \ar @{>>*\composite{\dir{x}*\dir{+}}<<}
 (20,7)
\endxy

Answer to exercise 3.6 (p.314): The author used

\xy *{\circ}="b" \ar@(ur,ul) c
 \ar@{.>}@(dr,ul) (20,0)*{\bullet}
\endxy

Note that it is essential that the curving specification comes after the arrow style.

Answer to exercise 3.7 (p.325): Here is the code used to typeset the pasting diagram in figure 3.3.

\xymatrixrowsep{1.5pc}
\xymatrixcolsep{3pc}
\diagram
 &&\relax\rtwocell<0>^{f_3^{}\;\;}{\omit}
 &\relax\ddtwocell<0>{\omit}
  \drtwocell<0>^{\;\;f_4^{}}{<3>}
  \ddrrtwocell<\omit>{<8>}\\
&&&&\relax\drtwocell<0>^{\;\;f_5^{}}{\omit}\\
A \uurrlowertwocell<-6>{\omit}\relax
\uurrcompositemap<2>_{f_1^{}}^{f_2^{}}{<.5>}
 \drtwocell<0>_{g_1^{}\;}{\omit}
 &&&\relax\urtwocell<0>{\omit}
 &&\relax\rtwocell<0>^{f_6^{}\;}{\omit}
 &\relax\rlowertwocell<-3>_{g_4^{}}{<-1>}
 \rcompositemap<6>_{f_7^{}}^{f_8^{}}{\omit}
 & B \\
 &\relax\urrtwocell<0>{\omit}
 \xcompositemap[-1,4]{}%
  <-4.5>_{g_2^{}}^{g_3^{}}{\omit}\\
\enddiagram

For the straight arrows, it would have been simpler to use \..to provided xyarrow has been loaded. Instead \..twocell<0>...{\omit } was used to illustrate the versatility of nudging and \omit ; thus xy2cell can completely handle a wide range of diagrams, without requiring xyarrow. Note also the use of \relax at the start of each new cell, to avoid premature expansion of a complicated macro, which can upset the compiling mechanism.

Answer to exercise 3.8 (p.329): Here is the code used by the author to set the first diagram.

{\uppercurveobject{{?}}
 \lowercurveobject{{\circ}}
\xymatrixcolsep{5pc}
\xymatrixrowsep{2pc}
\diagram
 \relax\txt{ FUn }\rtwocell<8>{!\&}
 & \relax\txt{ gaMES }
 \enddiagram}

Here is the code used for the second diagram.

\xymatrixcolsep{2.5pc}
\xymatrixrowsep{4pc}
\diagram
 \relax\txt<1.5cm>{\bf Ground State}
 \rrtwocell<12>~^{+{}~**!/-2.5pt/\dir{>}}
 ~_{++{}~**!/5pt/\dir{<<}}
 ^{<1.5>\txt{\small continuous power}}
 _{<1.5>\txt{\small pulsed emission}}{!}

& \relax\;\; N\!i\,C\!d\;\; \Circled
& \relax\txt<1.50cm>{\bf Excited State}
\enddiagram

Answer to exercise 3.9 (p.357): The author did

\xymatrix @!=1pc {
 **[l] A\times B
     \ar[r]^{/A} \ar[d]_{/B}
 & B \ar[d]^{\times A}
\\
 A   \ar[r]_{B\times}
 & **[r] B\times A
}

Answer to exercise 3.10 (p.357): Modifiers are used to make all entries round with a frame – the general form is used to ensure that the sequence is well-defined. Finally the matrix is rotated to make it possible to enter it as a simple square:

\entrymodifiers={=<1pc>[o][F-]}
\xymatrix @ur {
 A \save[];[r] **\dir{-},
        [];[dr]**\dir{-},
        [];[d] **\dir{-}\restore
   & B \\
 C & D }

Answer to exercise 3.11 (p.359): Here is how:

\xymatrix @W=3pc @H=1pc @R=0pc @*[F-] {%
 : \save+<-4pc,1pc>*\hbox{\it root}
     \ar[]
   \restore
\\
 {\bullet}
   \save*{}
    \ar`r[dd]+/r4pc/`[dd][dd]
   \restore
\\
 {\bullet}
   \save*{}
    \ar`r[d]+/r3pc/`[d]+/d2pc/
          `[uu]+/l3pc/`[uu][uu]
   \restore
\\
 1 }

Answer to exercise 3.12 (p.365): The first A was named to allow reference from the last:

\xygraph{

 []A="A1" :@/^/ [r]A
          :@/^/ [r]A
          :@/^/ "A1" }

Answer to exercise 3.13 (p.368): The author did

\SelectTips{cm}{}
\objectmargin={1pt}
\xygraph{ !{0;(.77,-.77):0}
 !~:{@{-}|@{>}}
 w (:[r(.6)]{x_1}
   ,:[d]z:[r]y:[u(.6)]{x_2}:"x_1":"z"
    :@( {"w";"z"}, {"y";"z"})"z":"x_2") }

It also shows that one can use {}s inside delimited arguments provided one adds a space to avoid the {}s being shaved off!

Answer to exercise 3.14 (p.371): Here is the code actually used to typeset the \xypolygon s, within an \xygraph . It illustrates three different ways to place the numbers. Other ways are also possible.

\def\objectstyle{\scriptscriptstyle}
\xy \xygraph{!{/r2pc/:}
[] !P3"A"{\bullet}
"A1"!{+U*++!D{1}} "A2"!{+LD*+!RU{2}}
"A3"!{+RD*+!LU{3}} "A0"
[rrr]*{0}*\cir<5pt>{}
!P6"B"{~<-\cir<5pt>{}}
"B1"1 "B2"2 "B3"3 "B4"4 "B5"5 "B6"6 "B0"
[rrr]0 !P9"C"{~*{\xypolynode}}}\endxy

Appendix B

Backwards Compatibility

Backwards compatibility with XY-pic version 2 is ensured by the ‘v2’ option and its support files.

B.1 Version 2 Compatibility

Vers. 3.4 by Kristoffer H. Rose ⟨krisrose@brics.dk⟩

This section describes the special backwards compatibility with XY-pic version 2: diagrams written according to the “Typesetting diagrams with XY-pic: User’s Manual” [13] should typeset correctly with this loaded. The compatibility is available either as an XY-option or through the special files

xypic.sty and xypic.tex described below.

There are a few exceptions to the compatibility: the features described in §B.1.1 below are not provided because they are not as useful as the author originally thought and thus virtually never used. And one extra command is provided to speed up typesetting of documents with XY-pic version 2 diagrams by allowing the new compilation functionality with old diagrams.

The remaining sections list all the obsolete commands and suggest ways to achieve the same things using XY-pic 3.7, i.e., without the use of this option. They are grouped as to what part of XY-pic replaces them; the compilation command is described last.

Note: “version 2” is meant to cover all public releases of XY-pic in 1991 and 1992, i.e., version 1.40 and versions 2.1 through 2.6. The published manual cited above (for version 2.6) is the reference in case of variations between these versions, and only things documented in that manual will be supported by this option!^{1}

Header:

1 %% $Id: xyv2.doc,v 3.4 1997/05/18 01:14:25 krisrose Exp $
2 %%
3 %% Xy-pic ``Version 2 compatibility'' feature.
4 %% Copyright (c) 1993-1995  Kristoffer H. Rose  <kris@diku.dk>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1995  Kristoffer H. Rose  <kris@diku.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the

1In addition a few of the experimental facilities supported in v2.7–2.12 are also supported.

12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%
24 \ifx\xyloaded\undefined \input xy \fi
26 \xyprovide{v2}{Version 2 Compatibility}{\stripRCS$Revision: 3.4 $}%
27 {Kristoffer H.~Rose}{krisrose@brics.dk}%
28 {BRICS/Computer Science, University of Aarhus, Ny Munkegade, building 540,
29  DK--8000 Aarhus~C}

Before we start, the old name macro.

67 \xylet@\XY=\Xy

B.1.1 Unsupported incompatibilities

Here is a list of known incompatibilities with version 2 even when the v2 option is loaded.

• Automatic ‘shortening’ of arrow tails using |<< breaks was a bug and has been ‘fixed’ so it does not work any more. Put a |<\hole break before it.

• The version 2.6 * position operator is not available. The version 2.6 construction t_{0};t_{1}*(x,y) should be replaced by the rather long but equivalent construction

                         { t_{0} ;p+/r/: t_{1} ="1";p+/u/,x;(0,0);:
                                      "1";p+/r/,y;(0,0);::(x,y)}

In most cases t_{0};t_{1}**{}?(x), possibly with a trailing +/^… /, suffices instead.

• Using t_{0};t_{1}:(x,y) as the target of an arrow command does not work. Enclose it in braces, i.e.,

write

                                      { t_{0} ; t_{1} :(x,y)}

• The older \pit, \apit, and \bpit commands are not defined. Use \dir{>} (or \tip) with variants and rotation.

• The even older notation where an argument in braces to \rto and the others was automatically taken to be a ‘tail’ is not supported. Use the supported |<… notation.

If you do not use these features then your version 2 (and earlier) diagrams should typeset the same with this option loaded except that sometimes the spacing with version 3 is slightly different from that of version 2.6 which had some spacing bugs.

B.1.2 Obsolete kernel features

The following things are added to the kernel by this option and described here: idioms, obsolete positions, obsolete connections, and obsolete objects. For each we show the suggested way of doing the same thing without this option:

Removed AMS-TEX idioms

Some idioms from AMS-TEX are no longer used by XY-pic: the definition commands \define and \redefine, and the size commands \dsize, \tsize, \ssize, and \sssize. Please use the commands recommended for your format—for plain TEX these are \def for the first two and \displaystyle,

\textstyle, \scriptstyle, and \scriptscriptstyle for the rest. The v2 option ensures that they

are available anyway.

140 \ifx\redefine\undefined \let\redefine=\def \fi
141 \ifx\define\undefined \let\define=\xydef@ \fi
143 \ifx\dsize\undefined \let\dsize=\displaystyle \fi
144 \ifx\tsize\undefined \let\dsize=\textstyle \fi
145 \ifx\ssize\undefined \let\ssize=\scriptstyle \fi
146 \ifx\sssize\undefined \let\sssize=\scriptscriptstyle \fi

Version also 2 used the AMS-TEX \text and a (non-object) box construction \Text which are emulated—\text is only defined if not already defined, however, using the native one (of AMS-TEX or AMS-L^{A}TEX or whatever) if possible. Please use the \txt object construction described in §1.6.3 directly since it is more general and much more efficient!

157 \ifx\text\undefined
158 \def\text{\relax\textC}%
159 \xydef@\textC#1{\relax
160 \ifmmode\mathchoice
161  {\hbox{\the\textfont0\relax#1}}%
162  {\hbox{\the\textfont0\relax#1}}%
163  {\hbox{\the\scriptfont0\relax#1}}%
164  {\hbox{\the\scriptscriptfont0\relax#1}}%
165 \else{\relax#1}\fi}
166 \fi
168 \xydef@\Text{\relax\xyFN@\Text@}
170 \xydef@\TextC{\relax\textC}%
172 \xydef@\Text@{%
173 \addLT@\ifx\next \addGT@{\addLT@\DN@##1}{\A@=##1\Text@i}%
174 \else \DN@{\A@=\maxdimen \Text@i}\fi \next@}
176 \xydef@\Text@i#1{%
177 \ifmmode \mathchoice
178  {\expandafter\Text@ii\the\textfont0{#1}}%
179  {\expandafter\Text@ii\the\textfont0{#1}}%
180  {\expandafter\Text@ii\the\scriptfont0{#1}}%
181  {\expandafter\Text@ii\the\scriptscriptfont0{#1}}%
182 \else
183  \leavevmode \expandafter\Text@ii\the\textfont0{#1}%
184 \fi\ignorespaces}

186 \xydef@\Text@ii{\hbox\bgroup \txt@i}

Obsolete state

Upto version 2.6 users could access the state variables \cL, \cR, \cH, and \cD, which are defined.

197 \xylet@\cL=\L@c
198 \xylet@\cR=\R@c
199 \xylet@\cD=\D@c
200 \xylet@\cH=\U@c

From v2.7 to 2.12 users could use the names of the state \dimen registers \Xmin, \Xmax, \Ymin,

and \Ymax; \Xp, \Yp \Dp, \Up, \Lp, and \Rp; \Xc, \Yc \Dc, \Uc, \Lc, and \Rc; \Xorigin, \Yorigin,

\Xxbase, \Yxbase, \Xybase, and \Yybase. Now the same effect can be achieved using ⟨corner⟩s but v2 defines the aliases.

212 \xylet@\Xc=\X@c
213 \xylet@\Yc=\Y@c
214 \xylet@\Uc=\U@c
215 \xylet@\Dc=\D@c
216 \xylet@\Lc=\L@c
217 \xylet@\Rc=\R@c
219 \xylet@\Xp=\X@p
220 \xylet@\Yp=\Y@p
221 \xylet@\Up=\U@p
222 \xylet@\Dp=\D@p
223 \xylet@\Lp=\L@p
224 \xylet@\Rp=\R@p
226 \xylet@\dX=\d@X
227 \xylet@\dY=\d@Y
229 \xylet@\Xorigin=\X@origin
230 \xylet@\Yorigin=\Y@origin
231 \xylet@\Xxbase =\X@xbase
232 \xylet@\Yxbase =\Y@xbase
233 \xylet@\Xybase =\X@ybase
234 \xylet@\Yybase =\Y@ybase
236 \xylet@\Xmin=\X@min
237 \xylet@\Ymin=\Y@min
238 \xylet@\Xmax=\X@max
239 \xylet@\Ymax=\Y@max

Obsolete position manipulation

In version 2 many things were done using individual ⟨decor⟩ control sequences that are now done using ⟨pos⟩ operators.

Version 2 positioning Replacement

            \go⟨pos⟩  \POS;p,⟨pos⟩

\aftergo{⟨decor⟩}⟨pos⟩

                        \afterPOS{⟨decor⟩};p,⟨pos⟩

B.1. VERSION 2 COMPATIBILITY 557

            \merge            \POS.p\relax
            \swap             \POS;\relax
            \Drop{⟨text⟩}       \drop+{⟨text⟩}

The code is basically that of xy.doc 2.6…

265 \xydef@\go{\aftergo{}}
266 \xydef@\aftergo#1{\xy@\aftergo{\enter@\pfromthec@}\afterPOS{\xy@@\leave@#1}}
268 \xydef@\merge{\POS.p\relax}
270 \xydef@\swap{\xy@\swap\swap@}
272 \xydef@\Drop{\expandafter\drop\entrymodifiers@}

Obsolete connections These connections are now implemented using directionals.

Version 2 connection Replacement

            \none              \connect h\dir{}
            \solid             \connect h\dir{-}
            \Solid             \connect h\dir2{-}
            \Ssolid            \connect h\dir3{-}
            \dashed            \connect h\dir{--}
            \Dashed            \connect h\dir2{--}
            \Ddashed           \connect h\dir3{--}
            \dotted            \connect h\dir{.}
            \Dotted            \connect h\dir2{.}
            \Ddotted           \connect h\dir3{.}
            \dottedwith{⟨text⟩} \connect h{⟨text⟩}

Note how the ‘hidden’ specifier h should be used because version 2 connections did not affect the size of diagrams.

300 \xydef@\none{\xy@\none{}\ignorespaces}
302 \xydef@\solid{\connect h\dir{-}}
303 \xydef@\Solid{\connect h\dir2{-}}
304 \xydef@\Ssolid{\connect h\dir3{-}}
306 \xydef@\dashed{\connect h\dir{--}}
307 \xydef@\Dashed{\connect h\dir2{--}}
308 \xydef@\Ddashed{\connect h\dir3{--}}
310 \xydef@\dotted{\connect h\dir{.}}
311 \xydef@\Dotted{\connect h\dir2{.}}
312 \xydef@\Ddotted{\connect h\dir3{.}}
314 \xydef@\dottedwith#1{\connect h{#1}}

558 APPENDIX B. BACKWARDS COMPATIBILITY

Obsolete tips These objects all have \dir-names now:

Version 2 tip Replacement

               \notip      \dir{}
               \stop       \dir{|}
               \astop      \dir^{|}
               \bstop      \dir_{|}
               \tip        \dir{>}
               \atip       \dir^{>}
               \btip       \dir_{>}
               \Tip        \dir2{>}
               \aTip  \object=<5pt>:(32,-1)\dir^{>}
               \bTip  \object=<5pt>:(32,+1)\dir_{>}
               \Ttip       \dir3{>}
               \ahook      \dir^{(}
               \bhook      \dir_{(}
               \aturn      \dir^{'}
               \bturn      \dir_{'}
346 \xydef@\notip{\dir{}}
348 \xydef@\stop{\dir{|}}
349 \xydef@\astop{\dir^{|}}
350 \xydef@\bstop{\dir_{|}}
352 \xydef@\tip{\dir{>}}
353 \xydef@\atip{\dir^{>}}
354 \xydef@\btip{\dir_{>}}
356 \xydef@\Tip{\dir2{>}}
358 \xywarnifdefined\aTip
359 \xywarnifdefined\bTip
360 {\xyuncatcodes
361 \gdef\aTip{\object=<5pt>:(32,-1)\dir^{>}}
362 \gdef\bTip{\object=<5pt>:(32,+1)\dir_{>}}}
364 \xydef@\Ttip{\dir3{>}}
366 \xydef@\ahook{\dir^{(}}
367 \xydef@\bhook{\dir_{(}}
369 \xydef@\aturn{\dir^{'}}
370 \xydef@\bturn{\dir_{'}}

The older commands \pit, \apit, and \bpit, are not provided.

Obsolete object constructions The following object construction macros are made obsolete by the enriched ⟨object⟩ format:

Version 2 object  Replacement

\rotate(⟨factor⟩)⟨tip⟩

\object:(⟨factor⟩,⟨factor⟩){⟨tip⟩}

            \hole             \object+{}
            \squash⟨tip⟩  \object=0{⟨tip⟩}
            \grow⟨tip⟩  \object+{⟨tip⟩}

\grow<⟨dimen⟩>⟨tip⟩ \object+<⟨dimen⟩>{⟨tip⟩}

            \squarify{⟨text⟩}   \object+={⟨text⟩}

            \squarify<⟨dimen⟩>{⟨text⟩}
                        \object+=<⟨dimen⟩>{⟨text⟩}

where rotation is done in a slightly different manner in version 3.7 (it was never accurate in version 2). These are mostly just the unmodified version 2.6 code:

405 \xydef@\rotate{\hbox\bgroup
406 \DN@{\ifx (\next %)
407  \DN@(####1){\rotate@ii{####1}}%
408 \else \DN@{\rotate@i}\fi\next@}\xyFN@\next@}
410 \xydef@\rotate@i#1{\reverseDirection@ #1\OBJECT@x}
412 \xydef@\rotate@ii#1#2{\dimen@=#1\p@
413 \ifdim     \dimen@=-\p@ \aboveDirection@\xydashl@
414 \else\ifdim\dimen@= \p@ \belowDirection@\xydashl@
415 \else\ifdim\dimen@<-1.5\p@ \advance\dimen@-2\p@
416 \edef\next@{\expandafter\removePT@\the\dimen@}\vDirection@(-1,\next@){1pc}%
417 \else\ifdim\dimen@<-.5\p@ \vDirection@(#1,-1){1pc}%
418 \else\ifdim\dimen@< .5\p@ \vDirection@( 1,#1){1pc}%
419 \else\ifdim\dimen@<1.5\p@ \vDirection@(#1, 1){1pc}%
420 \else \dimen@=-\dimen@ \advance\dimen@2\p@
421 \edef\next@{\expandafter\removePT@\the\dimen@}\vDirection@(-1,\next@){1pc}%
422 \fi\fi\fi\fi\fi\fi
423 #2\OBJECT@x}
425 \xydef@\squash#1{%
426 \ifmmode\setboxz@h{\m@th${\mathstrut}#1{\mathstrut}$}\else\setboxz@h{#1}\fi
427 \setboxz@h{\kern-.5\wdz@ \dimen@=.5\ht\z@ \advance\dimen@-.5\dp\z@
428 \lower\dimen@\boxz@}%
429 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
431 \xydef@\grow{%
432 \DN@{\ifx <\next \DN@<####1>{\dimen@=####1\grow@\empty}%
433 \else \DN@{\dimen@=2\p@ \grow@\empty}\fi\next@}\xyFN@\next@}
435 \xydef@\grow@#1#{\grow@@{#1}}
436 \xydef@\grow@@#1#2{\relax
437 \ifmmode \setboxz@h{\kern\dimen@ \m@th$#2$\kern\dimen@}%
438 \else    \setboxz@h{\kern\dimen@ {#2}\kern\dimen@}\fi
439 \dimen@ii=\ht\z@ \advance\dimen@ii\dimen@ \ht\z@=\dimen@ii
440 \dimen@ii=\dp\z@ \advance\dimen@ii\dimen@ \dp\z@=\dimen@ii \boxz@}
442 \xydef@\squarify{\addEQ@{\addPLUS@\object}}

We also reimplement the version 2 undocumented \qc quarter circle which is now called \corn@@ of the frame extension.

449 \xydef@\qc{\corn@@}

B.1.3 Obsolete extensions & features

Version 2 had commutative diagram functionality corresponding to the frames extension and parts of the matrix and arrow features. These are therefore loaded and some extra definitions added to emulate commands that have disappeared.

Frames

The version 2 frame commands are emulated using the frame extension (as well as the \dotframed, \dashframed, \rounddashframed commands communicated to some users by electronic mail):

Version 2 object Replacement

             \framed          \drop\frm{-}
             \framed<⟨dimen⟩> \drop\frm<⟨dimen⟩>{-}
             \Framed          \drop\frm{=}
             \Framed<⟨dimen⟩> \drop\frm<⟨dimen⟩>{=}
             \dotframed       \drop\frm{.}
             \dashframed      \drop\frm{--}
             \rounddashframed \drop\frm{o-}
             \circled         \drop\frm{o}
             \Circled         \drop\frm{oo}

For each of the above commands (and a few hidden ones) we parse the above and convert to the proper format.

489 \xyrequire{frame}\xycatcodes
491 \xydef@\framed{\relax\convertframed{-}}
492 \xydef@\Framed{\relax\convertframed{=}}
494 \xydef@\circled{\relax\convertframed{o}}
495 \xydef@\Circled{\relax\convertframed{oo}}
497 \xydef@\convertframed#1{\DNii@##1@{\drop\frm##1{#1}}\xyFN@\convertframed@i}
499 \xydef@\convertframed@i{%
500 \addLT@\ifx \next
501 \addGT@{\addLT@\DN@##1}{\addGT@{\addLT@{\nextii@}##1}@}%
502 \else \DN@{\nextii@ @}\fi \next@}
504 \xydef@\dotframed{\relax\drop\frm{.}}
505 \xydef@\dashframed{\relax\drop\frm{--}}
506 \xydef@\rounddashframed{\relax\drop\frm{o-}}
508 \xydef@\filled{\DN@{%
509 \addLT@\ifx \next
510  \addGT@{\addLT@\DN@####1}{\xy@@{\frame@fill@@{####1}}}%
511 \else \DN@{\xy@@{\frame@fill@@\z@}}%
512 \fi\next@}\xyFN@\next@}
514 \xydef@\Filled{\DN@{%
515 \addLT@\ifx \next
516  \addGT@{\addLT@\DN@####1}{\xy@@{\frame@emph@@{####1}}}%
517 \else \DN@{\xy@@{\frame@emph@@\z@}}%
518 \fi\next@}\xyFN@\next@}

Matrices

The \diagram ⟨rows⟩ \enddiagram command is provided as an alias for \xymatrix{ ⟨rows⟩ } centered in math mode and \LaTeXdiagrams changes it to use \begin … \end syntax. v2 sets a special internal ‘old matrix’ flag such that trailing \\ are ignored and entries starting with * are safe.

532 \xyrequire{matrix}\xycatcodes
536 \xydef@\diagram#1\enddiagram{\relax\diagram@\diagram@@{#1}}
538 \xydef@\diagram@{\relax
539 \ifmmode \DN@##1##2{\vcenter{\oldxymatrix@true \xy##1{\xymatrix{##2}}\endxy}}%
540 \else\DN@##1##2{{\oldxymatrix@true \xy/u.8ex/##1{\xymatrix{##2}}\endxy}}%
541 \fi \next@}
543 \xydef@\LaTeXdiagrams{\def\diagram{\ltxdiagram@\diagram@@}%
544 \def\diagramnocompile{\ltxdiagram@\literal@}% Declared in Compiling
545 \def\diagramcompileto##1{\ltxdiagram@{\NoCompileMatrices\xycompileto{##1}}}}
547 \xydef@\ltxdiagram@#1#2\end#3{\relax
548 \DN@{#3}\DNii@{diagram}\ifx\next@\nextii@\diagram@{#1}{#2}\end{diagram}%
549 \else\xyerr@{Put \string{\string} around \string\begin...\string\end\space
550  within diagrams}\fi}
552 \xylet@\diagram@@=\literal@
554 \xydef@\NoisyDiagrams{}

\NoisyDiagrams is ignored because the matrix feature always outputs progress messages.

Finally the version 2 \spreaddiagramrows, \spreaddiagramcolumns spacing commands are em-

ulated using \xymatrixrowsep and \xymatrixcolsep:

565 \xydef@\spreaddiagramrows#1{\addPLUS@\xymatrixrowsep{#1}}
566 \xydef@\spreaddiagramcolumns#1{\addPLUS@\xymatrixcolsep{#1}}

Arrows

The main arrow commands of version 2 were the \morphism and \definemorphism commands which now have been replaced by the \ar command.

v2 provides them as well as uses them to define the version 2 commands \xto, \xline, \xdashed, \xdotted, \xdouble, and all the derived commands \dto, \urto, …; the \arrow commands of the β-releases of v3 is also provided.

Instead of commands like \rrto and \uldouble you should use the arrow feature replacements

\ar[rr] and \ar@{=}[ul].

The predefined turning solid arrows \lltou, …, \tord are defined as well; these are now easy to do with ⟨turn⟩s.

598 \xyrequire{arrow}\xycatcodes
599 \xylet@\arrow=\ar

\morphism is a reduced version of the \ar command.

605 %\xyuncatcodes \catcode35=6
606 % \def\next#1#2#3{\relax \PATH ~={#1} ~>{\POS?>*{#2}\relax} ~<{\POS;?<*{#3};\relax}}
607 %\xycatcodes
608 %\xylet@\morphism=\next
610 {\xyuncatcodes

611 \gdef\morPHISM#1#2#3{\PATH~={\oldconnect{#1}}~<{|<*{#3}}~>{|>*{#2}}}}
613 \xydef@\morphism{\relax\morPHISM}
615 \xylet@\connect@iii=\connect
616 \xydef@\oldconnect#1{%
617 \let\PATHlabelabove@@=\PATHlabelabove@ %KLUDGE!
618 \let\PATHlabelbelow@@=\PATHlabelbelow@
619 \let\connect=\preconnect#1\let\connect=\connect@iii}

To Do: Unpack this to what \PATH does…

\definemorphism is essentially unchanged except we now use the privacy checking commands.

628 \xydef@\definemorphism#1#2#3#4{%
629 \xydefcsname@{x#1}{\morphism{#2}{#3}{#4}}%
630 \xydefcsname@{u#1}{\morphism{#2}{#3}{#4}[u]}%
631 \xydefcsname@{d#1}{\morphism{#2}{#3}{#4}[d]}%
632 \xydefcsname@{l#1}{\morphism{#2}{#3}{#4}[l]}%
633 \xydefcsname@{r#1}{\morphism{#2}{#3}{#4}[r]}%
634 \xydefcsname@{uu#1}{\morphism{#2}{#3}{#4}[uu]}%
635 \xydefcsname@{dd#1}{\morphism{#2}{#3}{#4}[dd]}%
636 \xydefcsname@{ll#1}{\morphism{#2}{#3}{#4}[ll]}%
637 \xydefcsname@{rr#1}{\morphism{#2}{#3}{#4}[rr]}%
638 \xydefcsname@{ur#1}{\morphism{#2}{#3}{#4}[ur]}%
639 \xydefcsname@{ul#1}{\morphism{#2}{#3}{#4}[ul]}%
640 \xydefcsname@{dr#1}{\morphism{#2}{#3}{#4}[dr]}%
641 \xydefcsname@{dl#1}{\morphism{#2}{#3}{#4}[dl]}%
642 \xydefcsname@{uul#1}{\morphism{#2}{#3}{#4}[uul]}%
643 \xydefcsname@{uur#1}{\morphism{#2}{#3}{#4}[uur]}%
644 \xydefcsname@{ull#1}{\morphism{#2}{#3}{#4}[ull]}%
645 \xydefcsname@{urr#1}{\morphism{#2}{#3}{#4}[urr]}%
646 \xydefcsname@{ddl#1}{\morphism{#2}{#3}{#4}[ddl]}%
647 \xydefcsname@{ddr#1}{\morphism{#2}{#3}{#4}[ddr]}%
648 \xydefcsname@{dll#1}{\morphism{#2}{#3}{#4}[dll]}%
649 \xydefcsname@{drr#1}{\morphism{#2}{#3}{#4}[drr]}%
650 \xydefcsname@{uull#1}{\morphism{#2}{#3}{#4}[uull]}%
651 \xydefcsname@{uurr#1}{\morphism{#2}{#3}{#4}[uurr]}%
652 \xydefcsname@{ddll#1}{\morphism{#2}{#3}{#4}[ddll]}%
653 \xydefcsname@{ddrr#1}{\morphism{#2}{#3}{#4}[ddrr]}}
655 \definemorphism{to}\solid\tip\notip
656 \definemorphism{line}\solid\notip\notip
657 \definemorphism{dashed}\dashed\notip\notip
658 \definemorphism{dotted}\dotted\notip\notip
659 \definemorphism{double}\Solid\notip\notip

To Do: These could be hugely optimised by using the arrow feature directly…

Next the predefined bent morphisms of version 2. These required some hacking to work; I hope this doesn’t mean that the ⟨path⟩ semantics has changed to much… ◯_{¨⌢}

670 \xywarnifdefined\xyviitoi
671 \xywarnifdefined\xyviitoii
673 \xydef@\XXtoY@#1#2#3#4#5{\save;[#3]\relax
674 \xy@@{%

675 \dimen@=\turnradius@ \ifdim#1<#2\relax \dimen@ii=#2\else\dimen@ii=#1\fi
676 \advance\dimen@\ifdim\dimen@>\dimen@ii +\dimen@\else +\dimen@ii\fi
677 \edef\xyviitoi{\the\dimen@}\leave@}%
678 \xto ~{[#3]} `#4[#3]#5/#4\xyviitoi/ `[#3]}
680 \xydef@\toXY@#1#2#3#4#5{\xy@@{\idfromc@{@}%
681 \dimen@=\turnradius@ \dimen@ii=#1\relax
682 \advance\dimen@\ifdim\dimen@>\dimen@ii +\dimen@\else +\dimen@ii\fi
683 \edef\xyviitoi{\the\dimen@}%
684 \dimen@=\turnradius@ \dimen@ii=#2\relax
685 \advance\dimen@\ifdim\dimen@>\dimen@ii +\dimen@\else +\dimen@ii\fi
686 \edef\xyviitoii{\the\dimen@}}%
687 \morphism\solid{\object #4:(-1,0)\dir{>}}\notip
688 ~{`"@" "@"} `#3"@"#5/#3\xyviitoi/#5/#4\p@/ `"@"#5/#4\xyviitoii/}
690 \xyuncatcodes \catcode64=11 %
692 \xydef@\lltod{\XXtoY@\D@c\D@p{ll}{d}+}
693 \xydef@\lltou{\XXtoY@\U@c\U@p{ll}{u}+}
694 \xydef@\rrtod{\XXtoY@\D@c\D@p{rr}{d}+}
695 \xydef@\rrtou{\XXtoY@\U@c\U@p{rr}{u}+}
696 \xydef@\ddtol{\XXtoY@\L@c\L@p{dd}{l}+}
697 \xydef@\ddtor{\XXtoY@\R@c\R@p{dd}{r}+}
698 \xydef@\uutol{\XXtoY@\L@c\L@p{uu}{l}+}
699 \xydef@\uutor{\XXtoY@\R@c\R@p{uu}{r}+}
701 \xydef@\told{\toXY@\L@c\D@c{l}{d}+}
702 \xydef@\tolu{\toXY@\L@c\U@c{l}{u}+}
703 \xydef@\tord{\toXY@\R@c\D@c{r}{d}+}
704 \xydef@\toru{\toXY@\R@c\U@c{r}{u}+}
705 \xydef@\todl{\toXY@\D@c\L@c{d}{l}+}
706 \xydef@\todr{\toXY@\D@c\R@c{d}{r}+}
707 \xydef@\toul{\toXY@\U@c\L@c{u}{l}+}
708 \xydef@\tour{\toXY@\U@c\R@c{u}{r}+}
710 \xycatcodes

Finally the version 2 arrow radius default command that actually never worked but some people might have hoped…

717 \xydef@\TurnRadius{\addEQ@\turnradius}

B.1.4 Obsolete loading

The v2 User’s Manual says that you can load XY-pic with the command \input xypic and as a L^{A}TEX 2.09 ‘style option’ [xypic]. This is made synonymous with loading this option by the files xypic.tex and xypic.sty distributed with the v2 option.

xypic.doc

This file (version 3.3) just loads the v2 feature.

1 %% $Id: xypic.doc,v 3.3 1996/12/19 03:31:56 krisrose Exp $
2 %%
3 %% Xy-pic v2 compatibility loading.

4 %% Copyright (c) 1993-1996 Kristoffer H. Rose <krisrose@brics.dk>
5 %%
6 %% This file is part of the Xy-pic package for graphs and diagrams in TeX.
7 %% See the companion README and INSTALL files for further information.
8 %% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.dk>
9 %%
10 %% The Xy-pic package is free software; you can redistribute it and/or modify
11 %% it under the terms of the GNU General Public License as published by the
12 %% Free Software Foundation; either version 2 of the License, or (at your
13 %% option) any later version.
14 %%
15 %% The Xy-pic package is distributed in the hope that it will be useful, but
16 %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 %% for more details.
19 %%
20 %% You should have received a copy of the GNU General Public License along
21 %% with this package; if not, write to the Free Software Foundation, Inc.,
22 %% 675 Mass Ave, Cambridge, MA 02139, USA.
23 %%

Here it is…

36 \input xyv2
37 \endinput

The log reveals that this was originally the main file.

43 % $Log: xypic.doc,v $
44 % Revision 3.3  1996/12/19 03:31:56  krisrose
45 % Maintenance release

46 %

47 % Revision 3.0  1995/07/07 20:14:21  kris
48 % Major release w/new User's Guide!

49 %

50 % Revision 2.13  1995/07/04  15:11:17  kris
51 % Ready to release v3?

52 %

53 % Revision 2.10  1994/06/15  12:55:07  kris
54 % Second 3beta release: bug fixes.

55 %

56 % Revision 2.7  1994/03/08  02:06:01  kris
57 % Release 3alpha.

58 %

59 % Revision 2.6.9.1  1994/03/07  04:22:46  kris
60 % Last internal 3alpha and pre-2.7 release.

61 %

62 % This file NEW for version 2.7 for backwards compatibility.
63 % Original xypic.doc renamed to xy.doc.

xypic.sty

1 %% $Id: xypic.sty,v 3.3 1996/12/19 03:31:56 krisrose Exp $ -*-tex-*-
2 %%
3 %% LaTeX style option to load Xy-pic in version 2 compatibility mode.
4 %% by Kristoffer H. Rose  <krisrose@brics.dk>
5 %%
6 %% This file is in the public domain.  It is distributed in the hope that it
7 %% will be useful, but WITHOUT ANY WARRANTY; without even the implied
8 %% warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9 %%
10 \input{xy.sty}
11 \xyoption{v2}
12 \catcode`\@=\xystycatcode
13 \endinput
15 % $Log: xypic.sty,v $
16 % Revision 3.3  1996/12/19 03:31:56  krisrose
17 % Maintenance release

18 %

19 % Revision 3.0  1995/07/07 20:14:21  kris
20 % Major release w/new User's Guide!

21 %

22 % Revision 2.13  1995/07/04  15:11:17  kris
23 % Ready to release v3?

24 %

25 % Revision 2.8  1994/04/08  04:30:00  kris
26 % Second (bug fix) 3alpha release.

27 %

28 % Revision 2.7  1994/03/08  02:06:01  kris
29 % Release 3alpha.

B.1.5 Compiling v2-diagrams

In order to make it possible to use the new compilation features even on documents written with XY-pic v2, the following command was added in v2.12:

                      \diagramcompileto{ ⟨name⟩ } . . . \enddiagram

which is like the ordinary diagram command except the result is compiled (see note 1.5e). Note that compilation is not quite safe in all cases!

769 \xydef@\diagramcompileto#1#2\enddiagram{\relax
770 \diagram@{\NoCompileMatrices\xycompileto{#1}}{#2}}

There is also the following command that switches on automatic compilation of all diagrams created with the v2 \diagram … \enddiagram command:

                            \CompileAllDiagrams { ⟨prefix⟩ }
                            \NoCompileAllDiagrams
                            \ReCompileAllDiagrams

will apply \xycompileto{⟨prefix⟩n}{… } to each diagram with n a sequence number starting from 1.

Use \CompileMatrices and \CompilePrefix instead!

566 APPENDIX B. BACKWARDS COMPATIBILITY

If for some reason a diagram does not work when compiled then replace the \diagram command

with \diagramnocompile (or in case you are using the L^{A}TEX form, \begin{diagramnocompile}).

793 \xydef@\diagramnocompile#1\enddiagram{\relax\diagram@\literal@{#1}}
797 \xydef@\CompileAllDiagrams#1{\CompilePrefix{#1}\CompileMatrices}
798 \xydef@\NoCompileAllDiagrams{\NoCompileMatrices}
799 \xydef@\ReCompileAllDiagrams{\CompileMatrices}

End & log

807 \xyendinput
809 % $Log: xyv2.doc,v $
810 % Revision 3.4  1997/05/18 01:14:25  krisrose
811 % Essential bugfixes.

812 %

813 % Revision 3.3  1996/12/19 14:43:55  krisrose
814 % Maintenance release.

815 %

816 % Revision 3.2  1995/09/19  18:22:27  kris
817 % Bug fix release.

818 %

819 % Revision 3.1  1995/09/05  20:31:32  kris
820 % Releasing!

821 %

822 % Revision 3.0  1995/07/07  20:14:21  kris
823 % Major release w/new User's Guide!

824 %

825 % Revision 2.14  1995/07/05  22:10:12  kris
826 % Buglets...

827 %

828 % Revision 2.13  1995/07/04  15:11:17  kris
829 % Ready to release v3?

830 %

831 % Revision 2.12  1994/10/25  11:34:25  kris
832 % Interim release just before v3 [works with AMS-LaTeX 1.2]...

833 %

834 % Revision 2.11  1994/07/05  10:37:32  kris
835 % Third 3beta release [bug fixes].
836 % Experimental graph feature included (for ECCT-94 presentation).

837 %

838 % Revision 2.10  1994/06/15  12:55:07  kris
839 % Second 3beta release: bug fixes.

840 %

841 % Revision 2.9  1994/06/09  14:59:19  kris
842 % Release 3beta.

843 %

844 % Revision 2.8  1994/04/08  04:30:00  kris
845 % Second (bug fix) 3alpha release.

´ 0  ´ 1  ´ 2  ´ 3  ´ 4  ´ 5  ´ 6  ´ 7
[figure: ´ 00x]

                                                                              ˝ 0x

[figure: ´ 01x]
[figure: ´ 02x]

                                                                              ˝ 1x

[figure: ´ 03x]
[figure: ´ 04x]

                                                                              ˝ 2x

[figure: ´ 05x]
[figure: ´ 06x]

                                                                              ˝ 3x

[figure: ´ 07x]
[figure: ´ 10x]

                                                                              ˝ 4x

[figure: ´ 11x]
[figure: ´ 12x]

                                                                              ˝ 5x

[figure: ´ 13x]
[figure: ´ 14x]

                                                                              ˝ 6x

[figure: ´ 15x]
[figure: ´ 16x]

                                                                              ˝ 7x

[figure: ´ 17x]

             ˝ 8      ˝ 9      ˝ A      ˝ B      ˝ C      ˝ D      ˝ E      ˝ F

Figure B.1: Font table for xyline10.

847 % Revision 2.7  1994/03/08  02:06:01  kris
848 % Release 3alpha.

849 %

850 % Revision 2.6.9.1  1994/03/07  04:22:46  kris
851 % Last internal 3alpha and pre-2.7 release.

852 %

853 % NEW file to go in version 2.7 (extracted from xy.doc 2.6.1.1).

B.2 Obsolete fonts

These fonts are obsolete since v2.7 but remain part of the distribution to make it possible to print DVI files created with version 2.6 and earlier versions.

B.2.1 xyline10

1 % $Id: xyline10.mf,v 3.3 1996/12/19 03:31:56 krisrose Exp $ -*-tex-*-
2 %
3 % XYLINE10: line segments for XY mode at 10 point.
4 % Copyright (c) 1991,1992  Kristoffer H. Rose  <krisrose@brics.dk>
5 %
6 % This file is part of the XY-pic macro package.
7 %
8 % The XY-pic macro package is free software; you can redistribute it and/or
9 % modify it under the terms of the GNU General Public License as published by

10 % the Free Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.

12 %

13 % The XY-pic macro package is distributed in the hope that it will be
14 % useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16 % Public License for more details.

17 %

18 % You should have received a copy of the GNU General Public License along
19 % with this macro package; if not, write to the Free Software Foundation, Inc.,
20 % 675 Mass Ave, Cambridge, MA 02139, USA.

21 %

22 % CONTENTS: Line segments going either segl# down or to the right.  Codes
23 % range from 0 to 127, distributed evenly in each of the
24 % intervals between the `purely' horizontal/
25 % vertical/diagonal characters with code 31,        ..../
26 % 63, 95, and 127 (code -1 would be  pure as        :  /:
27 % well if it existed):                              : / :
28 %                                                   :/  :
29 %       ..../  ..../   |   o   o....  o....  o----  o...:
30 %       :  /:  :  /:   |   |   :\  :  :\  :
31 %       : / :  : / :   |   |   : \ :  : \ :
32 %       :/  :  :/  :   |   |   :  \:  :  \:
33 %       o...:  o...:   o   |   :...\  :...\

34 %

35 % Code: [-1]     0    30  31     63     64     95     127

36 %

37 font_identifier "XYLINE"; font_size 10pt#;
38 font_coding_scheme:="XY line segments";
39 mode_setup;
41 % METANESS...

42 %

43 segl# = 1/2 designsize; define_pixels(segl);    % line segment length
44 rulew# = .4pt#; define_whole_blacker_pixels(rulew); % line thickness

45 %

46 % drawsegment draws a line from (0,0) to the argument point...
47 def drawsegment expr endpoint =
48 z0 = (0,0); z1 = endpoint;
49 pickup pencircle scaled rulew rotated (angle (z1-z0) - 90);
50 draw z0--z1; penlabels(0,1) enddef;
52 % TESTING...we redefine openit because the characters extend far to the
53 % left of the bounding box!

54 %

55 def openit = openwindow currentwindow
56 from origin to (screen_cols,screen_rows) at (-200,300) enddef;
58 % FONT.

59 %

60 % Font dimension 8 is the rule thickness (cf. The TeXbook, app.G)

61 fontdimen 8: rulew#;

62 %

63 % The characters follow...

64 %

65 for cc = 0 step 1 until 30:
66 beginchar(cc,(31-cc)/32*segl#,segl#,0); drawsegment (w,h); endchar;
67 endfor;

68 %

69 for cc = 31 step 1 until 63:
70 beginchar(cc,(cc-31)/32*segl#,0,segl#); drawsegment (w,-d); endchar;
71 endfor;

72 %

73 for cc = 64 step 1 until 94:
74 beginchar(cc,segl#,0,(95-cc)/32*segl#); drawsegment (w,-d); endchar;
75 endfor;

76 %

77 for cc = 95 step 1 until 126:
78 beginchar(cc,segl#,(cc-95)/32*segl#,0); drawsegment (w,h); endchar;
79 endfor;

80 %

81 beginchar(127,segl#,segl#,0); drawsegment (w,h); endchar;
83 bye.

84 %

85 % $Log: xyline10.mf,v $
86 % Revision 3.3  1996/12/19 03:31:56  krisrose
87 % Maintenance release

88 %

89 % Revision 3.0  1995/07/07 20:14:21  kris
90 % Major release w/new User's Guide!

91 %

92 % Revision 2.1  1992/01/02  14:54:07  kris
93 % Release version.

94 %

95 % Revision 1.7  1991/12/17  04:51:16  kris
96 % Version distributed with `final draft' on Usenet.

97 %

98 % Revision 1.6  1991/11/27  06:54:21  kris
99 % \beta-test on DIKU.

100 %

101 % Revision 1.5  1991/10/21  23:19:08  kris
102 % Version described in DIKU student report 91-7-10.

103 %

104 % Revision 1.4  1991/07/28  22:16:18  kris
105 % Inverted char0..30 to avoid negative widths.

106 %

107 % Revision 1.3  1991/07/26  01:22:28  kris
108 % Set bounding box completely!

109 %

110 % Revision 1.2  91/06/09  21:59:49  kris

´ 0  ´ 1  ´ 2  ´ 3  ´ 4  ´ 5  ´ 6  ´ 7
[figure: ´ 00x]

                                                                              ˝ 0x

[figure: ´ 01x]
[figure: ´ 02x]

                                                                              ˝ 1x

[figure: ´ 03x]
[figure: ´ 04x]

                                                                              ˝ 2x

[figure: ´ 05x]
[figure: ´ 06x]

                                                                              ˝ 3x

[figure: ´ 07x]
[figure: ´ 10x]

                                                                              ˝ 4x

[figure: ´ 11x]
[figure: ´ 12x]

                                                                              ˝ 5x

[figure: ´ 13x]
[figure: ´ 14x]

                                                                              ˝ 6x

[figure: ´ 15x]
[figure: ´ 16x]

                                                                              ˝ 7x

[figure: ´ 17x]

             ˝ 8      ˝ 9      ˝ A      ˝ B      ˝ C      ˝ D      ˝ E      ˝ F

Figure B.2: Font table for xyqc10.

111 % separated METANESS and CHARACTERS

112 %

113 % Revision 1.1  91/06/06  22:52:31  kris
114 % furst succesful attempt

B.2.2 xyqc10

1 % $Id: xyqc10.mf,v 3.0 1995/07/07 20:14:21 kris Exp $ -*-tex-*-
2 %
3 % XYQC10: quarter circles for XY mode at 10 point.
4 % Copyright (c) 1992  Kristoffer H. Rose  <kris@diku.dk>
5 %
6 % This file is part of the XY-pic macro package.
7 %
8 % The XY-pic macro package is free software; you can redistribute it and/or
9 % modify it under the terms of the GNU General Public License as published by
10 % the Free Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.

12 %

13 % The XY-pic macro package is distributed in the hope that it will be
14 % useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16 % Public License for more details.

17 %

18 % You should have received a copy of the GNU General Public License along

19 % with this macro package; if not, write to the Free Software Foundation, Inc.,
20 % 675 Mass Ave, Cambridge, MA 02139, USA.

21 %

22 % CONTENTS: Quarter circles in all directions:

23 %

24 %                                   -.
25 %                            |   )   |  /\
26 %           o    o    o    o-'  o    o    o  .-o    o
27 %          (     |_\/                    |     (

28 %

29 % Code:   [-1]   15   31   47   65   79   95  111  127

30 %

31 % Each character has a cosinoid bounding box :-) with wd = cos I = sin F,
32 % where I,F are the angles from direction --> to the initial,final direction.

33 %

34 font_identifier "XYQC"; font_size 10pt#;
35 font_coding_scheme:="XY quarter circles";
36 mode_setup;
38 % METANESS...

39 %

40 qcd# = 1/2 designsize;  % quarter circle diameter
41 rulew# = .4pt#;         % quarter circle line width
42 define_pixels(qcd,rulew);

43 %

44 % beginqc draws the quarter circle starting in the direction towards endpoint
45 % and turning left...
46 def beginqc(expr cc,ex,ey) =
47 alpha := angle (ex,ey);
48 cw := sqrt(1/2) * abs(sind(alpha + 135));
49 beginchar(cc,cw*qcd#,0,0);
50 pickup pencircle scaled rulew rotated (alpha - 90);
51 if (cc<64): draw quartercircle shifted (-.5,0) rotated (alpha - 90)
52  scaled qcd
53 else: draw quartercircle shifted (-.5,0) rotated (alpha - 90) shifted (cw,0)
54  scaled qcd
55 fi
56 enddef;
58 % TESTING...we redefine openit because the characters extend far to the
59 % left of the bounding box!

60 %

61 def openit = openwindow currentwindow
62 from origin to (screen_cols,screen_rows) at (-200,200) enddef;
64 % FONT.

65 %

66 % Font dimension 8 is the rule thickness (cf. The TeXbook, app.G).
67 fontdimen 8: rulew#;

68 %

69 % Here are the characters...

70 %

71 for cc = 0 step 1 until 31:
72 beginqc(cc,cc-15,-16); endchar;
73 endfor;

74 %

75 for cc = 32 step 1 until 63:
76 beginqc(cc,16,cc-47); endchar;
77 endfor;

78 %

79 for cc = 64 step 1 until 95:
80 beginqc(cc,79-cc,16); endchar;
81 endfor;

82 %

83 for cc = 96 step 1 until 127:
84 beginqc(cc,-16,111-cc); endchar;
85 endfor;
87 bye.

88 %

89 % $Log: xyqc10.mf,v $
90 % Revision 3.0  1995/07/07 20:14:21  kris
91 % Major release w/new User's Guide!

92 %

93 % Revision 2.6  1992/06/24  01:23:34  kris
94 % Implemented and used for hooks.

B.2.3 xymisc10

1 % $Id: xymisc10.mf,v 3.3 1996/12/19 03:31:56 krisrose Exp $ -*-tex-*-
2 %
3 % XYMISC10: miscellaneous characters for XY mode at 10 point.
4 % Copyright (c) 1991,1992  Kristoffer H. Rose  <krisrose@brics.dk>
5 %
6 % This file is part of the XY-pic macro package.
7 %
8 % The XY-pic macro package is free software; you can redistribute it and/or
9 % modify it under the terms of the GNU General Public License as published by
10 % the Free Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.

12 %

13 % The XY-pic macro package is distributed in the hope that it will be
14 % useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16 % Public License for more details.

17 %

18 % You should have received a copy of the GNU General Public License along
19 % with this macro package; if not, write to the Free Software Foundation, Inc.,
20 % 675 Mass Ave, Cambridge, MA 02139, USA.

21 %

22 % CONTENTS:

´ 0  ´ 1  ´ 2  ´ 3  ´ 4  ´ 5  ´ 6  ´ 7
[figure: ´ 00x]

                                                                                ˝ 0x

[figure: ´ 01x]
[figure: ´ 02x]

                                                                                ˝ 1x

[figure: ´ 03x]
[figure: ´ 04x]

                                                                                ˝ 2x

[figure: ´ 05x]
[figure: ´ 06x]

                                                                                ˝ 3x

[figure: ´ 07x]
[figure: ´ 10x]

                                                                                ˝ 4x

[figure: ´ 11x]

[figure: ´ 12x]

                                                                                ˝ 5x

[figure: ´ 13x]

[figure: ´ 14x]

                                                                                ˝ 6x

´ 15x

        ˝ 8       ˝ 9       ˝ A       ˝ B       ˝ C        ˝ D        ˝ E        ˝ F

Figure B.3: Font table for xymisc10 scaled 578.

23 %   Metaness.
24 %   Testing...
25 %   Font.
26 %     Dot fitting the rule width.
27 %     Quarter circles with radii from 1 to 10 and 12 to 30 pt; all have
28 %       height = depth = .5width = radius and are centered such that they
29 %       enter and leave the box in the middle of the sides.

30 %

31 font_identifier "XYMISC"; font_size 10pt#;
32 font_coding_scheme:="XY miscellaneous";
33 mode_setup;
35 % METANESS...

36 %

37 rulew# = .4pt#; define_whole_blacker_pixels(rulew); % line thickness

38 %

39 def pickuppen = pickup pencircle scaled rulew enddef;
41 % TESTING...we redefine openit because the characters extend far to the
42 % left of the bounding box!

43 %

44 def openit = %%let echar = endchar; def endchar = echar; stop ". " enddef;
45 openwindow currentwindow
46  from origin to (1000,800) at (-200,300)
47 enddef;
49 % FONT.

50 %

51 % Font dimension 8 is the rule thickness (cf. The TeXbook, app.G)
52 fontdimen 8: rulew#;
54 % DOT FOR DOTTED LINES AND DUMMY CIRCLE...

55 %

56 beginchar(0,0,0,0); pickuppen; drawdot (0,0); endchar;
57 beginchar(1,0,0,0); pickuppen; drawdot (0,0); endchar;
58 beginchar(2,0,0,0); pickuppen; drawdot (0,0); endchar;
59 beginchar(3,0,0,0); pickuppen; drawdot (0,0); endchar;
61 % QUARTER CIRCLES...  The four circles with radius N pt, 0 < N <= 10, are
62 % located at N*4 + QUADRANT, where 1 <= QUADRANT <= 4.  All have width as
63 % their radius with reference point at the level of the horizontal end of the
64 % arc and height, depth as the extent of the arc.

65 %

66 for radius = 1 step 1 until 10:
67 beginchar(radius*4,2radius*pt#,radius*pt#,radius*pt#);
68  pickuppen;
69  draw quartercircle rotated 180 shifted (1,.5) scaled (radius*2pt);
70 endchar;
71 beginchar(radius*4+1,2radius*pt#,radius*pt#,radius*pt#);
72  pickuppen;
73  draw quartercircle rotated -90 shifted (0,.5) scaled (radius*2pt);
74 endchar;
75 beginchar(radius*4+2,2radius*pt#,radius*pt#,radius*pt#);

76  pickuppen;
77  draw quartercircle shifted (0,-.5) scaled (radius*2pt);
78 endchar;
79 beginchar(radius*4+3,2radius*pt#,radius*pt#,radius*pt#);
80  pickuppen;
81  draw quartercircle rotated 90 shifted (1,-.5) scaled (radius*2pt);
82 endchar;
83 endfor;

84 %

85 % For 12 <= N <= 40 we step in 2pt increments... so for 10 <= N <= 40 the
86 % quarter circle with radius N is located at (N div 2 + 20 + QUADRANT).

87 %

88 for radius = 12 step 2 until 40:
89 beginchar(radius*2+20,2radius*pt#,radius*pt#,radius*pt#);
90  pickuppen;
91  draw quartercircle rotated 180 shifted (1,.5) scaled (radius*2pt);
92 endchar;
93 beginchar(radius*2+21,2radius*pt#,radius*pt#,radius*pt#);
94  pickuppen;
95  draw quartercircle rotated -90 shifted (0,.5) scaled (radius*2pt);
96 endchar;
97 beginchar(radius*2+22,2radius*pt#,radius*pt#,radius*pt#);
98  pickuppen;
99  draw quartercircle shifted (0,-.5) scaled (radius*2pt);
100 endchar;
101 beginchar(radius*2+23,2radius*pt#,radius*pt#,radius*pt#);
102 pickuppen;
103 draw quartercircle rotated 90 shifted (1,-.5) scaled (radius*2pt);
104 endchar;
105 endfor;
107 bye.

108 %

109 % $Log: xymisc10.mf,v $
110 % Revision 3.3  1996/12/19 03:31:56  krisrose
111 % Maintenance release

112 %

113 % Revision 3.0  1995/07/07 20:14:21  kris
114 % Major release w/new User's Guide!

115 %

116 % Revision 2.6  1992/06/24  01:23:34  kris
117 % Cleaned up.

118 %

119 % Revision 2.1  1992/01/02  14:54:07  kris
120 % Release version.

121 %

122 % Revision 1.6  1991/11/27  06:54:21  kris
123 % \beta-test on DIKU.

124 %

125 % Revision 1.5  1991/10/21  23:19:08  kris

126 % Version described in DIKU student report 91-7-10.

127 %

128 % Revision 1.4  1991/08/22  01:07:46  kris
129 % Now has quarter circles to radius 40pt as required for xy.doc[1.28].

130 %

131 % Revision 1.3  1991/07/21  21:04:35  kris
132 % Tested with xy.doc[1.19].

133 %

134 % Revision 1.2  1991/07/19  14:52:26  kris
135 % Changed quarter circles to fit xy.doc[1.19?].

136 %

137 % Revision 1.1  1991/06/24  20:57:37  kris
138 % Works with xy.doc [1.6] :-)

Appendix C

GNU General Public License

Version 2, June 1991

Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA

Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

Preamble

The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software–to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation’s software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.

To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.

For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.

We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.

Also, for each author’s protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors’ reputations.

Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone’s free use or not licensed at all.

The precise terms and conditions for copying, distribution and modification follow.

Terms and conditions for copying, distribution and modification

0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The “Program”, below, refers to any such program or work, and a “work based on the Program” means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term “modification”.) Each licensee is addressed as “you”.

Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.

1. You may copy and distribute verbatim copies of the Program’s source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.

You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.

2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:

a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.

b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.

c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.

In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.

3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:

a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,

b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,

c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.

If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.

4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.

6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients’ exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.

7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.

This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.

8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.

9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and “any later version”, you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.

10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WAR-

RANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU AS-SUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRIT-ING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CON-SEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

END OF TERMS AND CONDITIONS

Appendix: How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.

<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy  <name of author>
This program 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.
This program 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 program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this when it starts in an interactive mode:

    Gnomovision version 69, Copyright (C) 19yy name of author
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands ‘show w’ and ‘show c’ should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than ‘show w’ and ‘show c’; they could even be mouse-clicks or menu items–whatever suits your program.

You should also get your employer (if you work as a programmer) or your school, if any, to sign a “copyright disclaimer” for the program, if necessary. Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  `Gnomovision' (which makes passes at compilers) written by James Hacker.
  <signature of Ty Coon>, 1 April 1989
  Ty Coon, President of Vice

This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.

Appendix D

Distribution support files

This appendix presents the sources of various support files that are part of theXY-pic source distribution (except the file COPYING that contains the text reproduced in appendix A): the files with ‘hype’ for the package, the installation instructions, and the generation instructions (to make XY-pic from the sources).

D.1 Hype

These files explain what XY-pic is as required by the CTAN ‘L^{A}TEX 2ε bundle’ standard.

D.1.1 CATALOG

1 Name: xypic
2 Version: 3.7 <1999/02/16>
4 Description: Xy-pic is a package for typesetting graphs and diagrams.
5 It is structured as several modules, each defining a custom notation for
6 a particular kind of graphical object or structure. Example objects are
7 arrows, curves, frames, and colouring/rotation on drivers that support
8 it; these can be organised in matrix, directed graph, path, polygon, knot,
9 and 2-cell structure. Xy-pic works with most formats, including LaTeX,
10 AMS-LaTeX, AMS-TeX, and plain TeX, and has been used to typeset
11 complicated diagrams from many application areas including category
12 theory, automata theory, algebra, neural networks, and database theory.
14 Keywords: diagram, picture, graph, arrow, curve, commutative diagram.
16 Author: Kristoffer H. Rose
17 Problems-To: Kristoffer.Rose@ens-lyon.fr
18 Address: LIP/ENS-Lyon; 46, Allee d'Italie; 69364 Lyon 7; FRANCE
20 <URL: http://www.ens-lyon.fr/~krisrose/>

D.1.2 README

1 -*-text-*- $Id: README,v 3.6 1998/03/06 01:28:05 krisrose Exp $
3  ======================================================
4  THE Xy-pic PACKAGE FOR TYPESETTING GRAPHS AND DIAGRAMS
5  ======================================================

7 Xy-pic is a package for typesetting graphs and diagrams with TeX.
9 It works with most formats, including LaTeX (both 2.09 and 2e),
10 AMS-LaTeX, AMS-TeX, and plain TeX.
12 It has been used to typeset complicated diagrams from many application
13 areas including category theory, automata theory, algebra, neural
14 networks, and database theory.
16  - o -
18 See below in this file for an overview of the structure and features!
19 See CATALOG for up to date version information!
20 See TRAILER for author and accessibility information!
21 See COPYING for the conditions for redistribution and modification!
22 See MANIFEST for a complete file list!
23 See VERSIONS for the exact list of the versions of all source files!
24 See the various INSTALL files for how to install Xy-pic on your system!
25 See the W3 <URL: http://www.ens-lyon.fr/~krisrose/Xy-pic.html> for news!
27  - o -
29 Xy-pic is structured as a `kernel' and several orthogonal modules called
30 `options', each defining a custom notation for a particular kind of
31 graphical object or structure.
33 These (combinable) structures are available:
35 * A graph combinator mode where diagrams are specified the way they are
36  composed as graphs.
38 * A matrix-like mode where the dimensions of the drawing are computed by
39  aligning diagram entries in rows and columns (this is the `diagram'
40  mode Xy-pic version 2 users are used to).
42 * A polygon mode where diagrams shaped as regular polygons are entered
43  in a simple way.
45 * A mode for typesetting beautiful knots and links.
47 * A general object-oriented `turtle graphic' drawing language for
48  specifying graphs with objects and connections between them in a
49  manner independent of orientation.
51 The following objects may be used:
53 + Positions can be given in variety of formats (extendable) including
54  user defined coordinates (x,y) and relative to previous positions,
55  objects, object edges, and points on connections.
57 + Objects may be circular, elliptic, or rectangular (more shapes can be
58  added) and adjusted in several ways.
60 + Large library of objects with mnemonic names.
62 + Objects that orient themself along a connection when placed relative
63  to it, e.g., `\dir{|-}' is like \vdash but thus oriented; new such
64  objects can be defined in a convenient way.
66 + TeX `boxes', i.e., text and mathematical formulae.
68 + Includes circle segments and optionally arbitrary elliptical,

D.2. INSTALLATION INSTRUCTIONS 585

69  quadratic, and cubic arcs.
71 + Connections are aligned between the reference points of objects but
72  start and end on the edges.
74 + Any object can be used to build a connection (using `diagonal
75  filling'); library objects provide common line types.
77 + Flexible notation for drawing arrows and general paths with tail,
78  stem, and head built from any object(s).  Special support for arrows
79  that cross each other, arrows that `go by' other entries, paired
80  arrows (including support for 2-cells), curved arrows, and arrows with
81  bends.
83 + Library of frames and braces.
85 + Special notation for rotation, scaling, colour, and line thickness.
86  The correct typesetting of these features requires a backend that
87  supports it (i.e., PostScript) but even when this is not available
88  Xy-pic tries to approximate what is requested such that at least the
89  picture size is stable (and thus page breaks).
91 + Output can use PostScript for drawing (several \special formats are
92  supported: dvips, Textures, and OzTeX -- more are being added
93  continuously: contact Ross Moore <ross@mpce.mq.edu.au> for the current
94  list).  Notation for inclusion of literal PostScript is available.
96 * Other graphics can be imported and then `decorated' using Xy-pic.
98 All object forms may be used with all structures.
100  - o -
102 Finally, enjoy Xy-pic!
104 Sincerely,
105  Kristoffer H. Rose      <krisrose@ens-lyon.fr>
106  Ross Moore              <ross@mpce.mq.edu.au>

D.2 Installation instructions

These files explain how XY-pic is downloaded and installed, i.e., where the various files of the distribution should reside.

D.2.1 TRAILER

1 -*-text-*- $Id: TRAILER,v 3.7 1999/02/16 15:12:50 krisrose Exp $
3 =======================================================================
4  ANNOUNCING the Xy-pic version 3.7 DIAGRAM TYPESETTING PACKAGE
5 =======================================================================
7 This is to announce a release of my diagram typesetting package Xy-pic.
9 With version 3.7 we explicitly grant permission to use the unmodified
10 Xy-pic fonts and specials in distributed documents.
12 -----------------------------------------------------------------------
13  GENERAL

14 -----------------------------------------------------------------------
16 Xy-pic is a package for typesetting a variety of graphs and diagrams
17 with TeX.  Xy-pic works with most formats (including LaTeX, AMS-LaTeX,
18 AMS-TeX, and plain TeX), in particular Xy-pic is provided as a LaTeX2e
19 `supported package' (following the `CTAN LaTeX2e bundle' standard).
21 Further specifics of the package are in the distribution README file.
23 -----------------------------------------------------------------------
24  NEWS
25 -----------------------------------------------------------------------
27 The primary purpose of release 3.7 is the granting of special permission
28 to copy the Xy-pic fonts and graphic specials inside documents, for
29 example in DVI, PostScript, and PDF files.  This has no practical
30 significance except making current (reasonable) practice explicitly
31 legal.
33 Release 3.7 furthermore fixes a few bugs in release 3.6 and adds a few
34 features: a "smart turning path" feature and an extension with macro
35 expansion in kernel expressions and polygon shapes by George C. Necula,
36 and the beginnings of an emulation of LaTeX picture mode proposed by
37 Paul Burchard and Bill Richter.
39 Special thanks to George Necula for the bug fixes and impressive
40 extensions, to Bill Richter for extending Paul Burchard's pb-diagram to
41 use Xy-pic as a backend and for contributing the `picture' feature, to
42 Berthold Horn of Y&Y Inc. for releasing the copyright on their
43 PostScript fonts, and to Pieter Donche and Marcelo Cunha dos Santos for
44 the bug reports.
46 -----------------------------------------------------------------------
47  AVAILABILITY
48 -----------------------------------------------------------------------
50 Xy-pic can be retrieved through the World Wide Web Xy-pic `home page':
52  URL:                  http://www.ens-lyon.fr/~krisrose/Xy-pic.html
54 as well as by anonymous ftp from
56  CTAN:                 macros/generic/diagrams/xypic
58 Check the README file in each location for specifics, in particular
59 check that you have reached a version 3.7 copy (some archives take a
60 while to mirror the latest files)!
62 -----------------------------------------------------------------------
63  HISTORY & CREDITS
64 -----------------------------------------------------------------------
66 The first public release (version 1.40) of Xy-pic was created by
67 Kristoffer H. Rose, DIKU, U of Copenhagen (now ENS-Lyon, France) and
68 distributed via Usenet on December 19, 1991.  This quickly became
69 version 2 of which version 2.6 was the stable for sevarl years.
71 The thorough rewrite that became version 3 is a continued
72 collaboration with Ross Moore, Macquarie U, Sydney, initiated through

73 a visit to Macquarie (Jan-May 1994 supported by the Australian
74 Research Council, Macquarie University, and using donated DEC
75 equipment).  However, full backwards compatibility is maintained
76 (except for the unavoidable but fully documented obscure cases).
78 Xy-pic is Copyright (c) 1991-1998 by Kristoffer H. Rose and 1994-1998
79 by Ross Moore under GNU COPYLEFT (GPL) which means that you can use
80 the package for any purpose but if you provide the macros or any code
81 derived from them to a third party then you are obliged to include the
82 entire Xy-pic package (full details in the file COPYING).  The
83 PostScript fonts are additionally Copyright (c) 1997 Y&Y Inc.  The
84 FONTCOPYING file details the special permissions to distribute fonts
85 without the full requirements of the GPL.
87 -----------------------------------------------------------------------
89  This is the end of the announcement.  Enjoy Xy-pic!
91 -----------------------------------------------------------------------

D.2.2 INSTALL

1 -*-text-*- $Id: INSTALL,v 3.6 1998/03/06 01:28:05 krisrose Exp $
4  ================================================
5  INSTALLING THE Xy-pic DIAGRAM TYPESETTING MACROS
6  ================================================
9 This file explains how you install the files in the `run' distribution of
10 Xy-pic.  See `README' for general information.
12 Contents:
14 -1- Copyleft
15 -2- Overview of files and where they should be installed
16 -3- Information for specific systems
17 -4- Updating from version 2.6 (and earlier)
18 -5- Bugs & comments
21 ---------------------------------------------------------------------------
22 -1- COPYLEFT
23 ---------------------------------------------------------------------------
26 Note that the entire Xy-pic package is distributed with copyleft:
28  Copyright (c) 1991-1998   Kristoffer H. Rose  <krisrose@ens-lyon.fr>
29  Copyright (c) 1994-1998   Ross Moore          <ross@mpce.mq.edu.au>
31  The Xy-pic package is free software; you can redistribute it and/or
32  modify it under the terms of the GNU General Public License as
33  published by the Free Software Foundation; either version 2 of the
34  License, or (at your option) any later version.
36  The Xy-pic package is distributed in the hope that it will be
37  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
38  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
39  General Public License for more details.

41  You should have received a copy of the GNU General Public License
42  along with this package; if not, write to the Free Software
43  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
45 What this means is that if you install Xy-pic then you should (1) make
46 sure that the file `COPYING' is accessible to the users, and (2) be
47 prepared to provide Xy-pic (including sources) to any of your users
48 that request it (you may charge a fee for this if you are so
49 inclined).
51 Note: Some option files may be copyrighted by other people but the
52 conditions remain the same for any file distributed as part of Xy-pic.
55 ---------------------------------------------------------------------------
56 -2- OVERVIEW OF FILES AND WHERE THEY SHOULD BE INSTALLED
57 ---------------------------------------------------------------------------
60 In this section we explain in 11 steps where the different groups of
61 Xy-pic files in the `run' and `doc' distribution should be installed.
62 For each file category we indicate the location recommended by TDS,
63 the TeX Directory Standard (as formed by a TUG working group of that
64 name).
66 IMPORTANT
67 ---------
68 If you have users currently using version 2.6 then make sure you read
69 section 4!  Please also check the next section for any system specific
70 considerations.
72 SPACE REQUIREMENTS
73 ------------------
74 Installing the Xy-pic package requires almost 1MB with the macros
75 macros taking up most of the space.  Installing everything, including
76 sources, documentation in both DVI, DVIPS, and PS, form, as well as
77 bitmap fonts for several printers and in PostScript Type1 form,
78 requires more than 12MB.
81 Step 1. Eliminating Obsolete Files
82 ----------------------------------
83 The new PostScript Type1 fonts contributed by Y&Y Inc. require that
84 you REMOVE ALL COPIES of the following files BEFORE installing:
86 Old font map files should be removed:
88  xy.map
89  xypic.map
91 TDS directory: texmf/dvips/xypic
93 Also be aware that some installations, for example the TeX Live 2
94 CD-ROM, insert the contents of map files in `psfonts.map' (with TDS
95 directory texmf/dvips/base); then you must EDIT it to remove all lines
96 that start with `xy'.
98 Remove old PostScript Type1 font files:
100 xyatip10.pfa

101 xybsql10.pfa
102 xybtip10.pfa
103 xycirc10.pfa
104 xycmat10.pfa
105 xycmbt10.pfa
106 xydash10.pfa
107 xyeuat10.pfa
108 xyeubt10.pfa
110 xyatip10.pfb
111 xybsql10.pfb
112 xybtip10.pfb
113 xycirc10.pfb
114 xycmat10.pfb
115 xycmbt10.pfb
116 xydash10.pfb
117 xyeuat10.pfb
118 xyeubt10.pfb
120 TDS directory: texmf/fonts/type1/public/xypic
122 Remove old `xy.sty' and `xypic.sty' files that you might have stored
123 earlier in the TDS directory `texmf/tex/latex/misc'.
126 [FILES IN xy*run.tar.gz:]
129 Step 2. Availability & License
130 ------------------------------
131 These eight files contain general information and should be installed
132 in a publicly readable place:
134 README        generic information on Xy-pic
135 CATALOG       version information and summary
136 TRAILER       announcement and availability
137 INSTALL       how to install (this file)
138 MANIFEST      list of all files
139 VERSIONS      the RCS version ids of all source files
140 COPYING       GNU General Public License
142 TDS directory: texmf/doc/generic/xypic
145 Step 3. Macros
146 --------------
147 Files `texinputs/*' are TeX and LaTeX macro files that must be
148 installed in a place which TeX and LaTeX will search (e.g., with un*x
149 TeX, a directory users include in the TEXINPUTS environment variable).
151 The files `texinputs/*.ini'
153 TDS directory: texmf/tex/generic/xypic
156 Step 4. TeX Font Metric
157 -----------------------
158 Files `texfonts/*.tfm' should be installed in a directory that TeX
159 will search for fonts (e.g., with un*x TeX, a directory users include

160 in the TEXFONTS environment variable).
162 TDS directory: texmf/fonts/tfm/public/xypic
165 Step 5. METAFONT Sources
166 ------------------------
167 Files `mfinputs/*.mf' should be installed in some directory where the
168 METAFONT program will search for them (e.g., with un*x TeX, a
169 directory included in the MFINPUTS environment variable).
171 NOTE: The METAFONT source files are only useful on installations where
172 the printer driver and previewer can utilise them to generate the
173 required bitmap fonts `on-line'.  If this is possible on your
174 installation then please use it: it saves substantial amounts of space
175 and means that you will automatically use fonts optimised for each
176 printer (provided evrything is correctly set up, of course).
178 TDS directory: texmf/fonts/source/public/xypic
181 Step 6. Bitmap Fonts [Optional]
182 -------------------------------
183 Files matching the patterns `pkfonts/cx<N>/*.<N>pk' and
184 `pkfonts/ljfour<N>/*.<N>pk', where <N> is some number, contain bitmap
185 font files and should be installed where DVI previewers and printer
186 drivers will find them (e.g., with un*x, the `xdvi' program should see
187 them through the XDVIFONTS environment variable).  (`cx' is a 300 dpi
188 (dots per inch) mode and `ljfour' a 600 dpi mode.)
190 NOTE: This step is optional because the bitmaps are only needed (and
191 only recommended) for installations that can't use the METAFONT
192 sources directly but do have a 300 or 600 dpi laserprinter driver that
193 accepts PK bitmap font files.
195 TDS directory: texmf/fonts/pk/cx/public/xypic/dpi<N>
196  and: texmf/fonts/pk/ljfour/public/xypic<N>
199 Step 7. PostScript Type1 Fonts
200 ------------------------------
201 Files `type1/*.pfb' contain versions of the Xy-pic fonts in special
202 PostScript form that may be useful on some installations.  They should
203 be installed where the applications using them look for such fonts (if
204 used with DVIPS then the `ps/xypic.map' file from the next group
205 should also be installed).
207 NOTE: Some installations, notably teTeX 0.4, will PREFER using these
208 fonts over the METAFONT-generated equivalents (IMHO this is a bug in
209 the MakeTeXPK script).  On those systems we recommend that you ALSO
210 install the PK fonts to circumvent the problem.
212 IMPORTANT: Make sure that you do not have any old Xy-pic PostScript
213 `xy*.pfa' fonts floating around in your system - search for and remove
214 all files named `xy*.pfa' when you have installed the new fonts.  One
215 common way old (and wrong) fonts is manifest is when some arrowheads
216 appear skewed or too thin.

218 TDS directory: texmf/fonts/type1/public/xypic
221 Step 8. Adobe Font Metric Files
222 -------------------------------
223 Files `afm/*.afm' are special files for the Adobe Type Manager and
224 some other software.  Install them if you need them.
226 TDS directory (usually): texmf/fonts/afm/public/xypic
229 Step 9. PostScript Font Metric Files
230 ------------------------------------
231 Files `pfm/*.pfm' are special files for the Windows version of the
232 Adobe Type Manager and some other software.  Install them if you need
233 them.
235 TDS directory (usually): texmf/fonts/pfm/public/xypic
238 Step 10. PostScript Header Files
239 --------------------------------
240 Files `ps/*' contain PostScript header files.  If you plan to use the
241 PostScript extension option then you should copy these files to a
242 place where your PostScript DVI driver will find them.
244 NOTE: For older versions of DVIPS (at least for 5.58f) you should
245 replace the occurrences of `<<' with `<' in `xypic.map'.
247 TDS directory (usually): texmf/dvips/xypic
250 [FILES IN xy*doc.tar.gz:]
253 Step 11. Manuals
254 ----------------
255 The typeset User's Guide is distributed as a DVI file which you should
256 be able to print (or preview) once you have installed the fonts (as
257 source or bitmaps as applicable for your system):
259 doc/xyguide.dvi       User's Guide, typeset using the kernel Xy-pic fonts
260 doc/xyguide.dvips     --- using DVIPS specific `specials'
261 doc/xyguide.ps        --- in PostScript (with 600dpi bitmap fonts)
263 Similarly, the reference manual for the kernel and the distributed
264 options is included in the same format:
266 doc/xyrefer.dvi       Reference Manual, using Xy-pic fonts
267 doc/xyrefer.dvips     --- using DVIPS specific `specials'
268 doc/xyrefer.ps        --- in PostScript (with 600dpi bitmap fonts)
270 Notice that only the .dvi documents are portable among all TeX
271 installations.
273 TDS directory: texmf/doc/generic/xypic
276 That's all.  If you want to install the Xy-pic sources (to experiment
277 with development, for example), you need to get the separate
278 distribution `xy*src.tar.gz'.
281 ---------------------------------------------------------------------------

282 -3- INFORMATION FOR SPECIFIC SYSTEMS
283 ---------------------------------------------------------------------------
286 UN*X
287 ----
288 The above installation procedure (using the TDS recommended places) is
289 encoded in the script `support/install-tds': the command
291 ./support/install-tds <texmf>
293 where <texmf> is the full path name of the `texmf' directory (the root
294 of the TDS tree), will install all the Xy-pic runtime files (or more
295 precisely: it will perform steps 2-5 and 7-10 above).
297 NOTE: You must MANUALLY remove obsolete files (do step 1 above)!
299 If you get the source distribution as described in `TRAILER' and
300 change the configuration section of the provided `src/Makefile' to
301 reflect your local file system conventions as described in
302 `src/MAKE', then the command
304 make TEXMF=<texmf> install
306 will also do this (but with the generated files, of course).
309 VMS
310 ---
311 (Mon, 20 Mar 1995; thanks to Austin Benson <austin@shapel.ug.eds.com>
312 and Ralf Gaertner <gaertner@cthulhu.rhein-main.de>):
314 (1) VMS tfm and pk files are in a funny file format, which means they
315  EITHER should be generated from the mf source on a VMS machine, OR
316  be converted by a conversion program such as BILF (part of the
317  DECUS TeX distribution and the ZOO distribution although the
318  latter is reported to only work on VAXen).
320  FIX: Install .mf sources and pregenerate .tfm and .pk files
321  manually OR convert with BILF or a similar program.
323 (2) At least some (OLD) versions of TeX for VMS had a `buglet' to do
324  with searching for input files: if you go \input <filename> on VMS
325  then TeX prepends the filename with a chained logical
326  "tex_inputs:" - equivalent to a Unix path. Unfortunately \openin
327  does _not_do this - although on Unix systems \openin will search
328  the TEXINPUTS path just as \input does.
330  FIX: Change the following line in xy.tex
332 \xydef@\xyinputorelse@@#1#2{\openin\xyread@=#1

334  TO

336 \xydef@\xyinputorelse@@#1#2{\openin\xyread@=tex_inputs:#1
339 PC WITH PCTEX
340 -------------
341 On PCTeX fonts should be stored in files `C:\PIXEL\DPI<dpi>\<font>.pk'
342 where <dpi> and <font> are replaced by appropriate values, e.g., `600'
343 and `xyatip' (thanks to Alain Amiouni <alain_amiouni@msn.com>).

346 MAC WITH Textures or OzTeX
347 --------------------------
348 See the special files `INSTALL.Textures' and `INSTALL.OzTeX'.
351 ---------------------------------------------------------------------------
352 -4- UPDATING FROM VERSION 2.6 (AND EARLIER)
353 ---------------------------------------------------------------------------
356 IMPORTANT: If you have installed release 3.* or 2.7-2.12 then you can
357 skip this section. If you have not, and use version 2.6, then READ IT!
359 Xy-pic release 2.7 was almost a complete rewrite of Xy-pic; later
360 releases are updates to this version.  If you are using version 2.6 (or
361 some earlier version) then note the following:
363 * All the fonts have been redone AND renamed (except two that have not
364 changed).  Thus installing version 3 will not break any DVI files
365 you already have that were typeset using the old fonts.
367 NOTE: In fact the distribution still contains the old fonts but only
368 as METAFONT sources, TFM font metrics, and PK bitmaps.
370 * The distribution contains new versions of the files `xypic.tex' and
371 `xypic.sty' that load Xy-pic in a special compatibility mode.  Thus
372 retypesetting your documents will create DVI files using the new
373 fonts.  If you wish to keep the old `xypic.tex' and `xypic.sty' then
374 you should rename them before installation; we suggest naming them
375 `xypic-2.tex' and `xypic-2.sty' and REMEMBER to change the line
376 `\input xypic' in `xypic-2.sty' to `\input xypic-2' !
378 * There are a few points where the backwards compatibility is not
379 perfect -- these are noted in the documentation.
382 ---------------------------------------------------------------------------
383 -5- BUGS & COMMENTS
384 ---------------------------------------------------------------------------
387 We will appreciate reports on any problems you may encounter and
388 opinions you have on how the usefulness of Xy-pic can be improved.
389 Please report using either
391 Electronic mail (Internet): krisrose@ens-lyon.fr        [preferred]
393 Paper mail:   Kristoffer H. Rose
394  Laboratoire de l'Informatique du Parallélisme
395  Ecole Normale Supérieure de Lyon
396  46, Allée d'Italie
397  F-69364 Lyon cedex 07
398  FRANCE
400 Fax:          +33 4 7272 8080
402 W3            <URL: http://www.ens-lyon.fr/~krisrose/Xy-pic.html>
404 ---------------------------------------------------------------------------
406 This is the end of INSTALL.  We hope you'll enjoy Xy-pic!

594 APPENDIX D. DISTRIBUTION SUPPORT FILES

408  -- Ross Moore and Kristoffer Rose
410 ---------------------------------------------------------------------------
412 Kristoffer Høgsbro Rose, Ph.D., prof.associé  <Kristoffer.Rose@ENS-Lyon.FR>
413 Laboratoire de l'Informatique du Parallélisme  équipe PLUME, bureau LR5-026
414 Ecole Normale Supérieure de Lyon; 46, Allée d'Italie; F-69364 Lyon 07 cedex
415 phone: +33(0)4 7272 8642; fax:...8080    <http://www.ens-lyon.fr/~krisrose>
417 ---------------------------------------------------------------------------

D.3 Generation

These files are relevant when XY-pic is generated from sources on a un*x system.

D.3.1 MAKE

1 -*-text-*- $Id: MAKE,v 3.5 1997/05/28 22:40:26 krisrose Exp $
3  ================================================
4  MAKE: Xy-pic diagram typesetting package SOURCES
5  ================================================
7 Welcome to the source distribution of the Xy-pic macros for typesetting
8 diagrams!  Below you will find the following sections:
10  -1- License information
11  -2- Making the package and manual from sources
12  -3- Bugs & comments
13  -4- Distribution log
15 Please see the file `README' for a summary of features `TRAILER' for how
16 you can obtain the newest Xy-pic, and the various `INSTALL' files if you
17 have already retrieved pregenerated macros and fonts.
20 ----------------------------------------------------------------------
21  -1- LICENSE INFORMATION
22 ----------------------------------------------------------------------
24 The Xy-pic package is licensed under `GNU CopyLeft':
26  Xy-pic: Typesetting graphs and diagrams with TeX.
27  Copyright (c) 1991-1997  Kristoffer H. Rose  <krisrose@brics.dk>
29  The Xy-pic macro package is free software; you can redistribute it
30  and/or modify it under the terms of the GNU General Public License as
31  published by the Free Software Foundation; either version 2 of the
32  License, or (at your option) any later version.
34  The Xy-pic macro package is distributed in the hope that it will be
35  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
36  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
37  General Public License for more details.
39  You should have received a copy of the GNU General Public License
40  along with this package; if not, write to the Free Software
41  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

43 (Some options may be copyright by other people but the conditions remain
44 the same).
46 The full text of the GNU General Public License is supplied with Xy-pic
47 in the file `COPYING'.
50 ----------------------------------------------------------------------
51  -2- MAKING THE PACKAGE AND MANUAL FROM SOURCES
52 ----------------------------------------------------------------------
54 This section describes how to make the Xy-pic package from sources on
55 a un*x system.  Making Xy-pic requires use (and some knowledge) of
56 several standard un*x utilities; furthermore the typesetting og the
57 reference manual needs a **LARGE** TeX (see below), and full
58 installation requires both the plain TeX and LaTeX2e formats as well
59 as METAFONT (with the plain and cm bases.
61 NOTE FOR VMS USERS: The procedure for making the package from sources
62 described below does not work on VMS, of course.  You can, however,
63 run the enclosed `support/doc2tex.com' procedure file contributed by
64 R.Gaertner to create the .tex files from the .doc files.
66 NOTE FOR OTHER NON-UN*X USERS: If you do not have a un*x system then
67 you are best adviced to get the `ready to run' package and install it
68 as described in `INSTALL'.
70 UN*X GENERATION AND INSTALLATION STEPS:
72 1. First make sure that you have a separate directory `src' which
73  contains all the files of the distribution (including this file).
75  The file `MANIFEST' contains a list of the files.
77 2. Next you should edit the `Configuration section' of `Makefile' to fit
78  the configuration of your system by following the directions given
79  there.
81  When you have configured everything then just do
83  make
85  which should generate all the files needed to use the package.
87 3. You can test the newly generated system by typesetting the User's
88  Guide which you probably want for reference anyway: do
90  make guide
92  which should produce a file `xyguide.dvi' by running LaTeX several
93  times and BibTeX once.
95 4. If possible it is a good idea to try to preview the User's Guide (in
96  whatever way you do on your system) at this point.  This is slightly
97  difficult because it uses the Xy-pic fonts which you haven't
98  installed yet, so the previewer should be instructed to look in the
99  current directory before looking in the system font directories.  The
100  following show how to do this for the most common previewer (on un*x
101  systems with X windows) and might work for you:
103  env XDVIFONTS=.: xdvi xyguide.dvi

105 5. You can then install the package by ensuring that the install
106  directories in `Makefile' are setup correctly and do
108  make install
110  This will replace exisiting `xypic.tex' and `xypic.sty' files with
111  the new (compatibility mode) ones; the old ones will remain available
112  with an `.orig' suffix (if you want to keep the old version then read
113  section 2 of `INSTALL').
115 6. You can typeset the entire manual with
117  make manual
119  to create both files `xyguide.dvi' and `xyrefer.dvi'; they can be
120  installed in the TEXDOC directory with the command
122  make install.manual
124  NOTE: this requires a LARGE TeX system: the last typesetting (running
125  LaTeX on `xyrefer.man' without any driver) uses more than 600000 TeX
126  words, as noted above.  Using Karl Berry's Web2C 7.0 this is
127  achieved by including the lines
129 extra_mem_top = 400000 % extra high memory for chars, tokens, etc.
130 extra_mem_bot = 400000 % extra low memory for boxes, glue, breakpoints, etc.
132  in the texmf.cnf file.
134 7. You can build format files by the commands
136  make xytex.fmt
137  make xylatex.fmt
139  (the latter requires the new standard LaTeX release aka LaTeX2e).
140  These assume that the files `plain.tex' and `latex.ltx' are available
141  in the TeX search path; also you have to install the format files in
142  the appropriate place yourself.
144 That is all.
147 ----------------------------------------------------------------------
148 -3- BUGS & COMMENTS
149 ----------------------------------------------------------------------
151 I will appreciate reports on any problems you may encounter and
152 opinions you have on how the usefulness of Xy-pic can be improved.
153 Please report using either
155 Electronic mail (Internet): krisrose@brics.dk [preferred]
157 Paper mail:   Kristoffer H. Rose
158  BRICS/Computer Science
159  University of Aarhus
160  Ny Munkegade, building 540
161  DK-8000 Aarhus C
162  DENMARK
164 Fax:          +45 89423255  att. K.Rose / Karen Møller
166 You can always get the latest news of Xy-pic from computers connected

167 to the Internet by opening the Xy-pic World Wide Web page:
169 W3            <URL: http://www.brics.dk/~krisrose/Xy-pic.html>
172 ----------------------------------------------------------------------
173 -4- DISTRIBUTION LOG
174 ----------------------------------------------------------------------
176 The following versions have been distributed publicly:
178 $Log: MAKE,v $
179 Revision 3.5  1997/05/28 22:40:26  krisrose
180 Fixed missing breaks bug.
182 Revision 3.3  1996/12/19 03:31:56  krisrose
183 Maintenance release
185 Revision 3.1  1995/09/05  20:31:32  kris
186 Releasing!
188 Revision 3.0  1995/07/07  20:14:21  kris
189 Major release w/new User's Guide!
191 Renamed to MAKE for version 3 source description.
193 Revision 2.12  1994/10/25  11:34:25  kris
194 Interim release just before v3 [works with AMS-LaTeX 1.2]...
196 Revision 2.11  1994/07/05  10:37:32  kris
197 Third 3beta release [bug fixes].
198 Experimental graph feature included (for ECCT-94 presentation).
200 Revision 2.10  1994/06/15  12:59:44  kris
201 Second 3beta release [bug fixes].
203 Revision 2.8  1994/04/11  09:31:09  kris
204 Second (bug fix) 3alpha release [corrected].
206 Revision 2.7  1994/03/08  02:06:01  kris
207 Release 3alpha.
209 MAJOR REWRITE of distribution to prepare for Xy-pic 3 functionality.
210 Curve extension code contributed by Ross Moore <ross@mpce.mq.edu.au>;
211 support funding from MURG, ARC, and equipment from DEC.
213 Revision 2.6  1992/06/24  01:23:34  kris
214 Added `hook' tips using new font xyqc10.
215 Added new POSitions: * and !.
216 Added triple lines \Ssolid, \Ddashed, \Ddotted, and companion \Ttip.
217 Reorganised manual.
219 Revision 2.5  1992/02/24  03:30:54  kris
220 Fixed bugs in \Direction calculation logic...
221 Added (FACTOR) to \rotate to allow arbitrary rotation.
222 ` intermediate points now accept an optional /RADIUS argument.
223 Added \Tip with wide tip.
225 Revision 2.4  1992/01/22  02:15:10  kris
226 Fixed bugs [with thanks]:
227 \\ works with AMS-LaTeX: don't use \Let@ [Werner Struckmann/Darrel Hankerson]

228 No spurious arrow heads with LaTeX: \pit now undefined [Werner Struckmann]
229 \Solid works: sets \Density [Dave Bowen]
230 Short diagonal lines work...major rewrite of \connectv@ [Eric Domenjoud]
232 Revision 2.3  1992/01/10  21:38:27  kris
233 Several bugs fixed [with thanks]:
234 The \ddtoX and \uutoX arrows were interchanged [Nico Verwer].
235 Some diagonal lines were wrong [Eric Domenjoud].
236 AMS-LaTeX users had name clash problems [Werner Struckmann].
237 The installation instructions in the Makefile were buggy [Leen Torenvliet].
239 Revision 2.2  1992/01/09 04:05:40  kris
240 Patched to fix problem with \text and support AMS-LaTeX.
242 Revision 2.1  1992/01/02 14:54:07  kris
243 Release version.
245 Revision 1.40  1991/12/17 04:53:23 kris
246 Version distributed as `final draft' on Usenet.
248 ----------------------------------------------------------------------
250 This is the end of the source overview.  I hope you will enjoy Xy-pic!
252 ----------------------------------------------------------------------
254 Kristoffer Høgsbro ROSE                           <krisrose@brics.dk>
255 BRICS                           <URL: http://www.brics.dk/~krisrose/>
256 Department of Computer Science B3.26, +45 89423193 (fax +45 89423255)
257 University of Aarhus, Ny Munkegade, build. 540, 8000 Århus C, DENMARK
259 ----------------------------------------------------------------------

D.3.2 Makefile

1 # $Id: Makefile,v 3.7 1999/02/16 15:12:50 krisrose Exp krisrose $
2 #
3 # Un*x Makefile for Xy-pic macros, fonts, documentation, and distribution.
4 # Copyright (c) 1991-1997  Kristoffer H. Rose  <krisrose@ens-lyon.fr>
5 #
6 # This file is part of the Xy-pic macro package.
7 # Copyright (c) 1991-1997  Kristoffer H. Rose  <krisrose@ens-lyon.fr>
8 # See the README and INSTALL files for further information.
9 #
10 # The Xy-pic package is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by the
12 # Free Software Foundation; either version 2 of the License, or (at your
13 # option) any later version.

14 #

15 # The Xy-pic package is distributed in the hope that it will be useful, but
16 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 # for more details.

19 #

20 # You should have received a copy of the GNU General Public License along
21 # with this package; if not, write to the Free Software Foundation, Inc.,

22 # 675 Mass Ave, Cambridge, MA 02139, USA.
24 VERSION = 3.7
25 SHORTVERSION = 37
27 # CONTENTS:

28 #

29 #   Configuration section:
30 #       Directories.
31 #       Fonts.
32 #       Programs.

33 #

34 #   Generic targets.
35 #   Macros.
36 #   PostScript headers.
37 #   Fonts.
38 #   Formats.
39 #   Manual: User's guide and reference manual.
40 #   Reference manual.
41 #   TeXnical documentation.
42 #   Distribution tree.
43 #   Ftp'able distribution.
44 #   WWW publicity.
45 #   Announcements.
46 #   Tags.
47 #   RCS stuff.
48 #   Development targets.

49 #

50 #   Log.
53 #### CONFIGURATION SECTION ##################################################
55 # Please configure as instructed below for each of the DIRECTORIES, FONTS,
56 # and PROGRAMS parts by editing the definitions to fit your system.
58 #### DIRECTORIES.

59 #

60 # The following variables define the directories where the various parts of
61 # Xy-pic should be installed.

62 #

63 # You should *EITHER* set TDSROOT to the root of a TDS-compliant directory
64 # tree, usually named .../texmf (if you have a TDS [TeX Directory Structure]
65 # compliant system then that is in fact all you need to do):

66 #

67 USR = /usr/local
68 TDSROOT = $(USR)/share/texmf

69 #

70 # *OR* you should set each of the following variables right for you system
71 # (do this if your setup does not match TDS exactly):

72 #

73 TEXINPUTDIR = $(TDSROOT)/tex/generic/xypic
74 TEXFONTDIR = $(TDSROOT)/fonts/tfm/public/xypic

75 TEXDOCDIR = $(TDSROOT)/doc/generic/xypic
76 MFINPUTDIR = $(TDSROOT)/fonts/source/public/xypic
77 TYPE1DIR = $(TDSROOT)/fonts/type1/public/xypic
78 PFMDIR = $(TDSROOT)/fonts/pfm/public/xypic
79 AFMDIR = $(TDSROOT)/fonts/afm/public/xypic
80 PDFDIR = $(TDSROOT)/pdftex/xypic
81 PSHEADERDIR = $(TDSROOT)/dvips/xypic

82 #

83 # FONTDIR is the directory where bitmap fonts are stored and is special
84 # (If you do not plan to install bitmap fonts because they are automatically
85 # generated and remember to set the MAGS variable below to `.' then you may
86 # ignore this step.)

87 #

88 # Since the location of individual fonts sometimes depend on properties of
89 # the font, you can insert

90 #

91 #       $${dpi}         for the font resolution in `Dots Per Inch' (NOT the
92 #                       device resolution---that should be inserted directly)

93 #

94 #       $${mode}        for the METAFONT `mode' used to generate the font

95 #

96 # ---what these get set to depends on the next section.

97 #

98 # For example, if you set FONTDIR=/usr/lib/tex/pk$${dpi} and decide in the
99 # next section to generate PK fonts at 300 dpi using a generic mode
100 # (localfont) then you get files named /usr/lib/tex/pk300/xy*.300pk.

101 #

102 # If your installation still uses the (inefficient) principle of having all
103 # PK files in the same directory as the TFM files then you should just set
104 # FONTDIR=$(TEXFONTDIR).

105 #

106 FONTDIR = $(TDSROOT)/fonts/pk/$${mode}/public/xypic/dpi$${dpi}
108 #### FONTS.

109 #

110 # The METAFONT program needs to know the `mode' of your printer in order to
111 # be able to generate correct fonts for it.  On most installations the mode
112 # `localfont' is made synonymous with the mode required for the default
113 # printer; in that case you can just pick the `MODES = localfont' line.  If
114 # this is not the case -- or you need fonts for several output devices---then
115 # you will have to consult the local METAFONT guide/guru to inquire what
116 # modes are used at your site.  A good place to look for the modes used is in
117 # the MakeTeXPK script found on some sites.

118 #

119 # Set MODES to the list of printers you wish to use:

120 #

121 MODES = localfont
122 #MODES = cx ljfour

123 #

124 # You should also decide which TeX \magsteps you wish the font to be

125 # generated at.

126 #

127 # The default is . (dot) which prevents installation of any bitmaps because
128 # most modern installations generate them automatically.

129 #

130 MAGS = .
131 #MAGS = 0
132 #MAGS = 0 0.5 1 2
134 #### PROGRAMS.

135 #

136 # You don't have to edit the following lines unless you have a non-standard
137 # un*x system or un*x TeX installation...

138 #

139 SHELL = /bin/sh

140 #

141 TEX = TEXFONTS=.:$(TEXFONTDIR):$$TEXFONTS tex
142 LATEX = TEXFONTS=.:$(TEXFONTDIR):$$TEXFONTS latex
143 PDFLATEX = TEXFONTS=.:$(TEXFONTDIR):$$TEXFONTS pdflatex
144 BIBTEX = BIBINPUTS=. bibtex
145 MAKEINDEX = makeindex
146 INITEX = TEXFONTS=.:$(TEXFONTDIR):$$TEXFONTS initex

147 #

148 # Set MF to a command that will run plain METAFONT on your system.

149 #

150 MF = MFINPUTS=.:$(MFINPUTDIR):$$MFINPUTS mf

151 #

152 # Set GFTOPK to the command "false" and PK to "gf" if you use GF rather than PK
153 # bitmap font files.  There is no support for PXL-files [are they still used?].
154 # (Note: the default setting of MAGS above doesn't use bitmaps at all.)

155 #

156 GFTOPK = gftopk
157 PK=pk

158 #

159 #GFTOPK = false
160 #PK=gf

161 #

162 RM = rm -fr
163 CP = cp -f
164 MV = mv -f

165 #

166 # Set the INSTALLs to cp -f if your system does not have the install command.

167 #

168 INSTALL = install -c -m 444
169 INSTALLW = install -c -m 644
170 INSTALLX = install -c -m 555
171 #INSTALL = cp -f
172 #INSTALLW = cp -f
173 #INSTALLX = cp -f

175 # Set MKDIR to a mkdir command that creates intermediate directories.

176 #

177 MKDIR = mkdir -p -m 755

178 #

179 # DOC2TEX <file>: output efficient .tex file from inefficient .doc <file> with
180 # inlined documentation [my favourite hack :-].  Removes all DOCMODE lines,
181 # leaving only things before the first and in DOCMODE(...DOCMODE) brackets;
182 # also removes all blank lines and comment lines.

183 #

184 # If it breaks your sed you can just set DOC2TEX to cat although that will
185 # make the installed macro files three times larger and the reading of them
186 # somewhat slower...so in that case you are probably better of getting the
187 # `run' distribution where this has already been done for you!

188 #

189 DOC2TEX = sed \
190  -e '/^.DOCMODE(/b Yes' \
191  -e '/^.DOCMODE/b No' \
192  -e 'x' \
193  -e '/%%DONTCOPY%%/b Ignore' \
194  -e 'x' \
195  -e 's/[         ][      ]*/ /g' \
196  -e 's/{%.*$$/{%/' -e 's/}%.*$$/}%/' -e 's/ %.*$$//'  \
197  -e '/^*%$$/d' -e '/^*$$/d' -e '/^*%[^%]/d' \
198  -e 's/^%% \$$Id/%% $@ from $$Id/' \
199  -e 's/REPLACEWITHVERSION/$(VERSION)/' \
200  -e 's/REPLACEWITHSHORTVERSION/$(SHORTVERSION)/' \
201  -e 'b End' \
202  -e ': No' -e 's/.*/%%DONTCOPY%%/' -e 'x' -e 'd' \
203  -e ': Yes' -e 's/.*//' -e 'x' -e 'd' \
204  -e ': Ignore' -e 'x' -e 'd' \
205  -e ': End'

206 #

207 # MF2TFM script: make .tfm file and all requested bitmap files from .mf
208 # file by executing METAFONT with $${mode} and $${dpi} as described above.

209 #

210 # NOTE: for use as implicit make rule; do not modify unless you are sure you
211 # need to!

212 #

213 MF2TFM = set -x; for mode in $(MODES); do \
214  if [ "$(MAGS)" = "." ]; then \
215  $(MF) "\\mode=$$mode; input $<";\
216  $(RM) $*.*gf;\
217  else \
218  for mag in $(MAGS); do \
219  $(MF) "\\mode=$$mode; mag=magstep($$mag); input $<"; done;\
220  for f in $*.*gf; do if test -f "$$f"; then \
221  if $(GFTOPK) ./$$f; then $(RM) $$f; fi; else :; fi; done;\
222  fi; done
224 #### END OF CONFIGURATION SECTION ###########################################

227 # GENERIC TARGETS.

228 #

229 all:            macros fonts obsoletefonts
230 .PHONY:         all install clean realclean sterile world

231 #

232 install:        all install.macros install.trailer \
233  install.fonts install.obsoletefonts \
234  install.ps install.psfonts

235 #

236 clean:
237  $(RM) *.aux *.toc *.lof *.blg *.log *.idx *.ilg *.fmt \
238  *.ps *.ppm *.nops *.tmp *.ans *.xyc *.xyd \
239  ./#* *~ core *.BAK *JNL xytest.*gf out

240 #

241 realclean:      clean
242  $(RM) MANIFEST VERSIONS CATALOG
243  $(RM) xydoc.back; touch xydoc.back
244  $(RM) *.bbl *.glo *.ind \
245  *.tfm *.*gf *.*pk *.tex *.dvips *.dvi *.pdf *.last *.pro \
246  *.gif *.epsf *.size *.pbm *.ppm \
247  *.afm *.pfm *.pfb *.asc
248  $(RM) xyguide-html index*
249  $(RM) pnmrawtopcropwhite

250 #

251 sterile:        realclean rcsclean
252  $(RM) xydoc.back make.* TAGS
253  $(MAKE) Makefile xydoc.sty xydoc.bib

254 #

255 world:          realclean rcsclean
256  time $(MAKE) all ftp ftpdoc www 2>&1 |tee make.world
259 # MACROS.

260 #

261 TRAILERSOURCES =        TRAILER COPYING CATALOG.doc \
262  MAKE README Makefile $(INSTALLSTAR)
264 INSTALLSTAR =           INSTALL INSTALL.OzTeX INSTALL.Textures
266 KERNELSOURCES =         xy.doc xyidioms.doc xyrecat.doc
268 OPTIONSOURCES =         \
269  xyframe.doc xycmtip.doc xytips.doc xycurve.doc \
270  xyline.doc xyrotate.doc xycolor.doc xycrayon.doc xytile.doc \
271  xyimport.doc xytpic.doc xytp-f.doc \
272  xyps.doc xyps-ps.doc xyps-pro.doc xyps-col.doc xyps-c.doc xyps-f.doc \
273  xyps-l.doc xyps-r.doc xyps-s.doc xyps-t.doc \
274  xypsdict.doc xypspatt.doc xydocps.doc \
275  xydummy.doc xyall.doc xymatrix.doc xyarrow.doc xygraph.doc \
276  xy2cell.doc xypoly.doc xyarc.doc xyknot.doc xyweb.doc \
277  xydvips.doc xytextures.doc xy16textures.doc xyoztex.doc xy17oztex.doc \
278  xycmactex.doc xydvitops.doc xyemtex.doc xydvidrv.doc xyxdvi.doc \
279  xymovie.doc xyv2.doc xypic.doc \

280  xynecula.doc xysmart.doc
282 FORMATSOURCES =         xytex.ini xylatex.ini
284 LATEXSTYLES =           xy.sty xypic.sty movie.cls
285 OPTIONDATA =            xymacpat.xyp
287 MACROSOURCES =          $(TRAILERSOURCES) $(KERNELSOURCES) $(LATEXSTYLES) \
288  $(OPTIONSOURCES) $(OPTIONDATA) $(FORMATSOURCES)
290 TRAILERRUN =            TRAILER COPYING CATALOG README \
291  $(INSTALLSTAR) VERSIONS
293 KERNELRUN =             xy.tex xyidioms.tex xyrecat.tex
295 OPTIONRUN =             \
296  xyframe.tex xycmtip.tex xytips.tex xycurve.tex \
297  xyline.tex xyrotate.tex xycolor.tex xycrayon.tex xytile.tex \
298  xyimport.tex xytpic.tex xytp-f.tex \
299  xyps.tex xyps-ps.tex xyps-pro.tex xyps-col.tex xyps-c.tex xyps-f.tex \
300  xyps-l.tex xyps-r.tex xyps-s.tex xyps-t.tex \
301  xypsdict.tex xypspatt.tex $(OPTIONDATA) \
302  xydummy.tex xyall.tex xymatrix.tex xyarrow.tex xygraph.tex \
303  xy2cell.tex xypoly.tex xyarc.tex xyknot.tex xyweb.tex \
304  xydvips.tex xytextures.tex xy16textures.tex xyoztex.tex xy17oztex.tex \
305  xycmactex.tex xydvitops.tex xyemtex.tex xydvidrv.tex xyxdvi.tex \
306  xymovie.tex xyv2.tex xypic.tex \
307  xynecula.tex xysmart.tex
309 MACRORUN =              $(KERNELRUN) $(OPTIONRUN) $(FORMATSOURCES) \
310  $(LATEXSTYLES)
311 PSRUN =                 xy$(SHORTVERSION)dict.pro
313 SUPPORT =               install-tds doc2tex.com \
314  dvitogif89a pnmrawtopcropwhite.c
316 # Macros have .tex suffix and are generated from the .doc files.

317 #

318 .SUFFIXES:      .tex .doc
319 .doc.tex:;      $(DOC2TEX) $< > $@

320 #

321 .PHONY:         macros install.macros

322 #

323 macros:         $(MACRORUN)
324 install.macros: $(MACRORUN)
325  -test -d $(TEXINPUTDIR) || $(MKDIR) $(TEXINPUTDIR)
326  for f in $(MACRORUN); do $(INSTALL) $$f $(TEXINPUTDIR)/$$f; done

327 #

328 # Kernel dependencies:

329 #

330 xy.tex:                         xy.doc
331 xyidioms.tex:                   xyidioms.doc
332 xyrecat.tex:                    xyrecat.doc

333 #

334 # Extension option dependencies:

335 #

336 xyframe.tex:                    xyframe.doc
337 xytips.tex:                     xytips.doc
338 xycmtip.tex:                    xycmtip.doc
339 xycurve.tex:                    xycurve.doc
340 xyline.tex:                     xyline.doc
341 xyrotate.tex:                   xyrotate.doc
342 xycolor.tex:                    xycolor.doc
343 xycrayon.tex:                   xycrayon.doc
344 xyimport.tex:                   xyimport.doc
345 xytile.tex:                     xytile.doc

346 #

347 xytpic.tex:                     xytpic.doc
348 xytp-f.tex:                     xytp-f.doc

349 #

350 xyemtex.tex:                    xyemtex.doc

351 #

352 xyps.tex:                       xyps.doc
353 xyps-ps.tex:                    xyps-ps.doc
354 xyps-pro.tex:                   xyps-pro.doc
355 xyps-col.tex:                   xyps-col.doc
356 xyps-c.tex:                     xyps-c.doc
357 xyps-f.tex:                     xyps-f.doc
358 xyps-l.tex:                     xyps-l.doc
359 xyps-r.tex:                     xyps-r.doc
360 xyps-s.tex:                     xyps-s.doc
361 xyps-t.tex:                     xyps-t.doc
362 xypsdict.tex:                   xypsdict.doc
363 xypspatt.tex:                   xypspatt.doc

364 #

365 # Feature option dependencies:

366 #

367 xydummy.tex:                    xydummy.doc
368 xyall.tex:                      xyall.doc

369 #

370 xymatrix.tex:                   xymatrix.doc
371 xyarrow.tex:                    xyarrow.doc
372 xygraph.tex:                    xygraph.doc
373 xy2cell.tex:                    xy2cell.doc
374 xypoly.tex:                     xypoly.doc
375 xyarc.tex:                      xyarc.doc
376 xyknot.tex:                     xyknot.doc
377 xyweb.tex:                      xyweb.doc

378 #

379 # Driver option dependencies:

380 #

381 xycmactex.tex:                  xycmactex.doc
382 xydvips.tex:                    xydvips.doc
383 xydvitops.tex:                  xydvitops.doc

384 xydvidrv.tex:                   xydvidrv.doc
385 xydocps.tex:                    xydocps.doc
386 xytextures.tex:                 xytextures.doc
387 xy16textures.tex:               xy16textures.doc
388 xyoztex.tex:                    xyoztex.doc
389 xymovie.tex:                    xymovie.doc
390 xy17oztex.tex:                  xy17oztex.doc
391 xyxdvi.tex:                     xyxdvi.doc

392 #

393 # Backwards compatibility dependencies:

394 #

395 xyv2.tex:                       xyv2.doc
396 xypic.tex:                      xypic.doc

397 #

398 # Required documentation files

399 #

400 install.trailer:        $(TRAILERRUN)
401  -test -d $(TEXDOCDIR) || $(MKDIR) $(TEXDOCDIR)
402  for f in $(TRAILERRUN); do $(INSTALL) $$f $(TEXDOCDIR)/$$f; done
405 # PostScript HEADERS:

406 #

407 .PHONY: install.ps
408 install.ps:             $(PSRUN)
409  test -d $(PSHEADERDIR) || $(MKDIR) $(PSHEADERDIR)
410  for f in $(PSRUN); do $(INSTALL) $$f $(PSHEADERDIR)/$$f; done
413 # FONTS.

414 #

415 .PHONY:         mfinputs texfonts $(PK)fonts fonts install.fonts \
416  psfonts install.psfonts obsoletefonts install.obsoletefonts

417 #

418 METAFONTS = \
419  xydash10.mf xybsql10.mf xyd2.mf \
420  xyatip10.mf xybtip10.mf xytech.mf xyatip.mf xybtip.mf xyd.mf \
421  xycirc10.mf \
422  xycmat10.mf xycmbt10.mf xycmat11.mf xycmbt11.mf \
423  xycmat12.mf xycmbt12.mf xycm.mf \
424  xyeuat10.mf xyeubt10.mf xyeuat11.mf xyeubt11.mf \
425  xyeuat12.mf xyeubt12.mf xyeuler.mf

426 #

427 TEXFONTRUN = \
428  xydash10.tfm xybsql10.tfm xyatip10.tfm xybtip10.tfm xycirc10.tfm \
429  xycmat10.tfm xycmbt10.tfm xycmat11.tfm xycmbt11.tfm \
430  xycmat12.tfm xycmbt12.tfm \
431  xyeuat10.tfm xyeubt10.tfm xyeuat11.tfm xyeubt11.tfm \
432  xyeuat12.tfm xyeubt12.tfm

433 #

434 # Note: we only depend on the tfm-files, so you must remove them to
435 # regenerate the fonts at all desired magnifications.

436 #

437 .SUFFIXES:      .mf .tfm
438 .mf.tfm:;       $(MF2TFM)

439 #

440 mfinputs:       $(METAFONTS)

441 #

442 texfonts $(PK)fonts fonts: $(METAFONTS) $(TEXFONTRUN)
443 install.fonts:  fonts
444  if test -n "$(MFINPUTDIR)"; then \
445  test -d $(MFINPUTDIR) || $(MKDIR) $(MFINPUTDIR); \
446  for f in $(METAFONTS);do $(INSTALL) $$f $(MFINPUTDIR)/$$f;done; fi
447  -test -d $(TEXFONTDIR) || $(MKDIR) $(TEXFONTDIR)
448  for f in $(TEXFONTRUN); do $(INSTALL) $$f $(TEXFONTDIR)/$$f; done

449  #

450  [ "$(MAGS)" = "." ] || \
451  for mode in $(MODES); do for mag in $(MAGS); do \
452  $(RM) xytest.*gf xytest.*tfm;\
453  $(MF) "\\mode=$$mode; mag=magstep($$mag); input xytest";\
454  dpi="`expr xytest.*gf : 'xytest\.\([0-9]*\)gf'`";\
455  for f in $(TEXFONTRUN); do \
456  f="`expr $$f : '\([a-z0-9]*\)\.tfm'`.$${dpi}$(PK)" ;\
457  if [ ! -f $$f ]; then echo "ERROR: FONT $$f NOT GENERATED";\
458  else test -d "$(FONTDIR)" || $(MKDIR) $(FONTDIR);\
459  $(INSTALL) $$f $(FONTDIR)/$$f; fi; done; done; done

460 #

461 xydash10.tfm:   xydash10.mf xyd2.mf xytest.mf
462 xybsql10.tfm:   xybsql10.mf xyd.mf xytest.mf
463 xycirc10.tfm:   xycirc10.mf xytest.mf
464 xyatip10.tfm:   xyatip10.mf xytech.mf xyatip.mf xyd.mf xytest.mf
465 xybtip10.tfm:   xybtip10.mf xytech.mf xybtip.mf xyd.mf xytest.mf
466 xycmat10.tfm:   xycmat10.mf xyatip.mf xyd.mf xytest.mf
467 xycmbt10.tfm:   xycmbt10.mf xybtip.mf xyd.mf xytest.mf
468 xyeuat10.tfm:   xyeuat10.mf xyatip.mf xyd.mf xytest.mf
469 xyeubt10.tfm:   xyeubt10.mf xybtip.mf xyd.mf xytest.mf

470 #

471 # Obsolete fonts (from 2.6 and before).

472 #

473 OBSOLETEMETAFONTS = xyline10.mf xyqc10.mf xymisc10.mf
474 OBSOLETETEXFONTRUN = xyline10.tfm xyqc10.tfm xymisc10.tfm

475 #

476 obsoletefonts:  $(OBSOLETEMETAFONTS) $(OBSOLETETEXFONTRUN)

477 #

478 install.obsoletefonts:  obsoletefonts
479  if test -n "$(MFINPUTDIR)"; then \
480  test -d $(MFINPUTDIR) || $(MKDIR) $(MFINPUTDIR); \
481  for f in $(OBSOLETEMETAFONTS);do $(INSTALL) $$f $(MFINPUTDIR)/$$f;done; fi
482  -test -d $(TEXFONTDIR) || $(MKDIR) $(TEXFONTDIR)
483  for f in $(OBSOLETETEXFONTRUN); do \
484  $(INSTALL) $$f $(TEXFONTDIR)/$$f; done

485  #

486  [ "$(MAGS)" = "." ] || \
487  for mode in $(MODES); do for mag in $(MAGS); do \
488  $(RM) xytest.*gf xytest.*tfm;\
489  $(MF) "\\mode=$$mode; mag=magstep($$mag); input xytest";\
490  dpi="`expr xytest.*gf : 'xytest\.\([0-9]*\)gf'`";\
491  for f in $(OBSOLETETEXFONTRUN); do \
492  f="`expr $$f : '\([a-z0-9]*\)\.tfm'`.$${dpi}$(PK)" ;\
493  if [ ! -f $$f ]; then echo "ERROR: FONT $$f NOT GENERATED";\
494  else test -d "$(FONTDIR)" || $(MKDIR) $(FONTDIR);\
495  $(INSTALL) $$f $(FONTDIR)/$$f; fi; done; done; done

496 #

497 xyline10.tfm:   xyline10.mf xytest.mf
498 xyqc10.tfm:     xyqc10.mf xytest.mf
499 xymisc10.tfm:   xymisc10.mf xytest.mf
501 # PostScript fonts w/support files...from Y&Y.

502 #

503 TYPE1FONTS = \
504  xyatip10.pfb xybsql10.pfb xybtip10.pfb xycirc10.pfb xydash10.pfb \
505  xycmat10.pfb xycmbt10.pfb xyeuat10.pfb xyeubt10.pfb

506 #

507 PFMFONTS = \
508  xyatip10.pfm xybsql10.pfm xybtip10.pfm xycirc10.pfm xydash10.pfm \
509  xycmat10.pfm xycmbt10.pfm xyeuat10.pfm xyeubt10.pfm

510 #

511 AFMFONTS = \
512  xyatip10.afm xybsql10.afm xybtip10.afm xycirc10.afm xydash10.afm \
513  xycmat10.afm xycmbt10.afm xyeuat10.afm xyeubt10.afm

514 #

515 YANDYFONTS = $(TYPE1FONTS) $(AFMFONTS) $(PFMFONTS)

516 #

517 psfonts: $(YANDYFONTS)

518 #

519 $(YANDYFONTS): YandY_xy_fonts.zip
520  unzip -aoL YandY_xy_fonts.zip
521  touch $(YANDYFONTS)

522 #

523 install.psfonts: psfonts xypic.map
524  test -d $(TYPE1DIR) || $(MKDIR) $(TYPE1DIR)
525  test -d $(PFMDIR) || $(MKDIR) $(PFMDIR)
526  test -d $(AFMDIR) || $(MKDIR) $(AFMDIR)
527  test -d $(PDFDIR) || $(MKDIR) $(PDFDIR)
528  for f in $(TYPE1FONTS); do $(INSTALL) $$f $(TYPE1DIR)/$$f; done
529  for f in $(PFMFONTS); do $(INSTALL) $$f $(PFMDIR)/$$f; done
530  for f in $(AFMFONTS); do $(INSTALL) $$f $(AFMDIR)/$$f; done
531  test -d $(PSHEADERDIR) || $(MKDIR) $(PSHEADERDIR)
532  $(INSTALL) xypic.map $(PSHEADERDIR)/xypic.map

533 #

534 # All together...

535 #

536 FONTSOURCES = $(METAFONTS) $(OBSOLETEMETAFONTS) xytest.mf \
537  YandY_xy_fonts.zip xypic.map
539 # FORMATS:

540 #

541 # Build formats...

542 #

543 .SUFFIXES:      .ini .fmt
544 .ini.fmt:;      $(INITEX) $<

545 #

546 xytex.fmt:      xytex.ini macros
547 xylatex.fmt:    xylatex.ini macros
548 #xyamslatex.fmt:        xyamslatex.ini macros
549 #xydoc.fmt:     xydoc.ini macros
552 # MANUAL: USER'S GUIDE AND REFERENCE MANUAL.

553 #

554 # Note: the first generations use the DVIPS backend to run faster.

555 #

556 .PHONY:         guide manual install.manual manual.ps

557 #

558 MANUALDATA = ross.eps kris.eps import1.eps
559 MANUALSOURCES =         \
560  xyguide.man xydoc.sty latin1.sty xydoc.bib xydoc.back \
561  xyrefer.man $(KERNELSOURCES) $(LATEXSTYLES) $(OPTIONSOURCES) \
562  $(OPTIONDATA) $(MANUALDATA)

563 #

564 MANUALRUN =     xyguide.dvi xyrefer.dvi

565 #

566 .SUFFIXES:      .man .dvips .dvi .pdf
567 .man.dvips:
568  $(MAKE) macros fonts
569  echo "\\xyoption{dvips}\xyoption{ps}" > xydoc.back
570  $(LATEX) $<
571  @-$(CP) $<.dvi $*.dvi ; $(CP) $<.aux $*.aux ; $(CP) $<.idx $*.idx
572  $(BIBTEX) $*
573  @-$(CP) $*.bbl $<.bbl
574  [ -f $*.idx ] && $(MAKEINDEX) $* || :
575  @-$(CP) $*.ind $<.ind
576  echo "\\xyoption{dvips}\xyoption{ps}" > xydoc.back
577  $(LATEX) $<
578  @-$(CP) $<.dvi $*.dvi ; $(CP) $<.aux $*.aux ; $(CP) $<.idx $*.idx
579  [ -f $*.idx ] && makeindex $* || :
580  @-$(CP) $*.ind $<.ind
581  echo "\\xyoption{dvips}\xyoption{ps}" > xydoc.back
582  $(LATEX) $<
583  @-$(CP) $<.dvi $*.dvi ; $(CP) $<.aux $*.aux ; $(CP) $<.idx $*.idx
584  mv $*.dvi $*.dvips
585  touch $*.dvips

586 #

587 .dvips.dvi:
588  echo '' > xydoc.back
589  $(LATEX) $*.man
590  @-$(CP) $*.man.dvi $*.dvi ; $(CP) $*.man.aux $*.aux ; $(CP) $*.man.idx $*.idx
591  touch $*.dvi

592 #

593 .dvips.pdf:
594  echo '' > xydoc.back
595  $(PDFLATEX) $*.man
596  @-$(CP) $*.man.pdf $*.pdf ; $(CP) $*.man.aux $*.aux ; $(CP) $*.man.idx $*.idx
597  touch $*.pdf

598 #

599 guide:          xyguide.dvi

600 #

601 manual:         $(MANUALRUN)
602 install.manual: manual
603  -test -d $(TEXDOCDIR) || $(MKDIR) $(TEXDOCDIR)
604  for f in $(MANUALRUN); do $(INSTALL) $$f $(TEXDOCDIR)/$$f; done

605 #

606 xyguide.dvips:  xyguide.man xydoc.sty latin1.sty xydoc.bib version.tex
607 xyrefer.dvips:  xyrefer.man xydoc.sty latin1.sty xydoc.bib version.tex \
608  $(KERNELSOURCES) $(OPTIONSOURCES) $(MANUALDATA)
609 xytest.dvips:   xytest.man xydoc.sty latin1.sty xydoc.bib version.tex \
610  $(KERNELSOURCES) $(OPTIONSOURCES) $(MANUALDATA)

611 #

612 xyguide.dvi:    xyguide.dvips version.tex
613 xyrefer.dvi:    xyrefer.dvips version.tex
614 xytest.dvi:     xytest.dvips version.tex

615 #

616 xyguide.pdf:    xyguide.dvips version.tex
617 xyrefer.pdf:    xyrefer.dvips version.tex
618 xytest.pdf:     xytest.dvips version.tex

619 #

620 version.tex:    version.doc
621  $(LATEX) version.doc

622 #

623 .SUFFIXES:      .pro
624 xy$(SHORTVERSION)dict.pro: xydocps.tex xypsdict.tex xypspatt.tex xyps-pro.tex
625  -$(RM) xy$(SHORTVERSION)dict.pro
626  $(TEX) xydocps.tex

627 #

628 # PostScript targets:

629 #

630 # DVIPS should be Tom Rokicki's dvips PostScript DVI driver as a filter.
631 DVIPS = dvips -D600 -f

632 #

633 .SUFFIXES:      .ps
634 .dvips.ps:;     $(DVIPS) < $< > $@

635 #

636 xyguide.ps:     xyguide.dvips $(PSRUN)
637 xyrefer.ps:     xyrefer.dvips $(PSRUN)

638 #

639 manual.ps:      xyguide.ps xyrefer.ps
642 # TeXNICAL DOCUMENTATION.

643 #

644 .PHONY:         TeXnical
645 TeXnical:       xysource.ps xysource.dvi xysource.pdf

646 #

647 TeXNICALSOURCES = xysource.man COPYING.patch xydoc.back

648 #

649 TeXNICALAUX = \
650  TRAILER CATALOG README $(INSTALLSTAR) MAKE MANIFEST \
651  COPYING.tex

652 #

653 xysource.dvips: xysource.man macros.tmp \
654  macros fonts obsoletefonts $(ALLSOURCES) $(TeXNICALAUX)
655 xysource.ps:    xysource.dvips
656 xysource.dvi:   xysource.dvips
657 xysource.pdf:   xysource.dvips

658 #

659 xywork.dvips: xywork.man macros.tmp \
660  macros fonts obsoletefonts $(ALLSOURCES) $(TeXNICALAUX)
661 xywork.ps:      xywork.dvips
662 xywork.dvi:     xywork.dvips
663 xywork.pdf:     xywork.dvips

664 #

665 COPYING.tex: COPYING COPYING.patch
666  patch COPYING -o COPYING.tex < COPYING.patch

667 #

668 FONTCOPYING.tex: FONTCOPYING FONTCOPYING.patch
669  patch FONTCOPYING -o FONTCOPYING.tex < FONTCOPYING.patch

670 #

671 # Macro index...requires GNU AWK (gawk) or (in a pinch) NAWK.

672 #

673 GAWK = gawk

674 #

675 macros.tmp: $(KERNELSOURCES) $(LATEXSTYLES) $(OPTIONSOURCES) $(METAFONTS)
676  -$(RM) macros.tmp
677  for f in $(KERNELSOURCES) $(LATEXSTYLES) $(OPTIONSOURCES) $(METAFONTS);\
678  do $(GAWK) '\
679  func err(s) { printf("%s,%d: %s\n",FILENAME,FNR,s) >>"/dev/stderr"};\
680  func prt(s,i) { \
681  printf("\\filelinedef{%s}{%d}\\index def{%s}\n",FILENAME,FNR,s) };\
682  func prtdef(i) { t = substr($$0,i);\
683  if (match(t,/[\\|][a-zA-Z@]*|\\.|[^\\|]|{([^{}]|\\{|\\})*}/) != 1) \
684  err("Weird TeX token");\
685  else prt(substr($$0,i,RLENGTH),i) };\

686  func prtcsdef(i) { t = substr($$0,i);\
687  if (match(t,/{([^{}]|\\{|\\})*}|{([^{}]|\\{|\\})*{([^{}]|\\{|\\})*}([^{}]|\\{|\\})*}/) != 1) \
688  err("Weird TeX cs name token");\
689  else prt(substr($$0,i+1,RLENGTH-2),i) };\
690  /^\\let[^A-Za-z@]/            ||\
691  /^\\def[^A-Za-z@]/            { prtdef(5); next };\
692  /^\\gdef[^A-Za-z@]/           ||\
693  /^\\edef[^A-Za-z@]/           ||\
694  /^\\xdef[^A-Za-z@]/           { prtdef(6); next };\
695  /^\\newif[^A-Za-z@]/          { prtdef(7); next };\
696  /^\\xydef@[^A-Za-z@]/         ||\
697  /^\\xylet@[^A-Za-z@]/         { prtdef(8); next };\
698  /^\\xyfont@[^A-Za-z@]/        { prtdef(9); next };\
699  /^\\global\\let[^A-Za-z@]/    { prtdef(12); next };\
700  /^\\xywarnifdefined[^A-Za-z@]/ { prtdef(17); next };\
701  /^\\ifx\\undefined[^A-Za-z@]/ { prtdef(15); next };\
702  /^\\xynew@{[^{}]*}/           { prtdef(index($$0,"}")+1); next };\
703  /^\\xydefcsname@{/            { prtcsdef(14); next };\
704  /^\\xyletcsnamecsname@{/      { prtcsdef(20); next }' $$f;\
705  done | sed -e 's,\\{,\\\\otherebgroup,' -e 's,\\},\\\\otheregroup,' \
706  > macros.tmp
708 ###printf("\\macroentry{%s}{%s}{%d}\n",s,FILENAME,FNR) };\
711 # Xy-pic the MOVIE :)

712 #

713 .SUFFIXES: .texmovie .gif

714 #

715 .texmovie.gif:
716  $(LATEX) '\documentclass[dvips]{movie}' \
717  '\usepackage[all]{xy}' \
718  '\begin{document}' \
719  '\input{$*.texmovie}' \
720  '\end{document}'
721  @-[ -f texput.dvi ] && $(MV) texput.dvi $*.dvi && $(MV) texput.size $*.size
722  @-[ -f movie.cls.dvi ] && $(MV) movie.cls.dvi $*.dvi && $(MV) movie.cls.size $*.size
723  @-[ -f movie.dvi ] && $(MV) movie.dvi $*.dvi && $(MV) movie.size $*.size
724  ./dvitogif89a $*.dvi

725 #

726 .texmovie.dvi:
727  $(LATEX) '\documentclass{article}' \
728  '\usepackage[movie,all]{xy}' \
729  '\begin{document}' \
730  '\title{Storyboard for ``$*.''}' \
731  '\maketitle' \
732  '\input{$*.texmovie}' \
733  '\end{document}'

734 #

735 dragon.gif:     dragon.texmovie movie.cls dvitogif89a
736 dragon.dvi:     dragon.texmovie movie.cls

737 #

738 sesam.gif:      sesam.texmovie movie.cls dvitogif89a
739 sesam.dvi:      sesam.texmovie movie.cls

740 #

741 gasket.dvi:     gasket.texmovie movie.cls dvitogif89a
742 gasket.gif:     gasket.texmovie movie.cls
745 # DISTRIBUTION TREE.

746 #

747 DISTDIR = $(FTPROOT)/xy-$(VERSION)
748 DISTFONTDIR = $(DISTDIR)/$(PK)fonts/$${mode}$${dpi}

749 #

750 # Files:

751 #

752 SOURCES = $(MACROSOURCES) $(FONTSOURCES) $(MANUALSOURCES) $(SUPPORT)

753 #

754 # Commands:

755 #

756 # TAR <files>           output tar archive with <files>
757 # GZIP                  compression filter
758 # GZ                    filename extension appropriate for compressed files

759 #

760 # TODO: change compression to proper GNU gzip once everyone supports it...

761 #

762 TAR = tar cvf -
763 GZIP = gzip -v9
764 GZ = .gz

765 #

766 # Targets:

767 #

768 .PHONY: dist dist-$(VERSION) distsrc distrun distdoc

769 #

770 dist dist-$(VERSION):
771  cd $(DISTDIR);\
772  find . -type f -print | sed 's,^./,,' | sort > MANIFEST
773  $(INSTALL) README $(DISTDIR)/README

774 #

775 distsrc:        $(DISTDIR)/src

776 #

777 distrun:        $(DISTDIR)/CATALOG \
778  $(DISTDIR)/TRAILER \
779  $(DISTDIR)/README \
780  $(DISTDIR)/INSTALL \
781  $(DISTDIR)/VERSIONS \
782  $(DISTDIR)/texinputs \
783  $(DISTDIR)/texfonts \
784  $(DISTDIR)/mfinputs \
785  $(DISTDIR)/$(PK)fonts \
786  $(DISTDIR)/doc/xyguide.dvi \
787  $(DISTDIR)/doc/xyrefer.dvi \

788  $(DISTDIR)/doc/xysource.dvi \
789  $(DISTDIR)/ps \
790  $(DISTDIR)/type1 \
791  $(DISTDIR)/pfm \
792  $(DISTDIR)/afm \
793  $(DISTDIR)/COPYING \
794  $(DISTDIR)/support

795 #

796 distdoc:        $(DISTDIR)/doc/xyguide.dvips \
797  $(DISTDIR)/doc/xyguide.ps \
798  $(DISTDIR)/doc/xyguide.pdf \
799  $(DISTDIR)/doc/xyrefer.dvips \
800  $(DISTDIR)/doc/xyrefer.ps \
801  $(DISTDIR)/doc/xyrefer.pdf \
802  $(DISTDIR)/doc/xysource.dvips \
803  $(DISTDIR)/doc/xysource.ps
804 #### CURRENTLY BROKEN:
805 #               $(DISTDIR)/doc/xyguide-html \

806 #

807 # Explanation targets:

808 #

809 # CATALOG is automatically generated:

810 #

811 $(DISTDIR)/CATALOG: CATALOG $(DISTDIR)
812  $(INSTALL) CATALOG $(DISTDIR)/CATALOG

813 #

814 CATALOG:        CATALOG.doc
815  $(LATEX) CATALOG.doc
816  mv -f CATALOG.out CATALOG
818 $(DISTDIR)/TRAILER: TRAILER $(DISTDIR)
819  $(INSTALL) TRAILER $(DISTDIR)/TRAILER
821 $(DISTDIR)/README: README $(DISTDIR)
822  $(INSTALL) README $(DISTDIR)/README
824 $(DISTDIR)/VERSIONS: VERSIONS $(DISTDIR)
825  $(INSTALL) VERSIONS $(DISTDIR)/VERSIONS
827 $(DISTDIR)/INSTALL: $(INSTALLSTAR) $(DISTDIR)
828  for f in $(INSTALLSTAR); do if test -f "$$f"; then \
829  $(INSTALL) $$f $(DISTDIR)/$$f; else :; fi; done
831 $(DISTDIR)/COPYING: COPYING $(DISTDIR)
832  $(INSTALL) COPYING $(DISTDIR)/COPYING
834 $(DISTDIR)/FONTCOPYING: FONTCOPYING $(DISTDIR)
835  $(INSTALL) FONTCOPYING $(DISTDIR)/FONTCOPYING

836 #

837 # Directory targets:

838 #

839 $(DISTDIR):
840  -test -d $(DISTDIR) || $(MKDIR) $(DISTDIR)

842 $(DISTDIR)/src: $(SOURCES) MANIFEST VERSIONS ChangeLog $(DISTDIR)
843  -test -d $(DISTDIR)/src || $(MKDIR) $(DISTDIR)/src
844  for f in $(SOURCES); do echo $$f; done | sort -fu |\
845  while read u; do $(INSTALL) $$u $(DISTDIR)/src/$$u; done
846  echo '' > xydoc.back
847  $(INSTALLW) xydoc.back $(DISTDIR)/src
848  $(INSTALLW) MANIFEST VERSIONS ChangeLog $(DISTDIR)/src
850 xydoc.back:
851  echo '' > xydoc.back

852 #

853 # The MANIFEST in src is just a list of the distributed source files.

854 #

855 MANIFEST:       $(SOURCES)
856  ls -alg `for f in $(SOURCES); do echo $$f; done | sort -fu` >MANIFEST

857 #

858 # The VERSIONS is just a list of the RCS versions.

859 #

860 VERSIONS:       $(SOURCES)
861  sed -n 's/^.*\([$$]Id[:][^$$]*[$$]\).*$$/\1/p' \
862  `for f in $(SOURCES); do echo $$f; done | sort -u` >VERSIONS
864 $(DISTDIR)/texinputs: macros $(DISTDIR)
865  -test -d $(DISTDIR)/texinputs \
866  || $(MKDIR) $(DISTDIR)/texinputs
867  for f in $(MACRORUN) $(LATEXSTYLES); \
868  do $(INSTALL) $$f $(DISTDIR)/texinputs/$$f; done
870 $(DISTDIR)/texfonts: texfonts obsoletefonts $(DISTDIR)
871  -test -d $(DISTDIR)/texfonts \
872  || $(MKDIR) $(DISTDIR)/texfonts
873  for f in $(TEXFONTRUN) $(OBSOLETETEXFONTRUN); \
874  do $(INSTALL) $$f $(DISTDIR)/texfonts/$$f; done
876 $(DISTDIR)/mfinputs: mfinputs $(OBSOLETEMETAFONTS) $(DISTDIR)
877  -test -d $(DISTDIR)/mfinputs || $(MKDIR) $(DISTDIR)/mfinputs
878  for f in $(METAFONTS) $(OBSOLETEMETAFONTS); \
879  do $(INSTALL) $$f $(DISTDIR)/mfinputs/$$f; done
881 $(DISTDIR)/$(PK)fonts: $(PK)fonts $(DISTDIR)
882  -test -d $(DISTDIR)/$(PK)fonts || $(MKDIR) $(DISTDIR)/$(PK)fonts

883  :

884  for mode in $(MODES); do for mag in $(MAGS); do \
885  $(RM) xytest.*gf xytest.*tfm;\
886  $(MF) "\\mode=$$mode; mag=magstep($$mag); input xytest";\
887  dpi="`expr xytest.*gf : 'xytest\.\([0-9]*\)gf'`";\
888  for f in $(TEXFONTRUN); do \
889  f="`expr $$f : '\([a-z0-9]*\)\.tfm'`.$${dpi}$(PK)" ;\
890  if [ ! -f $$f ]; then echo "ERROR: FONT $$f NOT GENERATED";\
891  else test -d "$(DISTFONTDIR)" || $(MKDIR) $(DISTFONTDIR);\
892  $(INSTALL) $$f $(DISTFONTDIR)/$$f; fi; done; done; done
894 $(DISTDIR)/ps: xy$(SHORTVERSION)dict.pro xypic.map $(DISTDIR)

895  -test -d $(DISTDIR)/ps || $(MKDIR) $(DISTDIR)/ps
896  $(INSTALL) xy$(SHORTVERSION)*dict.pro $(DISTDIR)/ps
897  $(INSTALL) xypic.map $(DISTDIR)/ps
899 $(DISTDIR)/type1: $(TYPE1FONTS) $(DISTDIR)
900  -test -d $(DISTDIR)/type1 || $(MKDIR) $(DISTDIR)/type1
901  for f in $(TYPE1FONTS) ; \
902  do $(INSTALL) $$f $(DISTDIR)/type1/$$f; done
904 $(DISTDIR)/pfm: $(PFMFONTS) $(DISTDIR)
905  -test -d $(DISTDIR)/pfm || $(MKDIR) $(DISTDIR)/pfm
906  for f in $(PFMFONTS) ; \
907  do $(INSTALL) $$f $(DISTDIR)/pfm/$$f; done
909 $(DISTDIR)/afm: $(AFMFONTS) $(DISTDIR)
910  -test -d $(DISTDIR)/afm || $(MKDIR) $(DISTDIR)/afm
911  for f in $(AFMFONTS) ; \
912  do $(INSTALL) $$f $(DISTDIR)/afm/$$f; done
914 $(DISTDIR)/pdftex: $(DISTDIR) xypic.map
915  -test -d $(DISTDIR)/pdftex || $(MKDIR) $(DISTDIR)/pdftex
916  $(INSTALL) xypic.map $(DISTDIR)/pdftex
918 $(DISTDIR)/support: $(SUPPORT)
919  -test -d $(DISTDIR)/support || $(MKDIR) $(DISTDIR)/support
920  for f in $(SUPPORT) ; \
921  do $(INSTALLX) $$f $(DISTDIR)/support/$$f; done
923 # Document targets:

924 #

925 $(DISTDIR)/doc/xyguide.dvi:     xyguide.dvi $(DISTDIR)/doc
926  $(INSTALL) xyguide.dvi $(DISTDIR)/doc
928 $(DISTDIR)/doc/xyguide.dvips:   xyguide.dvips $(DISTDIR)/doc
929  $(INSTALL) xyguide.dvips $(DISTDIR)/doc
931 $(DISTDIR)/doc/xyguide.pdf:     xyguide.pdf $(DISTDIR)/doc
932  $(INSTALL) xyguide.pdf $(DISTDIR)/doc
934 $(DISTDIR)/doc/xyguide.ps:      xyguide.ps $(DISTDIR)/doc
935  $(INSTALL) xyguide.ps $(DISTDIR)/doc
937 $(DISTDIR)/doc/xyguide-html:    xyguide-html $(DISTDIR)/doc
938  tar cf - xyguide-html | (cd $(DISTDIR)/doc; tar xpvf -)
940 $(DISTDIR)/doc/xyrefer.dvi:     xyrefer.dvi $(DISTDIR)/doc
941  $(INSTALL) xyrefer.dvi $(DISTDIR)/doc
943 $(DISTDIR)/doc/xyrefer.dvips:   xyrefer.dvips ross.eps kris.eps import1.eps \
944  $(DISTDIR)/doc
945  $(INSTALL) xyrefer.dvips ross.eps kris.eps import1.eps $(DISTDIR)/doc
947 $(DISTDIR)/doc/xyrefer.pdf:     xyrefer.pdf ross.eps kris.eps import1.eps \
948  $(DISTDIR)/doc
949  $(INSTALL) xyrefer.pdf $(DISTDIR)/doc
951 $(DISTDIR)/doc/xyrefer.ps:      xyrefer.ps $(DISTDIR)/doc
952  $(INSTALL) xyrefer.ps $(DISTDIR)/doc

954 $(DISTDIR)/doc/xyrefer-html:    xyrefer-html $(DISTDIR)/doc
955  $(INSTALL) xyrefer-html $(DISTDIR)/doc
957 $(DISTDIR)/doc/xysource.dvi:    xysource.dvi $(DISTDIR)/doc
958  $(INSTALL) xysource.dvi $(DISTDIR)/doc
960 $(DISTDIR)/doc/xysource.dvips:  xysource.dvips ross.eps kris.eps import1.eps \
961  $(DISTDIR)/doc
962  $(INSTALL) xysource.dvips ross.eps kris.eps import1.eps $(DISTDIR)/doc
964 $(DISTDIR)/doc/xysource.ps:     xysource.ps $(DISTDIR)/doc
965  $(INSTALL) xysource.ps $(DISTDIR)/doc
967 $(DISTDIR)/doc:
968  -test -d $(DISTDIR)/doc || $(MKDIR) $(DISTDIR)/doc
971 # FTP'ABLE DISTRIBUTION.

972 #

973 FTPROOT = $$HOME/public_ftp/TeX
974 FTPDOCDIR = $(FTPROOT)/xy-$(VERSION)/doc

975 #

976 .PHONY:         ftp ftp-$(VERSION) ftpsrc ftprun ftpdoc ftpunpacked

977 #

978 ftp ftp-$(VERSION):     ftpsrc ftprun ftpdoc ftpunpacked
979  $(INSTALL) TRAILER $(FTPROOT)/xy$(SHORTVERSION).TRAILER

980 #

981 ftpsrc $(FTPROOT)/xy$(SHORTVERSION)src.tar$(GZ): distsrc
982  cd $(DISTDIR)/.. ;\
983  $(TAR) xy-$(VERSION)/src \
984  | $(GZIP) > $(FTPROOT)/xy$(SHORTVERSION)src.tar$(GZ)

985 #

986 ftpdoc $(FTPROOT)/xy$(SHORTVERSION)doc.tar$(GZ): distrun distdoc
987  cd $(DISTDIR)/.. ;\
988  $(TAR) xy-$(VERSION)/doc \
989  | $(GZIP) > $(FTPROOT)/xy$(SHORTVERSION)doc.tar$(GZ)
990  $(GZIP) < xyguide.dvi > $(FTPROOT)/xyguide.dvi$(GZ)
991  $(GZIP) < xyguide.dvips > $(FTPROOT)/xyguide.dvips$(GZ)
992  $(GZIP) < xyguide.ps    > $(FTPROOT)/xyguide.ps$(GZ)
993  $(GZIP) < xyguide.pdf    > $(FTPROOT)/xyguide.pdf$(GZ)
994  $(GZIP) < xyrefer.dvi > $(FTPROOT)/xyrefer.dvi$(GZ)
995  $(GZIP) < xyrefer.dvips > $(FTPROOT)/xyrefer.dvips$(GZ)
996  $(GZIP) < xyrefer.ps    > $(FTPROOT)/xyrefer.ps$(GZ)
997  $(GZIP) < xyrefer.pdf    > $(FTPROOT)/xyrefer.pdf$(GZ)
998  $(GZIP) < xysource.dvi > $(FTPROOT)/xysource.dvi$(GZ)
999  $(GZIP) < xysource.dvips > $(FTPROOT)/xysource.dvips$(GZ)
1000  $(GZIP) < xysource.ps    > $(FTPROOT)/xysource.ps$(GZ)
1001 #       $(TAR) xyguide-html | $(GZIP) > $(FTPROOT)/xyguide-html.tar.gz

1002 #

1003 ftprun $(FTPROOT)/xy$(SHORTVERSION)run.tar$(GZ): distrun
1004  cd $(DISTDIR)/.. ;\
1005  $(TAR) \
1006  `for f in $(TRAILERRUN); do echo xy-$(VERSION)/$$f; done` \

1007  xy-$(VERSION)/texinputs xy-$(VERSION)/mfinputs \
1008  xy-$(VERSION)/texfonts xy-$(VERSION)/$(PK)fonts \
1009  xy-$(VERSION)/ps xy-$(VERSION)/type1 xy-$(VERSION)/pfm \
1010  xy-$(VERSION)/afm \
1011  xy-$(VERSION)/support \
1012  | $(GZIP) > $(FTPROOT)/xy$(SHORTVERSION)run.tar$(GZ)

1013 #

1014 ftpunpacked: dist
1015  test $(DISTDIR) = $(FTPROOT)/xy-$(VERSION) || \
1016  (cd $(DISTDIR)/.. ; tar cf - xy-$(VERSION) |(cd $(FTPROOT); tar xvf -))
1017  cd $(FTPROOT); rm -f xy; ln -fs xy-$(VERSION) xy
1020 # WWW/HTML DOCUMENTATION & HYPE.

1021 #

1022 WWWDIR = $$HOME/public_html

1023 #

1024 WWWSOURCES =    Xy-pic.html Xy.doc Xy.xy \
1025  man2html.gawk man2html-post.gawk .latex2html-init

1026 #

1027 .PHONY:         guide.html www install.www

1028 #

1029 LATEX2HTML =    latex2html

1030 #

1031 LATEX2HTMLICONDIR = $$HOME/src/latex2html-96.1/icons
1032 LATEX2HTMLICONDIR2 = $$HOME/CV

1033 #

1034 man2html =      $(GAWK) -f man2html.gawk
1035 man2htmlpost =  $(GAWK) -f ../man2html-post.gawk

1036 #

1037 guide.html:     xyguide-html

1038 #

1039 xyguide-html.tex: xyguide.dvips xyguide.man $(WWWSOURCES)
1040  $(man2html) <xyguide.aux >xyguide-html.aux
1041  $(man2html) <xyguide.bbl >xyguide-html.bbl
1042  @-$(CP) xyguide.man.ans xyguide.ans
1043  @-$(CP) xyguide.man.idx xyguide.idx
1044  @-$(CP) xyguide.man.ind xyguide.ind
1045  $(man2html) <xyguide.ans >xyguide-html.ans
1046  $(man2html) <xyguide.idx >xyguide-html.idx
1047  $(man2html) <xyguide.ind | sed 's/"/|/g' >xyguide-html.ind
1048  $(man2html) <xyguide.man >xyguide-html.tex

1049 #

1050 xyguide-html-act:       xyguide-html.tex version.tex
1051  echo "\\xyoption{dvips}\xyoption{ps}" > xydoc.back
1052  $(LATEX2HTML) xyguide-html.tex

1053 #

1054 xyguide-html:   xyguide-html.tex xyguide-html-act
1055  (cd xyguide-html; \
1056  for f in *.html; do mv $$f $$f~; \
1057  $(man2htmlpost) <$$f~ \

1058  | sed -e 's/``/"/g' -e "s/''/\"/g" -e 's/  [>] />/g' >$$f; done; \
1059  (cd $$HOME/W3; tar cf - COPYING) | tar xpf - )

1060  :

1061  cp "$(LATEX2HTMLICONDIR2)/18pt.html" xyguide-html
1062  cat xyguide-html/*.html \
1063  | tr '"' "\n" \
1064  | sed -n 's;[.][/]\([a-z_]*[.]gif\);\1;p' | sort -u \
1065  | while read f ;\
1066  do if [ -f "$(LATEX2HTMLICONDIR2)/$$f" ]; \
1067  then echo "[$$f]"; cp $(LATEX2HTMLICONDIR2)/$$f xyguide-html ; \
1068  elif [ -f "$(LATEX2HTMLICONDIR)/$$f" ]; \
1069  then echo "[$$f]"; cp $(LATEX2HTMLICONDIR)/$$f xyguide-html ; \
1070  fi ; done

1071  :

1072  (cd xyguide-html; \
1073  $(RM) .I* .O* *.ppm *.xyc *.ans *.aux *.idx *.bbl *.log *.tex *~)

1074 #

1075 Xy.tex: Xy.doc
1076 Xy.dvi: Xy.tex Xy.xy macros; $(LATEX) Xy
1077 Xy.ps:  Xy.dvi; $(DVIPS) Xy.dvi -oXy.ps

1078 #

1079 PNMCROP = ./pnmrawtopcropwhite | pnmcrop
1080 PGMTOGIF = pgmtoppm rgbi:1/1/1 | ppmtogif -interlace -transparent rgbi:1/1/1

1081 #

1082 Xy.gif: Xy.ps pnmrawtopcropwhite
1083  echo '' | \
1084  gs -sDEVICE=pbmraw -r300 \
1085  -sOutputFile='|$(PNMCROP) >Xy.pbm' \
1086  -q - Xy.ps
1087  cat Xy.pbm | $(PGMTOGIF) >Xy.gif

1088 #

1089 pnmrawtopcropwhite: pnmrawtopcropwhite.c

1090 #

1091 www:            Xy-pic.html Xy.gif
1092 ####BROKEN##### guide.html

1093 #

1094 install.www:    www
1095  $(INSTALL) Xy-pic.html Xy.gif $(WWWDIR)
1096 #       $(RM) $(WWWDIR)/xyguide-html
1097 #       $(MKDIR) $(WWWDIR)/xyguide-html
1098 #       tar -cf - xyguide-html | (cd $(WWWDIR); tar xvpf -)
1101 # ANNOUNCEMENTS.

1102 #

1103 MAILSOURCES = TRAILER Users mail.Users

1104 #

1105 .PHONY:         announce
1106 announce:       $(MAILSOURCES)
1107  @./mail.Users

1110 # TAGS for Emacs.

1111 #

1112 TAGS:   $(SOURCES)
1113  -$(RM) TAGS
1114  for f in `for ff in $(SOURCES); do echo $$ff; done |sort -u`;\

1115  do\

1116  $(GAWK) '\
1117  func err(s) { printf("%s,%d: %s\n",FILENAME,FNR,s) >>"/dev/stderr"};\
1118  func prt(s,n) { printf("%s\177%d,%d\n",s,FNR,c+n) };\
1119  func prtdef(i) { t = substr($$0,i);\
1120  if (match(t,/[\\|][a-zA-Z@]*|\\.|[^\\|]|{([^{}]|\\{|\\})*}/) != 1) \
1121  err("Weird TeX token");\
1122  else prt(substr($$0,1,i+RLENGTH),i) };\
1123  func prtcsdef(i) { t = substr($$0,i);\
1124  if (match(t,/{([^{}]|\\{|\\})*}|{([^{}]|\\{|\\})*{([^{}]|\\{|\\})*}([^{}]|\\{|\\})*}/) != 1) \
1125  err("Weird TeX cs name token");\
1126  else prt(substr($$0,1,i+RLENGTH),i) };\
1127  func fin() { c += length($$0) + 1; next };\
1128  BEGIN { c = 0 };\
1129  /^\\let[^A-Za-z@]/            ||\
1130  /^\\def[^A-Za-z@]/            { prtdef(5); fin() };\
1131  /^\\gdef[^A-Za-z@]/           ||\
1132  /^\\edef[^A-Za-z@]/           ||\
1133  /^\\xdef[^A-Za-z@]/           { prtdef(6); fin() };\
1134  /^\\newif[^A-Za-z@]/          { prtdef(7); fin() };\
1135  /^\\xydef@[^A-Za-z@]/         ||\
1136  /^\\xylet@[^A-Za-z@]/         { prtdef(8); fin() };\
1137  /^\\xyfont@[^A-Za-z@]/        { prtdef(9); fin() };\
1138  /^\\global\\let[^A-Za-z@]/    { prtdef(12); fin() };\
1139  /^\\xywarnifdefined[^A-Za-z@]/ { prtdef(17); fin() };\
1140  /^\\ifx\\undefined[^A-Za-z@]/ { prtdef(15); fin() };\
1141  /^\\xynew@{[^{}]*}/           { prtdef(index($$0,"}")+1); fin() };\
1142  /^\\xydefcsname@{/            { prtcsdef(14); fin() };\
1143  /^\\xyletcsnamecsname@{/      { prtcsdef(20); fin() };\
1144  /\?\?\=\[/    { s = $$0; i = 0;\
1145  while (first = index(s, "\?\?=[")) {\
1146  s = substr(s,first+4); i += first+4;\
1147  if (j = index(s, "]")) prt(substr($$0,1,i+j-1),i);\
1148  else printf("Unmatched []s") }; fin() };\
1149  /^@[A-Za-z]*{/ { prt($$0,index($$0,"{")+1); fin() };\
1150  { fin() }' $$f >TAGS.tmp ;\
1151  wc -c TAGS.tmp|$(GAWK) '{printf "\f\n%s,%s\n","'"$$f"'",$$1}'>>TAGS;\
1152  cat TAGS.tmp >>TAGS ;\
1153  done
1154  $(RM) TAGS.tmp
1157 # RCS STUFF:

1158 #

1159 .PHONY:         ci ci-$(VERSION) cici rcscheck \
1160  rcslist rcslockedlist rcsunlockedlist \

1161  rcscleanlist rcsuncleanlist rcsclean rcsdep

1162 #

1163 ALLSOURCES = $(TRAILERSOURCES) $(SOURCES) $(MANUALSOURCES) $(TeXNICALSOURCES) \
1164  $(WWWSOURCES) $(MAILSOURCES) $(OBSOLETEMETAFONTS) $(TYPE1FONTS) \
1165  $(SUPPORT) xypic.map

1166 #

1167 ROSSSOURCES = INSTALL.OzTeX INSTALL.Textures import1.eps ross.eps \
1168  xy16textures.doc xy17oztex.doc xy2cell.doc xyarc.doc \
1169  xycolor.doc xycrayon.doc xycurve.doc \
1170  xydvips.doc xyimport.doc xyknot.doc xyline.doc \
1171  xymacpat.xyp xyoztex.doc xypoly.doc xyps-c.doc xyps-col.doc \
1172  xyps-f.doc xyps-l.doc xyps-pro.doc xyps-ps.doc xyps-r.doc \
1173  xyps-s.doc xyps-t.doc xyps.doc xypsdict.doc xypspatt.doc xyrotate.doc \
1174  xytextures.doc xytile.doc xytpic.doc xyemtex.doc xyweb.doc \
1175  xydvidrv.doc xyxdvi.doc xydvitops.doc xytp-f.doc xycmactex.doc

1176 #

1177 YANDYSOURCES = \
1178  xyatip10.pfa xybsql10.pfa xybtip10.pfa xycirc10.pfa xycmat10.pfa \
1179  xycmbt10.pfa xydash10.pfa xyeuat10.pfa xyeubt10.pfa \

1180 #

1181 ci ci-$(VERSION): $(ALLSOURCES) cici Makefile
1182 cici:
1183  -rcs -l `for f in $(ALLSOURCES); do echo $$f; done | sort -u`
1184  -ci -u$(VERSION) `$(MAKE) rcslockedlist`

1185 #

1186 rcscheck:       $(ALLSOURCES)
1187  @locked="`$(MAKE) rcslockedlist`"; \
1188  unlocked="`$(MAKE) rcsunlockedlist`"; \
1189  echo "Missing write permission on locked files:"; \
1190  for f in $$locked; do [ -w "$$f" ] || echo ' '$$f; done; \
1191  echo "Wrong write permission on unlocked files:"; \
1192  for f in $$unlocked; do [ -w "$$f" ] && echo ' '$$f; done; \
1193  echo "Wrong/missing locks on ross's files:"; \
1194  for f in $(ROSSSOURCES); \
1195  do lock=; \
1196  for ff in $$locked; \
1197  do if [ "$$f" = "$$ff" ]; then lock=' ross'; fi; done; \
1198  fgrep -s " ross Exp$$lock "'$$' $$f \
1199  ||(/bin/echo ' '$$f': \c' && grep 'Id[:].* Exp ' $$f || echo '?'); \
1200  done; \
1201  echo "Wrong/missing locks on krisrose's files:"; \
1202  for f in `$(MAKE) rcslist`; \
1203  do for ff in $(ROSSSOURCES); \
1204  do if [ "$$f" = "$$ff" ]; then continue 2; fi; done; \
1205  lock=; \
1206  for ff in $$locked; \
1207  do if [ "$$f" = "$$ff" ]; then lock=' krisrose'; fi; done; \
1208  fgrep -s " krisrose Exp$$lock "'$$' $$f \
1209  || (/bin/echo ' '$$f' \c' && grep 'Id[:].* Exp ' $$f || echo ''); \

1210  done

1211 #

1212 rcslist:
1213  -@rlog -R `for f in $(ALLSOURCES); do echo $$f; done | sort -u` \
1214  2>/dev/null | sed 's;RCS/\(.*\),v;\1;'

1215 #

1216 rcslockedlist:
1217  -@rlog -R -L `for f in $(ALLSOURCES); do echo $$f; done | sort -u` \
1218  2>/dev/null | sed 's;RCS/\(.*\),v;\1;'

1219 #

1220 rcsunlockedlist:
1221  -@locked="`$(MAKE) rcslockedlist`"; \
1222  $(MAKE) rcslist | while read f; \
1223  do echo=echo; for ff in $$locked; \
1224  do if [ "$$f" = "$$ff" ]; then echo=:; fi; done; \
1225  $$echo $$f; done

1226 #

1227 rcscleanlist:
1228  -@$(MAKE) rcslist \
1229  | while read f; do if test -w "$$f" -o "$$f" = Makefile; then :; \
1230  else echo $$f; fi; done

1231 #

1232 rcsuncleanlist:
1233  -@$(MAKE) rcslist \
1234  | while read f; do if test -w "$$f" -o "$$f" = Makefile; \
1235  then echo $$f; fi; done

1236 #

1237 rcsclean:
1238  -@$(MAKE) rcscleanlist | while read f; do $(RM) $$f; done

1239 #

1240 # Dependencies...

1241 #

1242 rcsdep:
1243  $(MAKE) rcslist | while read f; do \
1244  echo "$$f: RCS/$$f,v; test -d RCS && co $$f || :"; done
1246 .late2html-init:; test -d RCS -a -f RCS/.late2html-init,v && co .late2html-init || :
1247 CATALOG.doc:; test -d RCS -a -f RCS/CATALOG.doc,v && co CATALOG.doc || :
1248 COPYING.patch:; test -d RCS -a -f RCS/COPYING.patch,v && co COPYING.patch || :
1249 COPYING:; test -d RCS -a -f RCS/COPYING,v && co COPYING || :
1250 FONTCOPYING.patch:; test -d RCS -a -f RCS/FONTCOPYING.patch,v && co FONTCOPYING.patch || :
1251 FONTCOPYING:; test -d RCS -a -f RCS/FONTCOPYING,v && co FONTCOPYING || :
1252 INSTALL.OzTeX:; test -d RCS -a -f RCS/INSTALL.OzTeX,v && co INSTALL.OzTeX || :
1253 INSTALL.Textures:; test -d RCS -a -f RCS/INSTALL.Textures,v && co INSTALL.Textures || :
1254 INSTALL:; test -d RCS -a -f RCS/INSTALL,v && co INSTALL || :
1255 MAKE:; test -d RCS -a -f RCS/MAKE,v && co MAKE || :
1256 Makefile:; test -d RCS -a -f RCS/Makefile,v && co Makefile || :
1257 README:; test -d RCS -a -f RCS/README,v && co README || :
1258 TRAILER:; test -d RCS -a -f RCS/TRAILER,v && co TRAILER || :
1259 Users:; test -d RCS -a -f RCS/Users,v && co Users || :

1260 Xy-pic.blurb:; test -d RCS -a -f RCS/Xy-pic.blurb,v && co Xy-pic.blurb || :
1261 Xy-pic.html:; test -d RCS -a -f RCS/Xy-pic.html,v && co Xy-pic.html || :
1262 Xy-pic.xbm:; test -d RCS -a -f RCS/Xy-pic.xbm,v && co Xy-pic.xbm || :
1263 Xy.doc:; test -d RCS -a -f RCS/Xy.doc,v && co Xy.doc || :
1264 Xy.xy:; test -d RCS -a -f RCS/Xy.xy,v && co Xy.xy || :
1265 YandY_xy_fonts.zip:; test -d RCS -a -f RCS/YandY_xy_fonts.zip,v && co YandY_xy_fonts.zip || :
1266 doc2tex.com:; test -d RCS -a -f RCS/doc2tex.com,v && co doc2tex.com || :
1267 dvitogif89a:; test -d RCS -a -f RCS/dvitogif89a,v && co dvitogif89a || :
1268 gasket.texmovie:; test -d RCS -a -f RCS/gasket.texmovie,v && co gasket.texmovie || :
1269 import1.eps:; test -d RCS -a -f RCS/import1.eps,v && co import1.eps || :
1270 install-tds:; test -d RCS -a -f RCS/install-tds,v && co install-tds || :
1271 kris.eps:; test -d RCS -a -f RCS/kris.eps,v && co kris.eps || :
1272 latin1.sty:; test -d RCS -a -f RCS/latin1.sty,v && co latin1.sty || :
1273 mail.Users:; test -d RCS -a -f RCS/mail.Users,v && co mail.Users || :
1274 man2html-post.gawk:; test -d RCS -a -f RCS/man2html-post.gawk,v && co man2html-post.gawk || :
1275 man2html.gawk:; test -d RCS -a -f RCS/man2html.gawk,v && co man2html.gawk || :
1276 movie.cls:; test -d RCS -a -f RCS/movie.cls,v && co movie.cls || :
1277 pnmrawtopcropwhite.c:; test -d RCS -a -f RCS/pnmrawtopcropwhite.c,v && co pnmrawtopcropwhite.c || :
1278 ross.eps:; test -d RCS -a -f RCS/ross.eps,v && co ross.eps || :
1279 version.doc:; test -d RCS -a -f RCS/version.doc,v && co version.doc || :
1280 xy.doc:; test -d RCS -a -f RCS/xy.doc,v && co xy.doc || :
1281 xy.sty:; test -d RCS -a -f RCS/xy.sty,v && co xy.sty || :
1282 xy16textures.doc:; test -d RCS -a -f RCS/xy16textures.doc,v && co xy16textures.doc || :
1283 xy17oztex.doc:; test -d RCS -a -f RCS/xy17oztex.doc,v && co xy17oztex.doc || :
1284 xy2cell.doc:; test -d RCS -a -f RCS/xy2cell.doc,v && co xy2cell.doc || :
1285 xyall.doc:; test -d RCS -a -f RCS/xyall.doc,v && co xyall.doc || :
1286 xyamslatex.ini:; test -d RCS -a -f RCS/xyamslatex.ini,v && co xyamslatex.ini || :
1287 xyarc.doc:; test -d RCS -a -f RCS/xyarc.doc,v && co xyarc.doc || :
1288 xyarrow.doc:; test -d RCS -a -f RCS/xyarrow.doc,v && co xyarrow.doc || :
1289 xyatip10.mf:; test -d RCS -a -f RCS/xyatip10.mf,v && co xyatip10.mf || :
1290 xybsql10.mf:; test -d RCS -a -f RCS/xybsql10.mf,v && co xybsql10.mf || :
1291 xybtip10.mf:; test -d RCS -a -f RCS/xybtip10.mf,v && co xybtip10.mf || :
1292 xycirc10.enc:; test -d RCS -a -f RCS/xycirc10.enc,v && co xycirc10.enc || :
1293 xycirc10.mf:; test -d RCS -a -f RCS/xycirc10.mf,v && co xycirc10.mf || :
1294 xycm.mf:; test -d RCS -a -f RCS/xycm.mf,v && co xycm.mf || :
1295 xycmactex.doc:; test -d RCS -a -f RCS/xycmactex.doc,v && co xycmactex.doc || :
1296 xycmat10.mf:; test -d RCS -a -f RCS/xycmat10.mf,v && co xycmat10.mf || :
1297 xycmat11.mf:; test -d RCS -a -f RCS/xycmat11.mf,v && co xycmat11.mf || :
1298 xycmat12.mf:; test -d RCS -a -f RCS/xycmat12.mf,v && co xycmat12.mf || :
1299 xycmbt10.mf:; test -d RCS -a -f RCS/xycmbt10.mf,v && co xycmbt10.mf || :
1300 xycmbt11.mf:; test -d RCS -a -f RCS/xycmbt11.mf,v && co xycmbt11.mf || :
1301 xycmbt12.mf:; test -d RCS -a -f RCS/xycmbt12.mf,v && co xycmbt12.mf || :
1302 xycmtip.doc:; test -d RCS -a -f RCS/xycmtip.doc,v && co xycmtip.doc || :
1303 xycolor.doc:; test -d RCS -a -f RCS/xycolor.doc,v && co xycolor.doc || :
1304 xycrayon.doc:; test -d RCS -a -f RCS/xycrayon.doc,v && co xycrayon.doc || :
1305 xycurve.doc:; test -d RCS -a -f RCS/xycurve.doc,v && co xycurve.doc || :
1306 xyd.enc:; test -d RCS -a -f RCS/xyd.enc,v && co xyd.enc || :
1307 xyd.mf:; test -d RCS -a -f RCS/xyd.mf,v && co xyd.mf || :
1308 xyd2.enc:; test -d RCS -a -f RCS/xyd2.enc,v && co xyd2.enc || :

1309 xyd2.mf:; test -d RCS -a -f RCS/xyd2.mf,v && co xyd2.mf || :
1310 xydash10.mf:; test -d RCS -a -f RCS/xydash10.mf,v && co xydash10.mf || :
1311 xydoc.bib:; test -d RCS -a -f RCS/xydoc.bib,v && co xydoc.bib || :
1312 xydoc.sty:; test -d RCS -a -f RCS/xydoc.sty,v && co xydoc.sty || :
1313 xydocps.doc:; test -d RCS -a -f RCS/xydocps.doc,v && co xydocps.doc || :
1314 xydriver.doc:; test -d RCS -a -f RCS/xydriver.doc,v && co xydriver.doc || :
1315 xydummy.doc:; test -d RCS -a -f RCS/xydummy.doc,v && co xydummy.doc || :
1316 xydvidrv.doc:; test -d RCS -a -f RCS/xydvidrv.doc,v && co xydvidrv.doc || :
1317 xydvips.doc:; test -d RCS -a -f RCS/xydvips.doc,v && co xydvips.doc || :
1318 xydvitops.doc:; test -d RCS -a -f RCS/xydvitops.doc,v && co xydvitops.doc || :
1319 xyemtex.doc:; test -d RCS -a -f RCS/xyemtex.doc,v && co xyemtex.doc || :
1320 xyeuat10.mf:; test -d RCS -a -f RCS/xyeuat10.mf,v && co xyeuat10.mf || :
1321 xyeuat11.mf:; test -d RCS -a -f RCS/xyeuat11.mf,v && co xyeuat11.mf || :
1322 xyeuat12.mf:; test -d RCS -a -f RCS/xyeuat12.mf,v && co xyeuat12.mf || :
1323 xyeubt10.mf:; test -d RCS -a -f RCS/xyeubt10.mf,v && co xyeubt10.mf || :
1324 xyeubt11.mf:; test -d RCS -a -f RCS/xyeubt11.mf,v && co xyeubt11.mf || :
1325 xyeubt12.mf:; test -d RCS -a -f RCS/xyeubt12.mf,v && co xyeubt12.mf || :
1326 xyeuler.doc:; test -d RCS -a -f RCS/xyeuler.doc,v && co xyeuler.doc || :
1327 xyframe.doc:; test -d RCS -a -f RCS/xyframe.doc,v && co xyframe.doc || :
1328 xygraph.doc:; test -d RCS -a -f RCS/xygraph.doc,v && co xygraph.doc || :
1329 xyguide.man:; test -d RCS -a -f RCS/xyguide.man,v && co xyguide.man || :
1330 xyidioms.doc:; test -d RCS -a -f RCS/xyidioms.doc,v && co xyidioms.doc || :
1331 xyimport.doc:; test -d RCS -a -f RCS/xyimport.doc,v && co xyimport.doc || :
1332 xyknot.doc:; test -d RCS -a -f RCS/xyknot.doc,v && co xyknot.doc || :
1333 xylatex.ini:; test -d RCS -a -f RCS/xylatex.ini,v && co xylatex.ini || :
1334 xyline.doc:; test -d RCS -a -f RCS/xyline.doc,v && co xyline.doc || :
1335 xyline10.mf:; test -d RCS -a -f RCS/xyline10.mf,v && co xyline10.mf || :
1336 xymacpat.xyp:; test -d RCS -a -f RCS/xymacpat.xyp,v && co xymacpat.xyp || :
1337 xymatrix.doc:; test -d RCS -a -f RCS/xymatrix.doc,v && co xymatrix.doc || :
1338 xymisc10.mf:; test -d RCS -a -f RCS/xymisc10.mf,v && co xymisc10.mf || :
1339 xymovie.doc:; test -d RCS -a -f RCS/xymovie.doc,v && co xymovie.doc || :
1340 xyoztex.doc:; test -d RCS -a -f RCS/xyoztex.doc,v && co xyoztex.doc || :
1341 xypic.doc:; test -d RCS -a -f RCS/xypic.doc,v && co xypic.doc || :
1342 xypic.map:; test -d RCS -a -f RCS/xypic.map,v && co xypic.map || :
1343 xypic.sty:; test -d RCS -a -f RCS/xypic.sty,v && co xypic.sty || :
1344 xypoly.doc:; test -d RCS -a -f RCS/xypoly.doc,v && co xypoly.doc || :
1345 xyps-c.doc:; test -d RCS -a -f RCS/xyps-c.doc,v && co xyps-c.doc || :
1346 xyps-col.doc:; test -d RCS -a -f RCS/xyps-col.doc,v && co xyps-col.doc || :
1347 xyps-dto.doc:; test -d RCS -a -f RCS/xyps-dto.doc,v && co xyps-dto.doc || :
1348 xyps-dvi.doc:; test -d RCS -a -f RCS/xyps-dvi.doc,v && co xyps-dvi.doc || :
1349 xyps-f.doc:; test -d RCS -a -f RCS/xyps-f.doc,v && co xyps-f.doc || :
1350 xyps-l.doc:; test -d RCS -a -f RCS/xyps-l.doc,v && co xyps-l.doc || :
1351 xyps-one.doc:; test -d RCS -a -f RCS/xyps-one.doc,v && co xyps-one.doc || :
1352 xyps-oz.doc:; test -d RCS -a -f RCS/xyps-oz.doc,v && co xyps-oz.doc || :
1353 xyps-pro.doc:; test -d RCS -a -f RCS/xyps-pro.doc,v && co xyps-pro.doc || :
1354 xyps-ps.doc:; test -d RCS -a -f RCS/xyps-ps.doc,v && co xyps-ps.doc || :
1355 xyps-pub.doc:; test -d RCS -a -f RCS/xyps-pub.doc,v && co xyps-pub.doc || :
1356 xyps-r.doc:; test -d RCS -a -f RCS/xyps-r.doc,v && co xyps-r.doc || :
1357 xyps-s.doc:; test -d RCS -a -f RCS/xyps-s.doc,v && co xyps-s.doc || :

1358 xyps-t.doc:; test -d RCS -a -f RCS/xyps-t.doc,v && co xyps-t.doc || :
1359 xyps-txo.doc:; test -d RCS -a -f RCS/xyps-txo.doc,v && co xyps-txo.doc || :
1360 xyps-txt.doc:; test -d RCS -a -f RCS/xyps-txt.doc,v && co xyps-txt.doc || :
1361 xyps-wdo.doc:; test -d RCS -a -f RCS/xyps-wdo.doc,v && co xyps-wdo.doc || :
1362 xyps.doc:; test -d RCS -a -f RCS/xyps.doc,v && co xyps.doc || :
1363 xypsdict.doc:; test -d RCS -a -f RCS/xypsdict.doc,v && co xypsdict.doc || :
1364 xypspatt.doc:; test -d RCS -a -f RCS/xypspatt.doc,v && co xypspatt.doc || :
1365 xyqc10.mf:; test -d RCS -a -f RCS/xyqc10.mf,v && co xyqc10.mf || :
1366 xyrecat.doc:; test -d RCS -a -f RCS/xyrecat.doc,v && co xyrecat.doc || :
1367 xyrefer.man:; test -d RCS -a -f RCS/xyrefer.man,v && co xyrefer.man || :
1368 xyrotate.doc:; test -d RCS -a -f RCS/xyrotate.doc,v && co xyrotate.doc || :
1369 xysmart.doc:; test -d RCS -a -f RCS/xysmart.doc,v && co xysmart.doc || :
1370 xysource.man:; test -d RCS -a -f RCS/xysource.man,v && co xysource.man || :
1371 xystyle.doc:; test -d RCS -a -f RCS/xystyle.doc,v && co xystyle.doc || :
1372 xytech.mf:; test -d RCS -a -f RCS/xytech.mf,v && co xytech.mf || :
1373 xytest.mf:; test -d RCS -a -f RCS/xytest.mf,v && co xytest.mf || :
1374 xytex.ini:; test -d RCS -a -f RCS/xytex.ini,v && co xytex.ini || :
1375 xytextures.doc:; test -d RCS -a -f RCS/xytextures.doc,v && co xytextures.doc || :
1376 xytile.doc:; test -d RCS -a -f RCS/xytile.doc,v && co xytile.doc || :
1377 xytips.doc:; test -d RCS -a -f RCS/xytips.doc,v && co xytips.doc || :
1378 xytp-f.doc:; test -d RCS -a -f RCS/xytp-f.doc,v && co xytp-f.doc || :
1379 xytpic.doc:; test -d RCS -a -f RCS/xytpic.doc,v && co xytpic.doc || :
1380 xyv2.doc:; test -d RCS -a -f RCS/xyv2.doc,v && co xyv2.doc || :
1381 xyweb.doc:; test -d RCS -a -f RCS/xyweb.doc,v && co xyweb.doc || :
1382 xyxdvi.doc:; test -d RCS -a -f RCS/xyxdvi.doc,v && co xyxdvi.doc || :
1385 # DEVELOPMENT TARGETS:

1386 #

1387 .PHONY:         Install.macros Install Ftpsrc Ftpdoc Ftp World Minor
1389 Install.macros:
1390  $(MAKE)          USR=$$HOME/pub                 install.macros
1392 Install:
1393  $(MAKE)          USR=$$HOME/pub                 install
1395 Ftpsrc:
1396  $(MAKE)        MODES='ljfour cx'                \
1397  MAGS='0 0.5 1 2'                \
1398  FTPROOT=$$HOME/public_ftp/TeX      ftpsrc
1400 Ftpdoc:
1401  $(MAKE)      MODES='ljfour cx'                  \
1402  MAGS='0 0.5 1 2'                  \
1403  FTPROOT=$$HOME/public_ftp/TeX        ftpdoc
1405 Ftp:
1406  $(MAKE)      MODES='ljfour cx'                  \
1407  MAGS='0 0.5 1 2'                  \
1408  FTPROOT=$$HOME/public_ftp/TeX        ftp
1410 Www:
1411  $(MAKE)    WWWROOT=$$HOME/public_html           install.www

1413 World:
1414  $(MAKE)      LATEX='time latex'                 \
1415  MODES='ljfour cx'                  \
1416  MAGS='0 0.5 1 2'                  world
1417  mv make.world make.World
1419 TMPFTPROOT = $$HOME/tmp/new-ftp-root
1421 Minor:
1422  $(MKDIR) $(TMPFTPROOT)
1423  $(MAKE)      LATEX='time latex'                 \
1424  MODES='ljfour cx'                  \
1425  MAGS='0 0.5 1 2'                  \
1426  FTPROOT=$(TMPFTPROOT)                world
1427  mv make.world make.Minor

1428 #

1429  @echo "Making patch:";\
1430  cd $(TMPFTPROOT); \
1431  diff -urN $(FTPROOT)/xy-$(VERSION) xy-$(VERSION) > FIX; \
1432  n=`cd $(FTPROOT);ls xy$(SHORTVERSION)fix* | wc -w 2>/dev/null`; \
1433  n=`expr $$n + 1`; \
1434  fix=$(FTPROOT)/xy$(SHORTVERSION)fix`printf '%.2d' $$n`; \
1435  cp -vf FIX $$fix; gzip -v9 $$fix

1436 #

1437  @echo "Updating real ftp archive $(FTPROOT):";\
1438  cd $(TMPFTPROOT); \
1439  find xy* -type f -print \
1440  | while read f;\
1441  do cmp -s $$f $(FTPROOT)/$$f\
1442  || { echo $$f; $(MKDIR) `dirname $(FTPROOT)/$$f`;\
1443  if [ -w $$f ]; then $(INSTALLW) $$f $(FTPROOT)/$$f;\
1444  else                $(INSTALL)  $$f $(FTPROOT)/$$f;\
1445  fi; };\
1446  done
1447  $(RM) $(TMPFTPROOT)
1450 # LOG

1451 #

1452 # $Log: Makefile,v $
1453 # Revision 3.7  1999/02/16 15:12:50  krisrose
1454 # Interim release (Y&Y fonts now free).

1455 #

1456 # Revision 3.6  1998/03/06 01:28:05  krisrose
1457 # Releasing (with Y&Y fonts).

1458 #

1459 # Revision 3.5  1997/05/28 13:05:01  krisrose
1460 # Fixed missing breaks bug.

1461 #

1462 # Revision 3.4  1997/05/18 03:04:44  krisrose
1463 # Essential bugfixes.
1464 # And movies now included!

1465 #

1466 # Revision 3.3  1996/12/19 17:05:13  krisrose
1467 # Maintenance release!

1468 #

1469 # Revision 3.2  1995/09/19  18:22:27  kris
1470 # Bug fix release.

1471 #

1472 # Revision 3.1  1995/09/05  20:31:32  kris
1473 # Releasing!

1474 #

1475 # Revision 3.0  1995/07/07  20:14:21  kris
1476 # Major release w/new User's Guide!

1477 #

1478 # Revision 2.14  1995/07/06  02:56:02  kris
1479 # Buglets...

1480 #

1481 # Revision 2.13  1995/07/04  15:10:01  kris
1482 # Ready to release v3?

1483 #

1484 # Revision 2.12  1994/10/25  11:46:25  kris
1485 # Interim release just before v3 [works with AMS-LaTeX 1.2]...

1486 #

1487 # Revision 2.11  1994/07/05  10:37:32  kris
1488 # Third 3beta release [bug fixes].
1489 # Experimental graph feature included (for ECCT-94 presentation).

1490 #

1491 # Revision 2.10  1994/06/15  13:35:19  kris
1492 # Second 3beta release [bug fixes].

1493 #

1494 # Revision 2.9  1994/06/09  14:53:07  kris
1495 # Release 3beta.

1496 #

1497 # Revision 2.8  1994/04/08  04:30:00  kris
1498 # Second (bug fix) 3alpha release.

1499 #

1500 # Revision 2.7  1994/03/08  02:06:01  kris
1501 # Release 3alpha.

1502 #

1503 # Revision 2.6.9.1  1994/03/07  04:22:46  kris
1504 # Last internal 3alpha and pre-2.7 release.

1505 #

1506 # MAJOR REORGANISATION for version 2.7...

1507 #

1508 # Revision 2.6  1992/06/24  01:23:34  kris
1509 # Ready to release v.2.6.

1510 #

1511 # Revision 2.5  1992/02/24  03:30:54  kris
1512 # Default magsteps now just 0, 0.5, 1, and 2.

1514 # Revision 2.3  1992/01/13  02:12:28  kris
1515 # Fixed installation instructions and other details.

1516 #

1517 # Revision 2.1  1992/01/02  14:54:07  kris
1518 # Release version.

1519 #

1520 # Revision 1.6  1991/12/17  04:51:16  kris
1521 # Version distributed with `final draft' on Usenet.
1523 # Tell Emacs that this is a Makefile and how it is formatted:
1524 # Local Variables:
1525 # mode:fundamental
1526 # fill-prefix:"# "
1527 # fill-column:77
1528 # End:

Bibliography

[1] Adobe Systems Incorporated. PostScript Language Reference Manual, second edition, 1990.

[2] American Mathematical Society. AMS-L^{A}TEX Version 1.1 User’s Guide, 1.1 edition, 1991.

[3] Karl Berry. Expanded plain TEX, version 2.6 edition, May 1994. Available for anonymous ftp

from CTAN in macros/eplain/doc.

[4] Michel Goossens, Frank Mittelbach, and Alexander Samarin. The L^{A}TEX Companion. Addison-Wesley, 1994.

[5] Brian W. Kernighan. PIC—a language for typesetting graphics. Software Practice and Experience, 12(1):1–21, 1982.

[6] Donald E. Knuth. The TEXbook. Addison-Wesley, 1984.

[7] Donald E. Knuth. The book. Addison-Wesley, 1986.

[8] Donald E. Knuth. Computer Modern Typefaces, volume A of Computers & Typesetting. Addison-Wesley, 1986.

[9] Leslie Lamport. L^{A}TEX—A Document Preparation System. Addison-Wesley, 1986.

[10] Leslie Lamport. L^{A}TEX—A Document Preparation System. Addison-Wesley, 2nd edition, 1994.

[11] Tomas Rokicki. DVIPS: A TEX Driver. Distributed with the dvips program found on CTAN archives.

[12] Kristoffer H. Rose. How to typeset pretty diagram arrows with TEX—design decisions used in XY-pic. In Jiří Zlatuška, editor, EuroTEX ’92—Proceedings of the 7th European TEX Conference, pages 183–190, Prague, Czechoslovakia, September 1992. Czechoslovak TEX Users Group.

[13] Kristoffer H. Rose. Typesetting diagrams with XY-pic: User’s manual. In Jiří Zlatuška, editor, EuroTEX ’92—Proceedings of the 7th European TEX Conference, pages 273–292, Prague, Czechoslovakia, September 1992. Czechoslovak TEX Users Group.

[14] Kristoffer H. Rose. XY-pic User’s Guide. DIKU, University of Copenhagen, Universitetsparken 1, DK–2100 København Ø, 3.0 edition, June 1995.

[15] Kristoffer H. Rose and Ross R. Moore. XY-pic complete sources with TEXnical commentary. not yet available, June 1995.

[16] Kristoffer H. Rose and Ross R. Moore. XY-pic Reference Manual. DIKU, University of Copenhagen, Universitetsparken 1, DK–2100 København Ø, 3.0 edition, June 1995.

[17] Michael D. Spivak. The Joy of TEX—A Gourmet Guide to Typesetting with the AMS-TEX Macro Package. American Mathematical Society, second edition, 1990.

630 BIBLIOGRAPHY [18] TUG Working Group TWG-TDS. A directory structure for TEX files version 0.98. URL, May

1995. Available with URL ftp://jasper.ora.com/pub/twg-tds/.

Index

!, 23 &, 342 ', 295 (), 23

(0), 23
(0,0), 545
(1), 23

*, 23, 295, 306, 313, 343, 357, 500, 554 **, 23, 305, 357

*stylechar@P@, xynecula.doc:106
*stylechar@|@, xyline.doc:114

+, 23 ,, 23, 302 -, 23, 295, 298 ., 23

.xyd, 69

/, 295, 299, 304, 313 //, 23 :, 23, 46 ::, 23 ;, 23 <, 23, 295, 300, 305 <>, 23 <>(.5), 295, 298 =, 23, 295, 297, 299, 300, 305, 306 >, 23, 295, 300, 305 ?, 23, 305 @, 23, 295, 354, 456 @!, 355, 456 @!0, 355 @!=, 355 @!C, 355 @!R, 355 @(, 41, 314, 456 @), 41 @*, 357, 456 @+, 41 @-, 41 @/, 314, 456 @1, 359 @<, 315, 456 @=, 41 @?, 315, 456 @@, 41 @C, 354 @H, 355 @L, 355 @M, 355 @R, 354 @W, 355 @`, 456 @i, 41

                                             \[, xy.doc:2538
                                             [.], 54

[=, 46, 59, 238, 245

[P:, 281 [], 54, 55

                                             [c], 54
                                             [d], 54
                                             [dvips], 11
                                             [l], 54
                                             [o], 54
                                             [r], 54
                                             [textures], 11
                                             [u], 54

\\, 342

^, 295, 301–303, 305, 456 _, 295, 301–303, 305, 456 `, 295, 301 `s, 446

                                             {\styletoks@}, xy.doc:3894
                                             {\xypatread@}, xytile.doc:264

|, 295, 456 |<<, 554

                                             |DOCMODE, xy.doc:70

~, 295

0, 20, 23, 456

1, 456 2, 456 3, 456 10, 215 11, 215 12, 215

A, 8

\a, xy.doc:2062

a, 23

\A@, xyidioms.doc:85
\ABfromdiag@, xyarrow.doc:849
\aboveDirection@, xy.doc:7265
\activatedriver@, xy.doc:6705
\activatedriversupport@, xy.doc:6708
\activateEM@, xyemtex.doc:132
\activatetips@, xytips.doc:128
\activateTPIC@, xytpic.doc:222

active characters, 4

\ad, xy.doc:2063

⟨add op⟩, 46

\add@m@keys, movie.cls:95
\addAND@, xy.doc:296
\addAT@, xy.doc:293
\addbeforeDrop@@, xyframe.doc:113
\addDASH@, xy.doc:299
\addDOLL@, xy.doc:295
\addDOT@, xy.doc:300
\addEQ@, xy.doc:302
\addFalse@, xy.doc:318
\addGT@, xy.doc:303
\addHASH@, xy.doc:294
\addLQ@, xy.doc:304
\addLT@, xy.doc:301
\ADDOP@, xy.doc:3595
\Addop@, xy.doc:3631
\ADDOP@minus, xy.doc:3612
\ADDOP@plus, xy.doc:3605
\addPLUS@, xy.doc:298
\addq@, xymatrix.doc:183
\addq@@, xymatrix.doc:188
\addq@i, xymatrix.doc:190
\addq@ii, xymatrix.doc:193
\addRQ@, xy.doc:297
\addtoarinit@, xyarrow.doc:1264
\addtoarlabels@, xyarrow.doc:1267
\addtocrv@, xycurve.doc:1931
\addtocrvpts@, xycurve.doc:2032
\addtoDrop@@, xyframe.doc:111
\addtostyletoks@, xy.doc:3895
\addtotoks@, xy.doc:724
\addTrue@, xy.doc:319
\adjust@forsegments@, xycurve.doc:4114
\adjustBaseOrient@, xyarc.doc:1388
\adjustbsplineedges@, xycurve.doc:4132

                                             \adjustLR@, xy.doc:3142
                                             \adjustmaxmin@, xycurve.doc:3744
                                             \adjustMinMaxcirc@, xycurve.doc:4479
                                             \adjustUD@, xy.doc:3148
                                             \afterADDOP, xy.doc:3591
                                             \afterADDOP , 53
                                             \afterADDOP@, xy.doc:3593
                                             \afteraliases@@, xyarrow.doc:1058
                                             \afterar@@, xyarrow.doc:1218
                                             \AfterBeginDocument, xyps-ps.doc:179
                                             \afterCIR@, xy.doc:6070
                                             \afterCIRDIAG@, xy.doc:6071
                                             \afterCIRorDIAG, xy.doc:6068
                                             \afterCOORD, xy.doc:1377
                                             \afterCOORD , 24
                                             \afterCOORD@, xy.doc:1382
                                             \afterCURVE, xycurve.doc:1978
                                             \afterCURVEaction@, xycurve.doc:274
                                             \afterDIAG, xy.doc:4297
                                             \afterDIRECTION@, xy.doc:4239
                                             \afterDIRECTIONorEMPTY, xy.doc:4233
                                             \aftergo, xyv2.doc:266
                                             \aftergo , 556
                                             \afterMORPHISM, xy2cell.doc:161
                                             \afterNODE, xygraph.doc:213
                                             \afterNODE@@, xygraph.doc:211
                                             \afternudge, xy2cell.doc:827
                                             \afterPATH, xyarrow.doc:187
                                             \afterPATH , 295
                                             \afterPATH@, xyarrow.doc:185
                                             \afterPLACE, xy.doc:2274
                                             \afterPLACE@, xy.doc:2291
                                             \afterPOS, xy.doc:1370

\afterPOS , 24, 65, 301

                                             \afterPOS@, xy.doc:1375
                                             \aftertwo@CELL, xy2cell.doc:1225
                                             \aftertwoCELL, xy2cell.doc:1226
                                             \afterVECTOR@, xy.doc:1391
                                             \afterVECTORorEMPTY, xy.doc:1384
                                             \afterVECTORorEMPTY , 24
                                             \ahook, xyv2.doc:366
                                             \ahook , 558
                                             \ahook@, xy.doc:5730
                                             \ahook@@, xy.doc:5731
                                             \AliasPattern, xytile.doc:286
                                             \aliaspattern@@, xytile.doc:316

allocation, 15

                                             \almostz@, xy.doc:659
                                             \alphanum, xypoly.doc:428

AMS-L^{A}TEX, 7, 67 AMS-TEX, 7

\apit , 554
\appendtoholder@, xyknot.doc:1092
\appendtoholder@@, xyknot.doc:1096
\appendtoholder@@@, xyknot.doc:1100
\appendtoholer@, xyknot.doc:1115
\applyFIFOstyle@, xy.doc:4162
\applyLIFOstyle@, xy.doc:4190
\ar, xyarrow.doc:1226

\ar , 59, 299, 307, 446

\ar@, xyarrow.doc:1248
\ar@anchor, xyarrow.doc:1270
\ar@curve, xyarrow.doc:1736
\ar@curve@, xyarrow.doc:1747
\ar@curveinout, xyarrow.doc:1712
\ar@curveinout@, xyarrow.doc:1710
\ar@curveslash, xyarrow.doc:1673
\ar@error, xyarrow.doc:1324
\ar@form, xyarrow.doc:1287
\ar@i, xyarrow.doc:1346
\ar@ii, xyarrow.doc:1354
\ar@iii, xyarrow.doc:1359
\ar@iv, xyarrow.doc:1365
\ar@modifiers, xyarrow.doc:1781
\ar@PATH, xyarrow.doc:1406
\ar@slashing, xyarrow.doc:1675
\ar@slide, xyarrow.doc:1796
\ar@style, xyarrow.doc:1332
\ar@upsidedown, xyarrow.doc:1807
\ar@x, xyarrow.doc:1377
\arafterPOS@, xyarrow.doc:1408
\arafterPOS@@, xyarrow.doc:1211
\arc@, xyarc.doc:91
\arc@i, xyarc.doc:123
\arcbisector, xyarc.doc:1013
\arcCenter@, xyarc.doc:1020
\arcCenter@i, xyarc.doc:1026
\arcmagic, xyarc.doc:890
\arcmagic@@, xyarc.doc:889
\arcomponent@, xyarrow.doc:1424
\arcomponent@@, xyarrow.doc:1215
\arcomponent@i, xyarrow.doc:1438
\arcomponent@ii, xyarrow.doc:1440
\arcomponent@x, xyarrow.doc:1468
\arcomponenttype@@, xyarrow.doc:1216
\arconn@, xyarrow.doc:1457
\arcScale@@, xyarc.doc:252
\arcScale@dim, xyarc.doc:262

                                             \ARCturn@, xyarc.doc:961
                                             \ARCturn@@, xyarc.doc:964
                                             \ARCturn@@@, xyarc.doc:970
                                             \arexit@@, xyarrow.doc:1213
                                             \arhead@@, xyarrow.doc:1208
                                             \arinit@@, xyarrow.doc:1212
                                             \arlabels@@, xyarrow.doc:1210
                                             \armodifiers@@, xyarrow.doc:1209
                                             array, 361
                                             \arraystretch, xy.doc:6152
                                             \arrow, xyv2.doc:599

arrow head, 312 arrow stem, 312 arrow tail, 312

                                             \arrowobject, xy2cell.doc:207
                                             \Arrowobject@, xy2cell.doc:208
                                             \Arrowtok@, xy2cell.doc:1447
                                             \arSAFE, xyarrow.doc:1228
                                             \arsavedPATHafterPOS@@, xyarrow.doc:1412
                                             \arstem@@, xyarrow.doc:1207
                                             \arstemprefix@@, xyarrow.doc:1205
                                             \artail@@, xyarrow.doc:1206
                                             \artip@, xyarrow.doc:1442
                                             \arvariant@@, xyarrow.doc:1204
                                             \astop, xyv2.doc:349
                                             \astop , 558
                                             \AtBeginDvi, xyidioms.doc:175
                                             \aTip, xyv2.doc:358
                                             \atip, xyv2.doc:353
                                             \aTip , 558
                                             \atip , 558
                                             \atip@, xy.doc:5621
                                             \atip@@, xy.doc:5630
                                             \atip@cm, xytips.doc:125
                                             \atip@xy, xytips.doc:49
                                             \aturn, xyv2.doc:369
                                             \aturn , 558
                                             \aturn@, xy.doc:5760
                                             \aturn@@, xy.doc:5761
                                             \AveryUNLIKELYc@ntr@lSEQUENCE@@, xyidioms.doc:98

B, 8

                                             \B@, xyidioms.doc:86
                                             \backwardSectors@, xyarc.doc:1255

banner, 13

                                             \basefromthebase@, xy.doc:1879
                                             \baseOrient@, xyarc.doc:325
                                             \bblacked@, xyframe.doc:469
                                             \belowDirection@, xy.doc:7282
                                             \bendPLACE@, xycurve.doc:1378

\bhook, xyv2.doc:367
\bhook , 558
\bhook@, xy.doc:5738
\bhook@@, xy.doc:5739
\blacked@, xyframe.doc:461
\blacked@@, xyframe.doc:474
\blacktriangle, xypoly.doc:587

⟨body of the option⟩, 91

\boxz@, xyidioms.doc:114
\bpit , 554
\bprevPLACE@, xycurve.doc:1379
\break@end, xycurve.doc:2933
\break@start, xycurve.doc:2869
\breakendcontinue@, xycurve.doc:2888
\breakendcontinue@i, xycurve.doc:2895
\breakendfound@, xycurve.doc:2923
\breakstartcontinue@, xycurve.doc:2802
\breakstartcontinue@i, xycurve.doc:2808
\breakstartfound@, xycurve.doc:2821
\bsegment@@i, xycurve.doc:4194
\bsegment@@ii@i, xycurve.doc:4227
\bsegment@@ii@iii, xycurve.doc:4178
\bsegment@@iv, xycurve.doc:4204
\bsegment@@y@iv, xycurve.doc:4237
\bsegment@i, xycurve.doc:4260
\bsegment@i@iv, xycurve.doc:4276
\bsegment@z, xycurve.doc:4298
\bsegment@z@i, xycurve.doc:4314
\bsplinecancel@, xycurve.doc:3452
\bsplineconnect@, xycurve.doc:4012
\bsplined@, xycurve.doc:4110
\bsplined@@, xycurve.doc:4002
\bsplineiiiconnect@, xycurve.doc:3960
\bsplineivconnect@, xycurve.doc:3968
\bsplinesegment@, xycurve.doc:4328
\bsplinesegment@iii, xycurve.doc:4351
\bsplinesegment@iv, xycurve.doc:4377
\bstartPLACE@, xycurve.doc:1377
\bstop, xyv2.doc:350
\bstop , 558
\bthisPLACE@, xycurve.doc:1380
\bTip, xyv2.doc:359
\btip, xyv2.doc:354
\bTip , 558
\btip , 558
\btip@, xy.doc:5622
\btip@@, xy.doc:5631
\btip@cm, xytips.doc:126
\btip@xy, xytips.doc:50

                                             \bturn, xyv2.doc:370
                                             \bturn , 558
                                             \bturn@, xy.doc:5766
                                             \bturn@@, xy.doc:5767
                                             \buildcircle@, xycurve.doc:4604

C, 23, 40 c, 21 c, 23

                                             \c@poly@count, xynecula.doc:107
                                             \Calong@@, xy.doc:7930
                                             \cancelPSdict@, xyps-ps.doc:489

cartesian coordinate system, 21

category code, 4

                                             \Cbreak@@, xy.doc:7932
                                             \CCintercept@@, xycurve.doc:1664

CD, 23

                                             \cD, xyv2.doc:199

\cD , 556

                                             \centerobject@, xy.doc:3731
                                             \cfromcontrols@, xyarc.doc:508
                                             \cfromid@, xy.doc:2896
                                             \cfromp@, xy.doc:1629
                                             \cfroms@, xy.doc:2681
                                             \cfromthec@, xy.doc:1660
                                             \cfromthep@, xy.doc:1664
                                             \cH, xyv2.doc:200

\cH , 556

                                             \change@oxy@, xy.doc:860
                                             \changedriver@single, xy.doc:6690
                                             \checkafterCURVE@, xycurve.doc:710
                                             \checkcrvtilde@, xycurve.doc:947
                                             \checkendcurve@, xycurve.doc:680
                                             \checkEqOpen@, xyarc.doc:1128
                                             \checkfoundEbreak@, xycurve.doc:2850
                                             \checkfoundSbreak@, xycurve.doc:2831
                                             \checkgroupbreak@, xyknot.doc:1069
                                             \checkmodmap@, xy2cell.doc:494
                                             \checkoverlap@@, xy.doc:8044
                                             \checkpolytok@, xypoly.doc:519
                                             \checkRadOpen@, xyarc.doc:215
                                             \checkslidemore@, xycurve.doc:1188
                                             \checksplinefind@, xycurve.doc:1315
                                             \checkstartDirection@, xyarc.doc:1303
                                             \checkXy@rules@, xy.doc:5172
                                             \checkxyPScolor@, xyps-c.doc:109
                                             \checkxyPScolor@@, xyps-c.doc:108
                                             \checkXyStyle@, xy.doc:3970
                                             \checkZeroEdge@, xy.doc:3154
                                             \chooseangleinterval@, xy.doc:2038

\Cintercept@@, xy.doc:7931

⟨cir⟩, 85, 88

\cir, xy.doc:5986

\cir , 88, 549

\CIR@, xy.doc:6073
\cir@, xy.doc:5989
\CIR@@, xy.doc:6075
\cir@cir, xy.doc:6000
\cir@diag, xy.doc:6012
\cir@i, xy.doc:6023
\CIRacw@, xy.doc:6273
\cirbuild@, xy.doc:6135
\circhar@, xy.doc:6141
\circhar@@, xy.doc:6145
\circleArc@, xyarc.doc:991
\circleCentre@, xy.doc:7441
\circlecentredEdge@, xy.doc:7477
\circlecentredInner@, xy.doc:7491
\circlecentredOuter@, xy.doc:7495
\circlecentredUnder@, xy.doc:7481
\circleCorner@, xycurve.doc:4715
\Circled, xyv2.doc:495
\circled, xyv2.doc:494
\Circled , 560
\circled , 560
\circled@, xyframe.doc:518
\circled@x@, xyframe.doc:526
\circled@x@@, xyframe.doc:528
\circledobjects@, xycurve.doc:4557
\circleEdge, xy.doc:7420
\circleEdge@, xy.doc:7425
\circleInner@, xy.doc:7455
\circleOuter@, xy.doc:7461
\circleProp@, xy.doc:7431

circles, 14

\circlescale@, xy.doc:7489
\circletemplate@, xycurve.doc:4646
\circleUnder@, xy.doc:7437
\Circmagic, xycurve.doc:4445
\Circmagic@@, xycurve.doc:4444
\CIRcw@, xy.doc:6284
\CIRfull@, xy.doc:6125
\CIRhi@@, xy.doc:6113
\CIRin@@, xy.doc:6064
\CIRlo@@, xy.doc:6112
\CIRorient@@, xy.doc:6066
\CIRout@@, xy.doc:6065
\cirrestrict@@, xy.doc:6168
\CIRtest@@, xy.doc:6111

                                             \CIRtest@inside, xy.doc:6295
                                             \CIRtest@outside, xy.doc:6298

CL, 23

                                             \cL, xyv2.doc:197

\cL , 556

                                             \Clast@@, xy.doc:7933
                                             \clearcurve, xycurve.doc:1847
                                             \clearq@, xymatrix.doc:179
                                             \clearsearchflag@, xycurve.doc:716

cm, 215

                                             \cmerge@, xy.doc:1785
                                             \cmergethec@, xy.doc:1782
                                             \codeof, xy.doc:226
                                             \codeof , 4
                                             \codeof@, xy.doc:227
                                             \Col, xymatrix.doc:160
                                             \Col , 359
                                             \colorxy, xyps-ps.doc:271

column spacing, 354

                                             \comma@@, xy.doc:1591

⟨command⟩, 65

                                             \CompileAllDiagrams, xyv2.doc:797
                                             \CompileFixPoint, xy.doc:4821
                                             \CompileFixPoint , 67
                                             \CompileMatrices, xymatrix.doc:283
                                             \compilename@@, xy.doc:4743
                                             \CompilePrefix, xy.doc:4734
                                             \CompilePrefix , 67

compiling, 67 ⟨composite⟩, 46

                                             \composite, xy.doc:3319
                                             \composite , 46, 50, 82
                                             \composite@, xy.doc:3321
                                             \composite@i, xy.doc:3328
                                             \composite@ii, xy.doc:3335
                                             \composite@iii, xy.doc:3337
                                             \composite@iv, xy.doc:3347
                                             \composite@x, xy.doc:3352
                                             \compositemap, xy2cell.doc:1249
                                             \compositemap@, xy2cell.doc:273
                                             \compositemapp, xy2cell.doc:1263
                                             \computeLeftUpness@, xy.doc:3360
                                             \connect, xy.doc:4534

connect, 20

                                             \connect , 65
                                             \connect@, xy.doc:2140
                                             \Connect@@, xy.doc:3226
                                             \connect@iii, xyv2.doc:615
                                             \connect@Twocell, xy2cell.doc:1411

\connectDrop@@, xy.doc:2154

connection methods, 111

\connectobjectbox@@, xy.doc:2153
\connectpostXY@style@, xy.doc:2156
\connectpreXY@style@, xy.doc:2155
\connectRest@@, xy.doc:2158
\connectRestore@, xy.doc:2171
\connectStore@, xy.doc:2160

context, 17

\controlpts, xycurve.doc:1961, xycurve.doc:1989
\convertframed, xyv2.doc:497
\convertframed@i, xyv2.doc:499
\convexhull, xycurve.doc:1962, xycurve.doc:1991
\Conway, xyknot.doc:1231

⟨coord⟩, 23, 280

\COORD@, xy.doc:1513, xynecula.doc:74

copyleft, i copyright, i

\corn@@, xyframe.doc:380
\corn@x@, xyframe.doc:374
\corn@x@@, xyframe.doc:378

⟨corner⟩, 23

\CORNER@, xy.doc:1443
\CORNER@i, xy.doc:1450
\CORNER@ii, xy.doc:1467
\cosDirection, xy.doc:685
\cosFivePIon, xypoly.doc:697
\cosFourPIon, xypoly.doc:688
\cosPIon, xypoly.doc:663
\cosThreePIon, xypoly.doc:679
\cosTwoPIon, xypoly.doc:670
\count@@, xyidioms.doc:197, xyidioms.doc:200
\count@@@, xyidioms.doc:198, xyidioms.doc:201
\cplusthec@, xy.doc:1694

CR, 23

\cR, xyv2.doc:198

\cR , 556

\Creset@@, xy.doc:7925
\croplattice, xyweb.doc:190
\crv, xycurve.doc:264
\crv@, xycurve.doc:267
\crv@cnt@, xycurve.doc:84
\crv@getStyles@, xycurve.doc:781
\crv@noobject, xycurve.doc:354
\crv@normaltemplate, xycurve.doc:314
\crv@othertemplate, xycurve.doc:315
\crv@saveStyles@, xycurve.doc:777
\crv@special, xycurve.doc:391
\crv@specialtemplate@, xycurve.doc:390

                                             \crv@specialtemplate@@, xycurve.doc:316
                                             \crvconnect@@, xycurve.doc:968
                                             \crvi, xycurve.doc:324
                                             \crvi , 314
                                             \crvobjects@, xycurve.doc:605
                                             \crvpts@, xycurve.doc:86
                                             \crvresetbreaks@, xycurve.doc:1366
                                             \crvs, xycurve.doc:323
                                             \crvs@, xycurve.doc:326
                                             \crvSTYLE@@, xycurve.doc:352
                                             \crvXY@post@, xycurve.doc:775
                                             \crvXY@pre@, xycurve.doc:774
                                             \Cshavec@@, xy.doc:7927
                                             \Cshavep@@, xy.doc:7926
                                             \cskew@, xy.doc:1740
                                             \cskewthec@, xy.doc:1737
                                             \Cslidec@@, xy.doc:7929
                                             \Cslidep@@, xy.doc:7928
                                             \csname , 4
                                             \csp@, xy.doc:700
                                             \ctipEdge@, xy.doc:5595

CU, 23

                                             \cubic@start@, xycurve.doc:3926
                                             \cubicARC@, xyarc.doc:925
                                             \cubicARC@i, xyarc.doc:914
                                             \cubicARCcontrols@@, xyarc.doc:405
                                             \cubicCircleControls@@, xycurve.doc:4496
                                             \cubiccoarsedir@, xycurve.doc:3868
                                             \cubicconnect@, xycurve.doc:3718
                                             \cubicDadvance@@@, xycurve.doc:3823
                                             \cubicdecast@, xycurve.doc:3795
                                             \cubiced@, xycurve.doc:3939
                                             \cubiced@@, xycurve.doc:3832
                                             \cubicfinedir@, xycurve.doc:3851
                                             \cubicIadvance@, xycurve.doc:1519
                                             \cubicinfo@, xycurve.doc:3894
                                             \cubicinsidehull@, xycurve.doc:1796
                                             \cubicIpt@, xycurve.doc:1517
                                             \cubicoutsidehull@, xycurve.doc:1789
                                             \cubicoutsidehull@i, xycurve.doc:1800
                                             \cubicoutsidehull@ii, xycurve.doc:1807
                                             \cubicplot@maybe, xycurve.doc:3825
                                             \cubicplot@maybeii, xycurve.doc:3827
                                             \cubicrec@, xycurve.doc:3819
                                             \cubicreverse@, xycurve.doc:3906
                                             \cubicreverse@@, xycurve.doc:3909
                                             \cubicsegment@, xycurve.doc:3721
                                             \cubicsetparams@, xycurve.doc:3933
                                             \cubictestcvxhull@, xycurve.doc:1612

\cubictestcvxhull@i, xycurve.doc:1618

current object style, 46, 56

\curve, xycurve.doc:256
\curve@check, xyarrow.doc:1759
\curveobject, xy2cell.doc:1087
\curveSTYLE@, xycurve.doc:273
\cuspidalARC@, xyarc.doc:931
\cv@end, xycurve.doc:1919
\cv@restore, xycurve.doc:1920
\cv@start, xycurve.doc:1918
\czeroEdge@, xy.doc:1123

D, 20 D, 23, 40

\D@c, xy.doc:614
\D@p, xy.doc:622
\d@X, xy.doc:673
\d@Y, xy.doc:674

D_{c}, 21 D_{p}, 21

\darken@, movie.cls:271
\dash@, xy.doc:5498
\dasharstem@, xyarrow.doc:1320
\dashcorner@, xycurve.doc:4712
\dashcorner@@, xyframe.doc:390
\dashcorntemp@@, xycurve.doc:4706
\Dashed, xyv2.doc:307
\dashed, xyv2.doc:306
\Dashed , 557
\dashed , 557
\dashedcircle@, xycurve.doc:4665
\dashedSpread@, xy.doc:5514

dashes, 14

\dashframed, xyv2.doc:505
\dashframed , 560
\dashhfillchar, xyframe.doc:413
\dashsquiggle@, xy.doc:5529
\dashsquiggledSpread@, xy.doc:5540
\dashvfillchar, xyframe.doc:414
\dbldottedcircle@, xycurve.doc:4669
\dbraced, xyframe.doc:724
\Dc, xyv2.doc:215

\Dc , 556

\dcurveObject@, xy2cell.doc:1091
\Ddashed, xyv2.doc:308
\Ddashed , 557
\dDirection@, xy.doc:7073
\Ddotted, xyv2.doc:312
\Ddotted , 557
\ddtol, xyv2.doc:696

                                             \ddtor, xyv2.doc:697

⟨decor⟩, 65 decoration, 21

                                             \def , 3
                                             \defarstem@, xyarrow.doc:1313

default entry, 357

                                             \defaultinstallps@, xyps-ps.doc:210
                                             \defaultlatticebody, xyweb.doc:267
                                             \defaultpattfile@, xytile.doc:265
                                             \define , 555

define ⟨shape⟩, 36

                                             \definemorphism, xyv2.doc:628
                                             \definemorphism , 561
                                             \definesupermorphism, xy2cell.doc:163
                                             \deflatticebody@, xyweb.doc:266

⟨diag⟩, 46

                                             \DIAG@, xy.doc:4299
                                             \DIAG@@, xy.doc:4307
                                             \DIAG@@@, xy.doc:4313
                                             \diagram, xyv2.doc:536
                                             \diagram , 561
                                             \diagram@, xyv2.doc:538
                                             \diagram@@, xyv2.doc:552
                                             \diagramcompileto, xyv2.doc:769
                                             \diagramnocompile, xyv2.doc:793
                                             \dimen@half, xycurve.doc:2251
                                             \dimen@nth, xycurve.doc:2256

dimension registers, 7

                                             \dir, xy.doc:5035

\dir , 70, 72, 82, 312–314

                                             dir0{(}, xy.doc:5713
                                             dir0{)}, xy.doc:5719
                                             dir0{*}, xy.doc:5912
                                             dir0{+}, xy.doc:5896
                                             dir0{--}, xy.doc:5494
                                             dir0{-}, xy.doc:5128
                                             dir0{.}, xy.doc:5326
                                             dir0{//}, xy.doc:5907
                                             dir0{/}, xy.doc:5903
                                             dir0{<<}, xy.doc:5837
                                             dir0{<}, xy.doc:5617
                                             dir0{>>|}, xy.doc:5862
                                             dir0{>>}, xy.doc:5829
                                             dir0{>|}, xy.doc:5856
                                             dir0{>}, xy.doc:5611
                                             dir0{o}, xy.doc:5917
                                             dir0{x}, xy.doc:5900
                                             dir0{|-}, xy.doc:5890
                                             dir0{|<<}, xy.doc:5877

dir0{|<}, xy.doc:5868
dir0{||}, xy.doc:5850
dir0{|}, xy.doc:5690
dir0{}, xy.doc:5072
dir0{~}, xy.doc:5399
dir0{~~}, xy.doc:5526
dir1{(}, xy.doc:5710
dir1{)}, xy.doc:5716
dir1{--}, xy.doc:5491
dir1{-}, xy.doc:5125
dir1{..}, xy.doc:5547
dir1{.}, xy.doc:5323
dir1{<<}, xy.doc:5832
dir1{<}, xy.doc:5614
dir1{>>|}, xy.doc:5859
dir1{>>}, xy.doc:5824
dir1{>|}, xy.doc:5853
dir1{>}, xy.doc:5608
dir1{|-}, xy.doc:5880
dir1{|<<}, xy.doc:5871
dir1{|<}, xy.doc:5865
dir1{||}, xy.doc:5840
dir1{|}, xy.doc:5682
dir1{}, xy.doc:5073
dir1{~}, xy.doc:5396
dir1{~~}, xy.doc:5523
dir2{--}, xy.doc:5492
dir2{-}, xy.doc:5126
dir2{..}, xy.doc:5548
dir2{.}, xy.doc:5324
dir2{<<}, xy.doc:5835
dir2{<}, xy.doc:5642
dir2{>>|}, xy.doc:5860
dir2{>>}, xy.doc:5827
dir2{>|}, xy.doc:5854
dir2{>}, xy.doc:5641
dir2{|-}, xy.doc:5886
dir2{|<<}, xy.doc:5873
dir2{|<}, xy.doc:5866
dir2{||}, xy.doc:5846
dir2{|}, xy.doc:5687
dir2{}, xy.doc:5076
dir2{~}, xy.doc:5397
dir2{~~}, xy.doc:5524
dir3{--}, xy.doc:5493
dir3{-}, xy.doc:5127
dir3{..}, xy.doc:5549
dir3{.}, xy.doc:5325
dir3{<<}, xy.doc:5836

                                             dir3{<}, xy.doc:5658
                                             dir3{>>|}, xy.doc:5861
                                             dir3{>>}, xy.doc:5828
                                             dir3{>|}, xy.doc:5855
                                             dir3{>}, xy.doc:5657
                                             dir3{|-}, xy.doc:5888
                                             dir3{|<<}, xy.doc:5875
                                             dir3{|<}, xy.doc:5867
                                             dir3{||}, xy.doc:5848
                                             dir3{|}, xy.doc:5688
                                             dir3{}, xy.doc:5077
                                             dir3{~}, xy.doc:5398
                                             dir3{~~}, xy.doc:5525
                                             \dir@, xy.doc:5042
                                             \dir@i, xy.doc:5037
                                             \dir@ii, xy.doc:5040
                                             dir^{'}, xy.doc:5754
                                             dir^{(}, xy.doc:5711
                                             dir^{)}, xy.doc:5717
                                             dir^{<<}, xy.doc:5833
                                             dir^{<}, xy.doc:5615
                                             dir^{>>}, xy.doc:5825
                                             dir^{>}, xy.doc:5609
                                             dir^{`}, xy.doc:5757
                                             dir^{|-}, xy.doc:5882
                                             dir^{||}, xy.doc:5842
                                             dir^{|}, xy.doc:5683
                                             dir^{}, xy.doc:5074
                                             dir_{'}, xy.doc:5755
                                             dir_{(}, xy.doc:5712
                                             dir_{)}, xy.doc:5718
                                             dir_{<<}, xy.doc:5834
                                             dir_{<}, xy.doc:5616
                                             dir_{>>}, xy.doc:5826
                                             dir_{>}, xy.doc:5610
                                             dir_{`}, xy.doc:5758
                                             dir_{|-}, xy.doc:5884
                                             dir_{||}, xy.doc:5844
                                             dir_{|}, xy.doc:5685
                                             dir_{}, xy.doc:5075
                                             \Direction, xy.doc:681

⟨direction⟩, 46 direction, 16

                                             \Direction , 81, 82
                                             \DIRECTION@, xy.doc:4242
                                             \DIRECTION@group, xy.doc:4381
                                             \DIRECTION@i, xy.doc:4414
                                             \DIRECTION@open, xy.doc:4253
                                             \DIRECTION@v, xy.doc:4356

directional, 15

\DirectionChar, xy.doc:688
\DirectionChar , 80
\Directionfromdiag@, xy.doc:4324
\DirectionfromtheDirection@, xy.doc:6997
\Directiontest@@, xy.doc:7021
dir{ }, xy.doc:5079
dir{(}, xy.doc:5714
dir{)}, xy.doc:5720
dir{*}, xy.doc:5909
dir{+}, xy.doc:5894
dir{--}, xy.doc:5495
dir{-}, xy.doc:5129
dir{..}, xy.doc:5550
dir{.}, xy.doc:5327
dir{//}, xy.doc:5905
dir{/}, xy.doc:5902
dir{::}, xy.doc:5551
dir{:}, xy.doc:5328
dir{<<}, xy.doc:5838
dir{<}, xy.doc:5618
dir{==}, xy.doc:5496
dir{=}, xy.doc:5130
dir{>>|}, xy.doc:5863
dir{>>}, xy.doc:5830
dir{>|}, xy.doc:5857
dir{>}, xy.doc:5612
dir{o}, xy.doc:5914
dir{x}, xy.doc:5898
dir{|-}, xy.doc:5891
dir{|<<}, xy.doc:5878
dir{|<}, xy.doc:5869
dir{|=}, xy.doc:5892
dir{||}, xy.doc:5851
dir{|}, xy.doc:5691
dir{}, xy.doc:5070
dir{~}, xy.doc:5400
dir{~~}, xy.doc:5527
\dlDirection@, xy.doc:7068
\DN@, xyidioms.doc:109
\DNii@, xyidioms.doc:110
\do, xy.doc:6837
\dobspline@, xycurve.doc:4017
\docecho@, xy.doc:93
\docfinish@, xy.doc:94
\doCircleArc@@, xyarc.doc:437
\doCircleArc@@@, xyarc.doc:447
\doCircleArcs@, xyarc.doc:548
\doCircleQuadrant@@, xycurve.doc:4512

                                             \doCircleQuadrant@@@, xycurve.doc:4522
                                             \doCircleSectors@, xyarc.doc:1199
                                             \docm@, xy.doc:81
                                             \docm@i, xy.doc:82
                                             \docm@ii, xy.doc:83
                                             \docm@iii, xy.doc:85
                                             \docm@iv, xy.doc:90
                                             DOCMODE, 1, 7
                                             \documentclass , 11
                                             \doEllipseSectors@, xyarc.doc:1284
                                             \doii, xy.doc:6842
                                             \doMergeBoth@@, xyarc.doc:489
                                             \doMergeBothArc@, xyarc.doc:483
                                             \doMergeEnd@@@, xyarc.doc:458
                                             \doMergeEndArc@, xyarc.doc:500
                                             \doMergeEndArc@@, xyarc.doc:452
                                             \doMergeStart@@, xyarc.doc:474
                                             \doMergeStartArc@, xyarc.doc:468
                                             \dontleave@, xy.doc:773
                                             \doPSspecialRotate@@, xyps-r.doc:143
                                             \doShow, xy.doc:6741
                                             \doskewEllipse@, xyarc.doc:1333
                                             \dosolidcircle@, xycurve.doc:4535
                                             \dosolidcircle@@, xycurve.doc:4543
                                             \doSpecialRotate@, xyrotate.doc:359
                                             \dosplineplotpt@, xycurve.doc:3429
                                             \doSplineSegment@, xycurve.doc:4848
                                             \doSplineStraight@, xycurve.doc:4844
                                             \doStraightArc@@, xyarc.doc:504
                                             \dotcorner@, xycurve.doc:4710
                                             \dotcorner@@, xyframe.doc:389
                                             \dotcorntemp@@, xycurve.doc:4708
                                             \dotframed, xyv2.doc:504
                                             \dotframed , 560
                                             \Dotted, xyv2.doc:311
                                             \dotted, xyv2.doc:310
                                             \Dotted , 557
                                             \dotted , 557
                                             \dottedcircle@, xycurve.doc:4659
                                             \dottedSpread@, xy.doc:5366
                                             \dottedSpread@i, xy.doc:5374
                                             \dottedwith, xyv2.doc:314
                                             \dottedwith , 557
                                             \double@, xy.doc:5466
                                             \doublecircle@, xycurve.doc:4647
                                             \Dp, xyv2.doc:222

\Dp , 556

                                             \dparenthesized, xyframe.doc:821
                                             \draw@polyframe, xynecula.doc:146

\draw@polygon, xynecula.doc:213
\drDirection@, xy.doc:7079

⟨driver⟩, 92

\driverextensioncomplain@, xy.doc:6920
\Drop, xyv2.doc:272
\drop, xy.doc:4531
\Drop , 557
\drop , 65
\drop@, xy.doc:2104
\Drop@@, xy.doc:3225
\drop@Twocell, xy2cell.doc:1409
\dropentry@, xymatrix.doc:659
\droplabel@, xyarrow.doc:944
\Droprule@, xy.doc:5303
\droptwocelldrop@, xy2cell.doc:376
\droptwocelllabel@, xy2cell.doc:367
\droptwocelllabel@@, xy2cell.doc:368
\droptwocelltext@, xy2cell.doc:374
\dsize , 555
\dumpPSdict, xyps.doc:663
\dumpPSdict {<filename>}, 260
\dumpPSdict@@, xyps-ps.doc:158
\dumpsizefile, movie.cls:284
\dvidrv@@, xydvidrv.doc:42
\dvidrvEmTeX@, xydvidrv.doc:59
\dvidrvEmTeX@@, xydvidrv.doc:58
\dvidrvLine@, xydvidrv.doc:67
\dvidrvLine@@, xydvidrv.doc:66
\dvimessage@, xy.doc:6929
\dvips@, xyps.doc:270
\dvips@@, xydvips.doc:42
\dvips@Color@, xydvips.doc:71
\dvipsColor@@, xydvips.doc:85
\dvipsCrayola@, xydvips.doc:119
\dvipsCrayola@@, xydvips.doc:117
\dvipsCurrpt@, xydvips.doc:200
\dvipsCurrpt@@, xydvips.doc:201
\dvipsDict@, xydvips.doc:169
\dvipsEM@, xydvips.doc:290
\dvipsEM@@, xydvips.doc:289
\dvipsFrames@, xydvips.doc:257
\dvipsFrames@@, xydvips.doc:255
\dvipsInclude@, xydvips.doc:170
\dvipsLine@, xydvips.doc:244
\dvipsLine@@, xydvips.doc:242
\dvipsMacro@, xydvips.doc:168
\dvipsone@, xyps.doc:274
\dvipsPS@, xydvips.doc:212
\dvipsPS@@, xydvips.doc:138

                                             \dvipsPS@unload, xydvips.doc:140
                                             \dvipsPStypes@, xydvips.doc:151
                                             \dvipsRaw@, xydvips.doc:171
                                             \dvipsRotate@, xydvips.doc:224
                                             \dvipsRotate@@, xydvips.doc:222
                                             \dvipsRotScale@, xydvips.doc:231
                                             \dvipsSpecial@, xydvips.doc:167
                                             \dvipsTiles@, xydvips.doc:270
                                             \dvipsTiles@@, xydvips.doc:268
                                             \dvipsTPIC@, xydvips.doc:282
                                             \dvipsTPIC@@, xydvips.doc:281
                                             \DVITOPS, xydvitops.doc:32
                                             \dvitops@, xyps.doc:273
                                             \dvitops@@, xydvitops.doc:41
                                             \dvitops@Color@, xydvitops.doc:74
                                             \dvitopsBegin@, xydvitops.doc:179
                                             \dvitopsColor@@, xydvitops.doc:72
                                             \dvitopsColor@x, xydvitops.doc:183
                                             \dvitopsCrayon@, xydvitops.doc:136
                                             \dvitopsCrayon@@, xydvitops.doc:135
                                             \dvitopsCurrpt@, xydvitops.doc:208
                                             \dvitopsDict@, xydvitops.doc:175
                                             \dvitopsEnd@, xydvitops.doc:180
                                             \dvitopsFrames@, xydvitops.doc:286
                                             \dvitopsFrames@@, xydvitops.doc:284
                                             \dvitopsInclude@, xydvitops.doc:176
                                             \dvitopsLine@, xydvitops.doc:273
                                             \dvitopsLine@@, xydvitops.doc:271
                                             \dvitopsMacro@, xydvitops.doc:174
                                             \dvitopsOrigin@, xydvitops.doc:178
                                             \dvitopsPS@, xydvitops.doc:216
                                             \dvitopsPS@@, xydvitops.doc:143
                                             \dvitopsPS@unload, xydvitops.doc:145
                                             \dvitopsPStypes@, xydvitops.doc:157
                                             \dvitopsRaw@, xydvitops.doc:177
                                             \dvitopsRotate@, xydvitops.doc:230
                                             \dvitopsRotate@@, xydvitops.doc:228
                                             \dvitopsRotate@x, xydvitops.doc:181
                                             \dvitopsRotScale@, xydvitops.doc:237
                                             \dvitopsSpecial@, xydvitops.doc:173
                                             \dvitopsTiles@, xydvitops.doc:297
                                             \dvitopsTPIC@, xydvitops.doc:310
                                             \dvitopsTPIC@@, xydvitops.doc:308
                                             \dvitopsTransform@x, xydvitops.doc:182
                                             \dvitype@, xyps-ps.doc:96
                                             \dX, xyv2.doc:226
                                             \dY, xyv2.doc:227

E, 23, 40, 103

                                             \eat@, xyidioms.doc:106

\edef , 22

Edge, 20 Edge_{c}, 21 Edge_{p}, 21

\Edge@c, xy.doc:617
\Edge@p, xy.doc:625
\EdgefromtheEdge@, xyframe.doc:104
\ellipA, xyimport.doc:56
\ellipse, xyarc.doc:62
\ellipse@whichdblfrm@, xyframe.doc:589
\ellipse@whichfrm@, xyframe.doc:580
\ellipseArc@, xyarc.doc:393
\ellipsecentredEdge@, xy.doc:7506
\ellipsecentredInner@, xy.doc:7543
\ellipsecentredOuter@, xy.doc:7534
\ellipsecentredUnder@, xy.doc:7522
\ellipsed@, xyframe.doc:641
\ellipsed@e@, xyframe.doc:633
\ellipsed@ei@, xyframe.doc:615
\ellipsed@i, xyframe.doc:649
\ellipsed@i@, xyframe.doc:598
\ellipsed@x@, xyframe.doc:652
\ellipsed@x@@, xyframe.doc:654
\ellipsedashframed@, xyframe.doc:660
\ellipsedotframed@, xyframe.doc:658
\ellipseEdge@, xy.doc:7603
\ellipseInner@, xy.doc:7671
\ellipseOuter@, xy.doc:7669
\ellipseScale@, xyarc.doc:281
\ellipseScale@dim, xyarc.doc:277
\ellipsesolidframed@, xyframe.doc:656
\ellipticARC@, xyarc.doc:922
\ellsave@, xyarc.doc:1158
\EMalternative@, xyemtex.doc:105
\emptyspline@, xycurve.doc:3365
\endcrv@, xycurve.doc:742
\endcrv@@, xycurve.doc:276
\endcsname , 4
\endcurve, xycurve.doc:1982
\enddiagram , 561
\endellipse@@, xyarc.doc:65
\endgraph, xygraph.doc:172
\endpatread@, xytile.doc:301
\endxy, xy.doc:1142

\endxy , 19–21, 64

\endxycurve@, xycurve.doc:1979
\endXYdict@, xyps-ps.doc:470

enter, 17

\enter@, xy.doc:767

entry height, 355 entry margin, 355 entry width, 355

                                             \entry@, xymatrix.doc:607
                                             \entry@@, xymatrix.doc:614
                                             \entry@@i, xymatrix.doc:621
                                             \entry@@norm, xymatrix.doc:644
                                             \entry@@star, xymatrix.doc:625
                                             \entry@@star@i, xymatrix.doc:628
                                             \entry@@star@ii, xymatrix.doc:635
                                             \entrybox, xymatrix.doc:1192
                                             \entrymodifiers, xymatrix.doc:1187
                                             \entrymodifiers , 357
                                             \entrymodifiers@, xymatrix.doc:1190
                                             Error, 14

⟨escape⟩, 458

eu, 215

                                             \everyentry, xymatrix.doc:1243
                                             \everyentry , 359
                                             \everyentry@, xymatrix.doc:1246
                                             \everyxy, xy.doc:1127
                                             \everyxy@@, xy.doc:1130

execution, 19

                                             \expandbeforenext@, xynecula.doc:52

extension, 92 extents, 20

                                             \extractparameterm@, xymovie.doc:64

e|, 280

                                             \F, movie.cls:238, xymovie.doc:80
                                             \F@, movie.cls:241

file header, 1

                                             \filepattern@@, xytile.doc:310
                                             \Filled, xyv2.doc:514
                                             \filled, xyv2.doc:508
                                             \filled@, xyframe.doc:945
                                             \filled@Circle@, xyframe.doc:991
                                             \filled@Ellipse@, xyframe.doc:992
                                             \filled@Oval@, xyframe.doc:990
                                             \filled@Rectangle@, xyframe.doc:989
                                             \filled@Region@, xyframe.doc:981
                                             \filledCircle@@, xyframe.doc:971
                                             \filledCircle@PS, xyps-f.doc:195
                                             \filledCircle@TPIC@@, xytp-f.doc:242
                                             \filledEllipse@@, xyframe.doc:972
                                             \filledEllipse@PS, xyps-f.doc:197
                                             \filledEllipse@TPIC@@, xytp-f.doc:244
                                             \filledOval@@, xyframe.doc:973
                                             \filledOval@PS, xyps-f.doc:199
                                             \filledOval@TPIC@@, xytp-f.doc:245

\filledRectangle@@, xyframe.doc:970
\filledRectangle@PS, xyps-f.doc:193
\filledRectangle@TPIC@@, xytp-f.doc:238
\findbreakwarning@, xycurve.doc:2797
\findIsegment@, xycurve.doc:1528
\findIsegment@i, xycurve.doc:1537
\findIsegment@ii, xycurve.doc:1541
\findIsegment@x, xycurve.doc:1545
\findIsegment@y, xycurve.doc:1550
\finishq@, xymatrix.doc:197
\firstbspline@, xycurve.doc:4024
\firstPS@, xyps-ps.doc:137
\firstPS@@, xyps-ps.doc:139
\firstsplinepoint@, xycurve.doc:2405

fixed grid, 355

\fixedDirection@, xy.doc:7112
\fixedRadiusArc@, xyarc.doc:228
\fixedRadiusArc@i, xyarc.doc:232
\flagwarn@, xycurve.doc:717

fonts, 14

\forceload@XYdict, xyps-ps.doc:613

format dependencies, 7 formats, 7

\forwardSectors@, xyarc.doc:1226
\foundpattern@, xytile.doc:314
\Fr, movie.cls:239, xymovie.doc:81

fraction computation, 18

\frame@compute, movie.cls:216
\frame@emph@, xyframe.doc:940
\frame@emph@@, xyframe.doc:943
\frame@emph@PS, xyps-f.doc:202
\frame@fill@, xyframe.doc:939
\frame@fill@@, xyframe.doc:942
\Framed, xyv2.doc:492
\framed, xyv2.doc:491
\Framed , 560
\framed , 560
\framed@, xyframe.doc:284
\framed@@, xyframe.doc:330
\framed@body@, xyframe.doc:343
\framed@body@@, xyframe.doc:358
\framesetthick@, xyframe.doc:287
\framesetthick@line, xyframe.doc:305
\framezerodot@@, xyframe.doc:265
french.sty, 4
\frm, xyframe.doc:63

\frm , 40, 197

\frm {**}, 209
\frm {*}, 209

                                             frm2{-e}, xyframe.doc:573
                                             frm2{.e}, xyframe.doc:572
                                             \frm@, xyframe.doc:86
                                             \frm@dashh@@, xyframe.doc:406
                                             \frm@dashv@@, xyframe.doc:409
                                             \frm@doth@@, xyframe.doc:258
                                             \frm@dotv@@, xyframe.doc:260
                                             \frm@generic, xyframe.doc:92
                                             \frm@i, xyframe.doc:76
                                             \frm@rddashh@@, xyframe.doc:428
                                             \frm@rddashv@@, xyframe.doc:430
                                             \frm@solidh@@, xyframe.doc:289
                                             \frm@solidv@@, xyframe.doc:290
                                             \frm@thickc@@, xyframe.doc:307
                                             frm[]{--}, xyframe.doc:404
                                             frm[]{-}, xyframe.doc:282
                                             frm[]{.}, xyframe.doc:256
                                             frm[]{=}, xyframe.doc:298
                                             frm[]{}, xyframe.doc:207
                                             frm[o]{--}, xyframe.doc:578
                                             frm[o]{-}, xyframe.doc:575
                                             frm[o]{.}, xyframe.doc:577
                                             frm[o]{=}, xyframe.doc:576
                                             frm[o]{}, xyframe.doc:208
                                             frm[P]{-}, xynecula.doc:141
                                             frm[P]{.}, xynecula.doc:142
                                             frm[P]{=}, xynecula.doc:143
                                             \frmDrop@, xyframe.doc:99
                                             \frmradius@@, xyframe.doc:74
                                             frm{(}, xyframe.doc:811
                                             frm{)}, xyframe.doc:812
                                             frm{**}, xyframe.doc:934
                                             frm{*}, xyframe.doc:929
                                             frm{,}, xyframe.doc:452
                                             frm{-,}, xyframe.doc:459
                                             frm{--}, xyframe.doc:399
                                             frm{-e}, xyframe.doc:569
                                             frm{-o}, xyframe.doc:543
                                             frm{-}, xyframe.doc:281
                                             frm{..}, xyframe.doc:263
                                             frm{.e}, xyframe.doc:568
                                             frm{.o}, xyframe.doc:536
                                             frm{.}, xyframe.doc:252
                                             frm{=}, xyframe.doc:292
                                             frm{\\otherebgroup}, xyframe.doc:714
                                             frm{\\otheregroup}, xyframe.doc:715
                                             frm{^)}, xyframe.doc:814
                                             frm{^\\otheregroup}, xyframe.doc:717
                                             frm{_)}, xyframe.doc:815

frm{_\\otheregroup}, xyframe.doc:718
frm{ee}, xyframe.doc:571
frm{e}, xyframe.doc:567
frm{o-}, xyframe.doc:421
frm{oo}, xyframe.doc:507
frm{o}, xyframe.doc:497
frm{}, xyframe.doc:206
\Fshape@, xyframe.doc:1018, xynecula.doc:550
\Fshape@i, xyframe.doc:1025
\Fshape@ii, xyframe.doc:1030
\Fshape@iii, xyframe.doc:1034
\Fshape@whichframe, xynecula.doc:554
\Fshape@x, xyframe.doc:1037
\fullCircle@, xyarc.doc:191
\fullEllipse@, xyarc.doc:377
\fullPi@, xycurve.doc:4447
german.sty, 4
\getarcExtents@, xyarc.doc:1075
\getarcExtents@ii, xyarc.doc:1082
\getarcExtents@iv, xyarc.doc:1086
\getarcOrientation@, xyarc.doc:1092
\getarcOrientation@i, xyarc.doc:1098
\getarcparams@, xyarc.doc:204
\getbsplineparams@, xycurve.doc:4015
\getcrvsegsnum@, xycurve.doc:2581
\getcubicparams@, xycurve.doc:3890
\getEndDirection@, xyarc.doc:1108
\getEndDirection@i, xyarc.doc:1133
\getEndDirection@x, xyarc.doc:1138
\getEqDirection@, xyarc.doc:1119
\getSpecialRotate@, xyrotate.doc:339
\getsplineedges@, xycurve.doc:2213
\getsplineedges@safe, xycurve.doc:2197
\getsplineedges@safe@, xycurve.doc:2201
\getsquineparams@, xycurve.doc:3629
\gettwocelledges@, xy2cell.doc:1781
\gettwocelledges@@, xy2cell.doc:1786
\getxyDirection@, xy.doc:7235
\getxypattern@, xytile.doc:305
\getxypattern@@, xytile.doc:306
\global , 8

GNU Copyleft, i

\go, xyv2.doc:265

\go , 556

\GRAPH, xygraph.doc:174

⟨graph⟩, 458

\graph, xygraph.doc:164
graph!E, xygraph.doc:500
graph!M, xygraph.doc:455

                                             graph!P, xygraph.doc:495
                                             \GRAPH@, xygraph.doc:176
                                             \GRAPHafterar@, xygraph.doc:206
                                             \GRAPHar@, xygraph.doc:203
                                             \GRAPHeveryarrow@@, xygraph.doc:530
                                             \GRAPHeveryentry, xygraph.doc:464
                                             \GRAPHeveryline@@, xygraph.doc:533
                                             \GRAPHnodemodifiers@@, xygraph.doc:312
                                             \GRAPHsaved@afterar@@, xygraph.doc:201
                                             \GRAPHsaved@PATHafterPOS, xygraph.doc:200
                                             \graphsetup@, xygraph.doc:535
                                             \graphsetup@i, xygraph.doc:537
                                             \grow, xyv2.doc:431
                                             \grow , 559
                                             \grow@, xyv2.doc:435
                                             \grow@@, xyv2.doc:436

h, 46

                                             \H@max, xymatrix.doc:521
                                             \H@maxin, xymatrix.doc:505
                                             \H@maxout, xymatrix.doc:506
                                             \halfEllipse@, xyarc.doc:1349
                                             \halfPi@, xycurve.doc:4448
                                             \halfrootthree, xy.doc:1851
                                             \halfrootthree , 30
                                             \halfroottwo, xy.doc:1849
                                             \halfroottwo , 30
                                             \halign , 361
                                             \halve@dimen, xycurve.doc:2254
                                             \hbox , 46
                                             \Hcap, xyknot.doc:1975
                                             \hcap, xyknot.doc:1545
                                             \Hcross, xyknot.doc:1967
                                             \hcross, xyknot.doc:385
                                             \hcrossneg, xyknot.doc:393
                                             height, 251
                                             \hidePSmessages, xyps-ps.doc:449
                                             \hloop, xyknot.doc:1608
                                             \hole, xyarrow.doc:1003

\hole , 306, 559

                                             \holesize, xyknot.doc:1801
                                             \hollowpoint@, xy.doc:5915
                                             \hook@, xy.doc:5722
                                             \hook@@, xy.doc:5723

hooks, 14

                                             \hover, xyknot.doc:479
                                             \Hrow@c@@, xymatrix.doc:504
                                             \Hrow@HWmax, xymatrix.doc:543
                                             \Hrow@in, xymatrix.doc:502
                                             \Hrow@max, xymatrix.doc:540

\Hrow@out, xymatrix.doc:503
\Hrow@R, xymatrix.doc:537
\htwist, xyknot.doc:658
\htwistneg, xyknot.doc:666
\huncross, xyknot.doc:401
\hunder, xyknot.doc:489
\hunover, xyknot.doc:499
\huntwist, xyknot.doc:674
\HW@max, xymatrix.doc:523
\HWmax@max, xymatrix.doc:546
\HWmax@set, xymatrix.doc:549

i, 46

\idfrombase@, xy.doc:2865
\idfromc@, xy.doc:2862
\idfromcxy@, xy.doc:2893
\idfroms@, xy.doc:2729
\idfromstack@, xy.doc:2868
\idfromxy@, xy.doc:2890

idioms, 7

\ifDIRECTIONempty@, xy.doc:4240
\ifEMspecials@, xyemtex.doc:59
\ifHidden@, xy.doc:3220
\ifInside@, xy.doc:7398
\ifInvisible@, xy.doc:3219
\ifjusthvtest@, xy.doc:5212
\iflastframe@, movie.cls:167, xymovie.doc:89
\ifm@caption, movie.cls:40
\ifm@count, movie.cls:46
\ifm@time, movie.cls:52
\ifnoisymatrices@, xymatrix.doc:219
\ifoldxymatrix@, xymatrix.doc:422
\ifoutlineread@, xy.doc:4887
\ifPATHomitslide@@, xyarrow.doc:313
\ifPATHsingle@, xyarrow.doc:209
\ifpoly@badinters, xynecula.doc:261
\ifpoly@closedrange, xynecula.doc:409
\ifsilentxy@, xy.doc:1538
\ifsm@acceptable, xysmart.doc:297
\ifsm@firstseg, xysmart.doc:296
\ifsplinefar@, xycurve.doc:2170
\ifsplineplot@, xycurve.doc:2171
\ifsupportwarnings@, xy.doc:6901
\iftmp@, xy.doc:662
\ifTPICspecials@, xytpic.doc:61
\ifunsupportwarnings@, xy.doc:6882
\ifVECTORempty@, xy.doc:1390
\ifxydrivernoloads@, xy.doc:6931
\ifxyPSshapes@, xyps-ps.doc:636
\ifxysaving@, xy.doc:4781

                                             \imposeDirection@, xy.doc:7210
                                             \imposeDirection@i, xy.doc:7221
                                             \includePSmessage@, xyps-ps.doc:473
                                             \includePSmessage@@, xyps-ps.doc:472
                                             \includeXYPSdict@, xyps-ps.doc:468
                                             \includeXYPSdict@@, xyps-ps.doc:464
                                             \includeXYPSdict@r, xyps-ps.doc:466
                                             \initbreaks@, xycurve.doc:1368
                                             \initshape@, xycurve.doc:795
                                             \innercroplatticeloop@, xyweb.doc:212
                                             \innerlatticeloop@, xyweb.doc:173
                                             \input xy, 1
                                             \input xypic, 563
                                             \insertmatrixingraph@, xygraph.doc:468
                                             \installCrayolaColors@, xycrayon.doc:46
                                             \installDVITOPSrotate@, xydvitops.doc:245
                                             \installEMline@, xyemtex.doc:202
                                             \installPScolor@, xyps-c.doc:87
                                             \installPSfills@, xyps-f.doc:204
                                             \installPSframes@, xyps-f.doc:67
                                             \installPSline@, xyps-l.doc:83
                                             \installPSlinestyles@, xyps-l.doc:103
                                             \installPSpatterns@, xyps-t.doc:82
                                             \installPSpolylines@, xyps-l.doc:138
                                             \installPSrotscale@, xyps-r.doc:79
                                             \installPSstyle@, xyps-s.doc:90
                                             \installTPICcurves@, xytpic.doc:413
                                             \installTPICfills@, xytp-f.doc:247
                                             \installTPICframes@, xytp-f.doc:55
                                             \installTPICline@, xytpic.doc:318
                                             \installxyps@, xyps-ps.doc:160
                                             \installxyps@@, xyps-ps.doc:164
                                             \installxyps@orig, xyps-ps.doc:199
                                             \installxyps@x, xyps-ps.doc:168
                                             \intercepthull@, xycurve.doc:1715
                                             \interceptinsidehull@, xycurve.doc:1735
                                             \interceptoutsidehull@, xycurve.doc:1761
                                             \interpARC@, xyarc.doc:934
                                             \interpolateinterval@, xy.doc:2043
                                             \interpolatepoint@, xy.doc:2050
                                             \intersect@, xy.doc:2450
                                             \invisbreaks@, xycurve.doc:1365
                                             \inxy@, xy.doc:869
                                             \inxypoly@, xypoly.doc:245

italic corrections, 15

                                             \iterate@, xy.doc:837
                                             \jot , 36
                                             \jumpMOVE@, xygraph.doc:241
                                             \jumpMOVE@@, xygraph.doc:240

\K@, xy.doc:678
\K@dXdY, xy.doc:682
\K@dYdX, xy.doc:683
\khole, xyknot.doc:1052
\KK@, xy.doc:679
\knothole, xyknot.doc:1051
\knothole@, xyknot.doc:1048
\knotholesize, xyknot.doc:1800
\knotholesize@, xyknot.doc:1798
\KNOTstyle, xyknot.doc:1790
\knotSTYLE, xyknot.doc:1781
\knotstyle, xyknot.doc:1784
\knotstyles, xyknot.doc:1787
\knottips, xyknot.doc:1803

L, 20 L, 23, 40

\L@, xycurve.doc:4461
\L@c, xy.doc:615
\L@p, xy.doc:623

L_{c}, 21 L_{p}, 21 label separation, 355

\labelbox, xyarrow.doc:1025
\labelbox , 306
\labelmargin, xyarrow.doc:987
\labelmargin , 306
\labelmargin@, xyarrow.doc:985
\labelstyle, xyarrow.doc:1024
\labelstyle , 306
\lastbreak@@, xy.doc:7935
\lastbreaks@, xycurve.doc:1373
\lastbspline@, xycurve.doc:4069
\lastbspline@@, xycurve.doc:4056
\lastobject , 16
\lastobjectbox@, xy.doc:646
\lastprentry@@, xymatrix.doc:380
\lastsplinepoint@, xycurve.doc:2406

L^{A}TEX, 7, 11

\LaTeXdiagrams, xyv2.doc:543
\LaTeXdiagrams , 561

L^{A}TEX 2ε, 11

\lattice@A, xyweb.doc:50
\lattice@B, xyweb.doc:51
\latticeA, xyweb.doc:52
\latticeB, xyweb.doc:53
\latticebody, xyweb.doc:131, xyweb.doc:278, xyweb.doc:90
\lbraced, xyframe.doc:765
\Lc, xyv2.doc:216

\Lc , 556 LD, 23

                                             \lDirection@, xy.doc:7106

leave, 17

                                             \leave@, xy.doc:777
                                             \Leftness@, xy.doc:3222
                                             \let , 3, 4
                                             \lighten@, movie.cls:270
                                             \line@, xy.doc:5132
                                             \line@@, xy.doc:5155

⟨list⟩, 458

                                             \literal@, xyidioms.doc:105
                                             \lltod, xyv2.doc:692
                                             \lltou, xyv2.doc:693
                                             \LoadAllPatterns, xytile.doc:280

loading, 1, 3, 4, 11

                                             \LoadPattern, xytile.doc:283
                                             \loadPSdriver@, xyps.doc:266
                                             \loadtipfonts@, xytips.doc:119
                                             \loadxystyle@, xy.doc:3984

logo, 13

                                             \loop , 18
                                             \loop@, xy.doc:836
                                             \loop@@, movie.cls:58
                                             \lowercurveobject, xy2cell.doc:1089
                                             \lowertwocell, xy2cell.doc:1248
                                             \lowertwocell@, xy2cell.doc:271
                                             \lowertwocelll, xy2cell.doc:1259
                                             \Lp, xyv2.doc:223

\Lp , 556

                                             \lparenthesized, xyframe.doc:846
                                             \ltxdiagram@, xyv2.doc:547

LU, 23

                                             \m@caption, movie.cls:143
                                             \m@height, xymovie.doc:61
                                             \m@keys, movie.cls:133, movie.cls:94
                                             \m@nicetotal, movie.cls:225
                                             \m@scene, xymovie.doc:90
                                             \m@width, xymovie.doc:62
                                             \MacPatterns, xytile.doc:60
                                             \makeatletter , 4
                                             \makeatother , 4
                                             \MakeOutlines, xy.doc:4869
                                             \MakeOutlines , 69

math mode, 20

                                             \mathbf, xy2cell.doc:882
                                             \mathsurround , 21

⟨matrix⟩, 343 matrix, 342 matrix orientation, 354 matrix spacing, 354

\matrixsize@, xymatrix.doc:218
\maxcol@, xymatrix.doc:163
\maxcolrow@, xymatrix.doc:164
\maxrow@, xymatrix.doc:162
\maxTPICpoints, xytpic.doc:81
\maybeunraise@, xy.doc:1155
\merge, xyv2.doc:268
\merge , 557
\mergecropextents@, xyweb.doc:227

messages, 13

\middlebspline@, xycurve.doc:4102
\middlebspline@@, xycurve.doc:4071
\mkHmax@, xymatrix.doc:527
\mkHrow@, xymatrix.doc:525
\mkHWdefaults@, xymatrix.doc:531
\mkHWmax@, xymatrix.doc:529
\mkWcol@, xymatrix.doc:526
\mkWmax@, xymatrix.doc:528
\moddefs@, xy2cell.doc:1022

⟨modifier⟩, 46, 280

\modifystyle@, xy.doc:4114
\modmap@, xy2cell.doc:1010
\modmapobject, xy2cell.doc:1054
\modmapobject@, xy2cell.doc:1055
\modPSboxz@, xyps-ps.doc:412
\modPSconnect@, xyps-ps.doc:427
\modPSdrop@, xyps-ps.doc:417
\modXYstyle@, xy.doc:3953
\modXYstyle@@, xy.doc:3959
\modXYtransform@, xyrotate.doc:205
\morepatread@, xytile.doc:302
\morphism, xyv2.doc:613
\morphism , 561

⟨move⟩, 458

\MOVE@, xygraph.doc:243
\MOVE@hop, xygraph.doc:267
\MOVE@letter, xygraph.doc:248
\MOVE@place, xygraph.doc:272
\MOVE@x, xygraph.doc:256
movie, 250
\MovieSetup, movie.cls:138, xymovie.doc:68
\MovieSetup , 251
\MultipleDrivers, xy.doc:6699
\MultipleDrivers , 93
\myPOS, xy2cell.doc:1286
\newdir, xy.doc:5795
\newdir , 82, 312
\newdir@, xy.doc:5797

                                             \newdriver, xy.doc:6808
                                             \newdriver , 95
                                             \newgraphescape, xygraph.doc:598
                                             \newgraphescape , 367
                                             \newgraphescape@, xygraph.doc:607
                                             \newlinechar , 14
                                             \newxyColor, xycolor.doc:175
                                             \newxycolor, xycolor.doc:174
                                             \newxycolor , 235
                                             \newxycolor@, xycolor.doc:193
                                             \newxyPattern, xytile.doc:117
                                             \newxypattern, xytile.doc:114
                                             \newxypattern , 242
                                             \newxypattern@, xytile.doc:123
                                             \newxypattern@i, xytile.doc:115
                                             \newxyPSshape, xyps-ps.doc:683
                                             \newxyshape, xyps-ps.doc:661
                                             \newxystyle, xy.doc:4088
                                             \next, movie.cls:131, movie.cls:30, movie.cls:31,
                                                    xy.doc:417, xy.doc:420, xy.doc:6836, xy.doc:6841,
                                                    xy.sty:43, xyknot.doc:1403, xyknot.doc:332
                                             \next , 3
                                             \nextbreak@@, xy.doc:8091
                                             \nextcptlabel, xycurve.doc:1859
                                             \no@, xy.doc:5081
                                             \no@@, xy.doc:7986
                                             \noCalong@@, xy.doc:7952
                                             \noCbreak@@, xy.doc:7973
                                             \noCintercept@@, xy.doc:7960
                                             \noClast@@, xy.doc:7974
                                             \NoCompileAllDiagrams, xyv2.doc:798
                                             \NoCompileMatrices, xymatrix.doc:284
                                             \NoComputerModernTips, xycmtip.doc:52
                                             \noCshavec@@, xy.doc:7942
                                             \noCshavep@@, xy.doc:7937
                                             \noCslidec@@, xy.doc:7948
                                             \noCslidep@@, xy.doc:7944

⟨node⟩, 458

                                             \NODE@, xygraph.doc:220
                                             \NODE@arc, xygraph.doc:501
                                             \NODE@arc@, xygraph.doc:503
                                             \NODE@escape, xygraph.doc:430
                                             \NODE@i, xygraph.doc:274
                                             \NODE@it, xygraph.doc:309
                                             \NODE@matrix, xygraph.doc:457
                                             \NODE@matrix@, xygraph.doc:459
                                             \NODE@poly, xygraph.doc:496
                                             \NODE@poly@, xygraph.doc:497
                                             \NODE@x, xygraph.doc:307

\NODEit@, xygraph.doc:314
\NODEit@i, xygraph.doc:319
\noDictmessage@, xyps-ps.doc:492
\NoDVIPScolor@, xydvips.doc:87
\NoDVIPScolordvi@, xydvips.doc:102
\NoDVITOPScolor@, xydvitops.doc:89
\NoEMlinewidth, xyemtex.doc:212
\NoEMspecials, xyemtex.doc:61
\noinsert@, xy.doc:8002
\nointerceptwarning@, xycurve.doc:1712
\NoisyDiagrams, xyv2.doc:554
\NoisyDiagrams , 561
\NoisyEMTeX, xyemtex.doc:86
\NoisyMatrices, xymatrix.doc:222
\NoisyTPIC, xytpic.doc:130
\none, xyv2.doc:300
\none , 557
\NooldOzTeXColor@, xy17oztex.doc:92
\NooldTexturesColor@, xy16textures.doc:86
\NoOutlines, xy.doc:4876
\NoOutlines , 69
\NoOzTeXColor@, xyoztex.doc:97
\NoPScolor, xyps-c.doc:74
\NoPSframes, xyps-f.doc:75
\NoPSlines, xyps-l.doc:87
\NoPSrotate, xyps-r.doc:90
\NoPSspecials, xyps.doc:312
\NoPSspecials , 255
\NoPStiles, xyps-t.doc:91
\NoResizing, xyrotate.doc:120
\NoRules, xy.doc:5214
\NoRules , 74
\notempty, xyidioms.doc:120
\NoTexturesColor@, xytextures.doc:95
\notip, xyv2.doc:346
\notip , 558
\NoTips, xytips.doc:176
\NoTips , 216
\NoTPICframes, xytp-f.doc:63
\NoTPICspecials, xytpic.doc:63
\notrelaxorelse@, xy.doc:1430
\NoXDVIcolor@, xyxdvi.doc:104
\NoXDVIcolordvi@, xyxdvi.doc:119
\nter@, xy.doc:770
\nudgepos@, xy2cell.doc:828
\nudgepos@@, xy2cell.doc:845
\null@xy@ps, xyps-ps.doc:214
\numcontrolpts, xycurve.doc:1881
\obeyDVIPSlines@, xydvips.doc:182, xydvitops.doc:201

                                             \obeyoldOzTeXlines@, xy17oztex.doc:155
                                             \obeyoldTextureslines@, xy16textures.doc:165
                                             \obeyoutlines@, xyps-ps.doc:566
                                             \obeyOzTeXlines@, xyoztex.doc:160
                                             \obeyTextureslines@, xytextures.doc:170
                                             \obeyXDVIlines@, xyxdvi.doc:195

⟨object⟩, 46

                                             \object, xy.doc:3292

object, 20

\object , 45, 46, 72 object methods, 48

                                             \OBJECT@, xy.doc:3074, xynecula.doc:64
                                             \object@, xy.doc:3294
                                             \OBJECT@@, xy.doc:3125
                                             \OBJECT@change, xy.doc:3522
                                             \OBJECT@change@, xy.doc:3543
                                             \OBJECT@direction, xy.doc:4223
                                             \OBJECT@letter, xy.doc:3079
                                             \OBJECT@other, xy.doc:3092
                                             \OBJECT@set, xy.doc:3532
                                             \OBJECT@shape, xy.doc:3749
                                             \OBJECT@shapei, xy.doc:3779
                                             \OBJECT@shift, xy.doc:3410
                                             \OBJECT@shift@, xy.doc:3416
                                             \OBJECT@x, xy.doc:3176

⟨objectbox⟩, 46

                                             \objectbox, xy.doc:3239, xy.doc:3253

\objectbox , 45, 47, 49, 306

                                             \objectEdge, xy.doc:3698
                                             \objectheight, xy.doc:3490
                                             \objectheight , 52
                                             \objectheight@, xy.doc:3486
                                             \objectmargin, xy.doc:3488
                                             \objectmargin , 52, 305, 306
                                             \objectmargin@, xy.doc:3484
                                             \objectstyle, xy.doc:3241, xy.doc:3255, xy.doc:3668,
                                                    xypoly.doc:135, xypoly.doc:588
                                             \objectwidth, xy.doc:3489
                                             \objectwidth , 52
                                             \objectwidth@, xy.doc:3485
                                             \old@OzTeX@PS@, xy17oztex.doc:190
                                             \oldconnect, xyv2.doc:616
                                             \oldoztexColor@@, xy17oztex.doc:78
                                             \oldOzTeXColours@, xy17oztex.doc:80
                                             \oldOzTeXCrayon@@, xy17oztex.doc:111
                                             \oldOzTeXCurrpt@, xy17oztex.doc:166
                                             \oldOzTeXCurrpt@@, xy17oztex.doc:167
                                             \oldOzTeXDict@, xy17oztex.doc:134
                                             \oldOzTeXFrames@, xy17oztex.doc:219

\oldoztexFrames@@, xy17oztex.doc:217
\oldOzTeXinclude@, xy17oztex.doc:135
\oldoztexLine@, xy17oztex.doc:206
\oldoztexLine@@, xy17oztex.doc:204
\oldOzTeXMacro@, xy17oztex.doc:133
\oldoztexPS@@, xy17oztex.doc:121, xy17oztex.doc:177
\oldOzTeXPStypes@, xy17oztex.doc:138
\oldoztexPSunload@, xy17oztex.doc:123
\oldOzTeXraw@, xy17oztex.doc:136
\oldOzTeXRotate@, xy17oztex.doc:254
\oldoztexRotate@@, xy17oztex.doc:252
\oldOzTeXSpecial@, xy17oztex.doc:132
\oldOzTeXTiles@, xy17oztex.doc:232
\oldoztexTiles@@, xy17oztex.doc:230
\oldTextures@@, xy16textures.doc:43
\oldtexturesColor@@, xy16textures.doc:84
\oldTexturesColours@, xy16textures.doc:71
\oldtexturesCrayon@, xy16textures.doc:106
\oldtexturesCrayon@@, xy16textures.doc:105
\oldtexturesCurrpt@, xy16textures.doc:172
\oldtexturesCurrpt@@, xy16textures.doc:173
\oldtexturesFrames@, xy16textures.doc:231
\oldtexturesFrames@@, xy16textures.doc:229
\oldTexturesInclude@, xy16textures.doc:145
\oldtexturesLine@, xy16textures.doc:217
\oldtexturesLine@@, xy16textures.doc:215
\oldTexturesMacro@, xy16textures.doc:144
\oldtexturesPS@, xy16textures.doc:190
\oldtexturesPS@@, xy16textures.doc:113
\oldtexturesPStypes@, xy16textures.doc:148
\oldtexturesPSunload@, xy16textures.doc:115
\oldTexturesRaw@, xy16textures.doc:146
\oldtexturesRotate@, xy16textures.doc:203
\oldtexturesRotate@@, xy16textures.doc:201
\oldTexturesSpecial@, xy16textures.doc:143
\oldtexturesTiles@, xy16textures.doc:245
\oldtexturesTiles@@, xy16textures.doc:243
\omitarrows@, xy2cell.doc:508
\omittingTokens@, xyarc.doc:1142
\OnlyOutlines, xy.doc:4871
\OnlyOutlines , 69
\openpattfile@, xytile.doc:273

⟨orient⟩, 85 orientation, 354

\origPATHturn@, xysmart.doc:108
\outlines@@, xy.doc:4865
\outlines@make, xy.doc:4862
\outlines@no, xy.doc:4861
\outlines@only, xy.doc:4863

                                             \outofranges@, xy.doc:2690
                                             \outputstyle@, xy.doc:4119
                                             \outputxyline@, xyline.doc:599
                                             \outputxylinecap@, xyline.doc:319
                                             \outputxylinejoin@, xyline.doc:344
                                             \outputxylinemiter@, xyline.doc:369
                                             \oxy@, xy.doc:858
                                             \OzTeX@, xyps.doc:272
                                             \OzTeX@@, xy17oztex.doc:53, xyoztex.doc:59
                                             \oztexColor@@, xyoztex.doc:83
                                             \OzTeXColours@, xyoztex.doc:85
                                             \OzTeXCrayon@@, xyoztex.doc:116
                                             \OzTeXCurrpt@, xyoztex.doc:171
                                             \OzTeXCurrpt@@, xyoztex.doc:172
                                             \OzTeXDict@, xyoztex.doc:139
                                             \OzTeXFrames@, xyoztex.doc:217
                                             \oztexFrames@@, xyoztex.doc:215
                                             \OzTeXinclude@, xyoztex.doc:140
                                             \oztexLine@, xyoztex.doc:204
                                             \oztexLine@@, xyoztex.doc:202
                                             \OzTeXMacro@, xyoztex.doc:138
                                             \oztexPS@, xyoztex.doc:182
                                             \oztexPS@@, xyoztex.doc:126
                                             \OzTeXPStypes@, xyoztex.doc:143
                                             \oztexPSunload@, xyoztex.doc:128
                                             \OzTeXraw@, xyoztex.doc:141
                                             \OzTeXRotate@, xyoztex.doc:252
                                             \oztexRotate@@, xyoztex.doc:250
                                             \OzTeXRotScale@, xyoztex.doc:265, xyoztex.doc:276
                                             \OzTeXSpecial@, xyoztex.doc:137
                                             \OzTeXTiles@, xyoztex.doc:230
                                             \oztexTiles@@, xyoztex.doc:228

P, 23, 40, 103

p, 21 p, 23 package, 11

                                             \parallelDirection@, xyarc.doc:1372
                                             \parEllipse@, xyarc.doc:1374
                                             \parseCURVE@, xycurve.doc:498
                                             \parsecurve@, xycurve.doc:586
                                             \parseCURVE@@, xycurve.doc:500
                                             \parsecurve@@, xycurve.doc:587
                                             \parsepattern@@, xytile.doc:309
                                             \partroottwo, xy.doc:1850
                                             \partroottwo , 30
                                             \PATH, xyarrow.doc:183

\PATH , 295, 307

                                             \PATH@, xyarrow.doc:211
                                             \PATH@normal, xyarrow.doc:216

\PATHaction, xyarrow.doc:455
\PATHaction , 299
\PATHaction@, xyarrow.doc:462
\PATHaction@default, xyarrow.doc:454
\PATHafter@@, xyarrow.doc:237
\PATHafterPOS, xyarrow.doc:590
\PATHafterPOS , 301
\PATHafterPOS@default, xyarrow.doc:589
\PATHanchor@, xyarrow.doc:377
\PATHanchor@i, xyarrow.doc:379
\PATHanchor@toks, xyarrow.doc:390
\PATHbefore@@, xyarrow.doc:236
\PATHcontinue@@, xyarrow.doc:278
\PATHextra@@, xyarrow.doc:276
\PATHfail@@, xyarrow.doc:234
\PATHfinal@, xyarrow.doc:287
\PATHfinishsegments@, xyarrow.doc:414
\PATHfinishsegments@i, xyarrow.doc:419
\PATHinit@@, xyarrow.doc:274
\PATHinitstraight@, xyarrow.doc:297
\PATHit@, xyarrow.doc:394
\PATHit@i, xyarrow.doc:396
\PATHitshapes@@, xyarrow.doc:392
\PATHlabelabove@, xyarrow.doc:935
\PATHlabelabove@@, xyarrow.doc:941
\PATHlabelalias@, xyarrow.doc:1052
\PATHlabelbelow@, xyarrow.doc:938
\PATHlabelbelow@@, xyarrow.doc:942
\PATHlabelbreak@, xyarrow.doc:959
\PATHlabelit@@, xyarrow.doc:362
\PATHlabels@, xyarrow.doc:364
\PATHlabelsevery@@, xyarrow.doc:239
\PATHlabelsextralast@, xyarrow.doc:294
\PATHlabelslast@@, xyarrow.doc:241
\PATHlabelsnext@@, xyarrow.doc:240
\PATHlastout@@, xyarrow.doc:661
\PATHpost@@, xyarrow.doc:277
\PATHpostpos@@, xyarrow.doc:771
\PATHsegment@, xyarrow.doc:315
\PATHsegment@@, xyarrow.doc:346
\PATHsetting@, xyarrow.doc:243
\PATHslide@@, xyarrow.doc:312
\PATHsmartturn@cir, xysmart.doc:122
\PATHsmartturn@i, xysmart.doc:128
\PATHstraight@, xyarrow.doc:280
\PATHturn@, xyarrow.doc:667, xysmart.doc:109
\PATHturn@cir, xyarrow.doc:677
\PATHturn@diag, xyarrow.doc:704
\PATHturn@i, xyarrow.doc:773

                                             \PATHturn@ii, xyarrow.doc:834
                                             \pfromc@, xy.doc:1632
                                             \pfromthec@, xy.doc:1672
                                             \pfromthep@, xy.doc:1668
                                             \pit , 554

⟨place⟩, 23

                                             \PLACE@, xy.doc:2293
                                             \PLACE@@, xy.doc:2324
                                             \PLACE@intercept, xy.doc:2307
                                             \PLACE@intercept@, xy.doc:2316, xycurve.doc:1650
                                             \placeAllQuadrants@, xycurve.doc:4578
                                             \placeCircObject@, xycurve.doc:4599
                                             \placeCircQuadrant@, xycurve.doc:4590
                                             \PLACEedgec@, xy.doc:2289
                                             \PLACEedgec@@, xy.doc:2286
                                             \PLACEedgep@, xy.doc:2288
                                             \PLACEedgep@@, xy.doc:2285
                                             \PLACEf@, xy.doc:2283

placement state, 21

                                             \placeQuadrants@, xycurve.doc:4572

plainTEX, 7

                                             \plainxy@, xy.doc:892
                                             \point@, xy.doc:5330
                                             \pointlike@, xy.doc:5332
                                             \poly@append, xynecula.doc:204
                                             \poly@append@, xynecula.doc:205
                                             \poly@cachehit, xynecula.doc:279
                                             \poly@cachehitdisable, xynecula.doc:283
                                             \poly@close, xynecula.doc:208
                                             \poly@close@, xynecula.doc:209
                                             \poly@drawseg, xynecula.doc:234
                                             \poly@empty, xynecula.doc:169
                                             \poly@findextent, xynecula.doc:536
                                             \poly@getinterspoints, xynecula.doc:517
                                             \poly@intersdoit, xynecula.doc:307
                                             \poly@interseg, xynecula.doc:357
                                             \poly@intersfinish, xynecula.doc:336
                                             \poly@intersprobecache, xynecula.doc:289
                                             \poly@isinrange, xynecula.doc:410
                                             \poly@isonray, xynecula.doc:447
                                             \poly@isonseg, xynecula.doc:437
                                             \poly@map, xynecula.doc:170
                                             \poly@map@stop, xynecula.doc:178
                                             \poly@mapExpand, xynecula.doc:180
                                             \poly@parse, xynecula.doc:186
                                             \poly@setEdge, xynecula.doc:135
                                             \poly@setEdge@, xynecula.doc:136
                                             \poly@setorigin, xynecula.doc:345
                                             \poly@setorigin@, xynecula.doc:346

\poly@setp, xynecula.doc:229
\poly@setp@, xynecula.doc:230
\polygonEdge, xynecula.doc:243
\polygonEdge@Dist, xynecula.doc:402
\polygonEdge@Inner, xynecula.doc:483
\polygonEdge@Inters, xynecula.doc:263
\polygonEdge@Outer, xynecula.doc:524
\polygonEdge@Under, xynecula.doc:457
\POS, xy.doc:1368

⟨pos⟩, 23 \POS , 24, 65, 299

\POS@, xy.doc:1593
\POS@colon, xy.doc:1603
\POS@star, xy.doc:1608

positions, 20

\postShape@@, xyrotate.doc:194
\postspline@, xycurve.doc:2683
\postStyle@@, xy.doc:3981
\postXY@style@, xy.doc:3854
\postxyescape@, xyps-s.doc:74
\postxyline@, xyline.doc:595
\postxyline@@, xyline.doc:592
\postxylinecap@, xyline.doc:317
\postxylinecap@@, xyline.doc:314
\postxylinejoin@, xyline.doc:342
\postxylinejoin@@, xyline.doc:339
\postxylinemiter@, xyline.doc:367
\postxylinemiter@@, xyline.doc:364
\postXYtransform@, xyps-r.doc:114, xyrotate.doc:186
\postXYtransform@@, xyrotate.doc:189
\pre@emit, xymatrix.doc:444
\pre@emit@, xymatrix.doc:481
\pre@emit@i, xymatrix.doc:485
\pre@emit@ii, xymatrix.doc:492
\preARC@, xyarc.doc:69
\preconnect, xy.doc:4537
\preconnect@, xy.doc:2144
\prentry@, xymatrix.doc:365
\prentry@@, xymatrix.doc:384
\prentry@@@, xymatrix.doc:424
\prentry@@@i, xymatrix.doc:429
\prentry@@norm, xymatrix.doc:405
\prentry@@star, xymatrix.doc:389
\prentry@@star@i, xymatrix.doc:392
\prentry@@star@ii, xymatrix.doc:396
\prentry@@x, xymatrix.doc:410
\preShape@@, xyrotate.doc:193
\preStyle@@, xy.doc:3980
\prevEdge@@, xy.doc:3123

                                             \prevEdgefromtheEdge@, xyframe.doc:107
                                             \prevhowclose@, xycurve.doc:1748
                                             \prevXypostStyle@@, xy.doc:4065
                                             \prevXypreStyle@@, xy.doc:4064
                                             \preXY@style@, xy.doc:3853
                                             \prexyescape@, xyps-s.doc:73
                                             \prexyline@, xyline.doc:594
                                             \prexyline@@, xyline.doc:590
                                             \prexylinecap@, xyline.doc:316
                                             \prexylinecap@@, xyline.doc:312
                                             \prexylinejoin@, xyline.doc:341
                                             \prexylinejoin@@, xyline.doc:337
                                             \prexylinemiter@, xyline.doc:366
                                             \prexylinemiter@@, xyline.doc:362
                                             \preXYstyle@@, xy.doc:3982
                                             \preXYtransform@, xyps-r.doc:113, xyrotate.doc:185
                                             \preXYtransform@@, xyrotate.doc:188

privacy, 3

                                             \processArcDirections@, xyarc.doc:1150
                                             \processArcDirections@@, xyarc.doc:1160
                                             \processDirections@@, xyarc.doc:1146
                                             \PSdict@@, xyps-ps.doc:63
                                             \Pshape@, xynecula.doc:109
                                             \PSignore@, xyps-ps.doc:447
                                             \PSinclude@@, xyps-ps.doc:66
                                             \PSincrease@, xyps.doc:500
                                             \PSmacro@, xyps-ps.doc:453
                                             \PSmacro@@, xyps-ps.doc:62
                                             \PSmessage@, xyps-ps.doc:446
                                             \PSraw@@, xyps-ps.doc:67
                                             \PSread@@, xyps-ps.doc:65
                                             \PSspecial@@, xyps-ps.doc:64
                                             \PSspecialdict@@, xyps-ps.doc:69
                                             \PSspecials@, xyps.doc:448
                                             \PSspecials@@, xyps.doc:453
                                             \PStracing, xyps-ps.doc:450
                                             \pure@crv, xycurve.doc:277
                                             \q, xypoly.doc:609

q, 46

                                             \qartPi@, xytpic.doc:348
                                             \qc, xyv2.doc:449

\qc , 559

                                             \qcount@, xymatrix.doc:176
                                             \qcount@@, xymatrix.doc:177
                                             \qspline, xycurve.doc:4773
                                             \quadARC@, xyarc.doc:928

queue, 17

                                             \queue@, xymatrix.doc:173
                                             \queue@@, xymatrix.doc:174

\quotesmash, xy.doc:6093, xy.doc:6192, xy.doc:6212
\quotient@, xy.doc:812
\quotient@@, xy.doc:824
\quotPTK@, xy.doc:701
\quotsign@@, xy.doc:808

R, 8, 20 R, 23, 40

\R@, xyidioms.doc:87
\R@c, xy.doc:616
\R@p, xy.doc:624

R_{c}, 21 R_{p}, 21 ⟨radius⟩, 85

\rbraced, xyframe.doc:781
\Rc, xyv2.doc:217

\Rc , 556 RD, 23

\rDirection@, xy.doc:7084
\readoutline@, xy.doc:4889
\readoutline@@, xy.doc:4867
\readsplineparams@, xycurve.doc:2193
\readxycurve, xycurve.doc:1922
\readxycurve@, xycurve.doc:1921
\realinstallxyps@x, xyps-ps.doc:178
\ReCompileAllDiagrams, xyv2.doc:799
\recovercurve@, xycurve.doc:342
\recovercv@end, xycurve.doc:349
\recoverXyStyle@, xy.doc:4072
\rectangleDist@, xy.doc:7787
\rectangleDist@i, xy.doc:7796
\rectangleEdge, xy.doc:7697
\rectangleEdge@, xy.doc:7731
\rectangleEdge@i, xy.doc:7737
\rectangleEdge@ii, xy.doc:7744
\rectangleEdge@iii, xy.doc:7750
\rectangleProp@, xy.doc:7819
\rectangleUnder@, xy.doc:7769
\redefine , 555

redefined, 3 \relax , 3, 4, 65

\reloadxyEM@, xyemtex.doc:138
\reloadxyTPIC@, xytpic.doc:228
\removePT@, xy.doc:809
\resetbreaks@, xycurve.doc:1361
\resetcrvobjects@, xycurve.doc:606
\resetDirection@, xy.doc:7314
\resetPS@, xyps.doc:314
\resetStyle@, xy.doc:3856
\resetstyle@@, xy.doc:4118

                                             \resetTransform@, xyrotate.doc:226
                                             \resetupDirection@, xy.doc:7321
                                             \resetvariant@, xyarrow.doc:1339
                                             \resetxyline@, xyline.doc:597
                                             \resetxyline@@, xyline.doc:601
                                             \resetxyline@i, xyline.doc:598
                                             \resetxylinecap@, xyline.doc:320
                                             \resetxylinecap@@, xyline.doc:322
                                             \resetxylinecap@i, xyline.doc:321
                                             \resetxylinejoin@, xyline.doc:345
                                             \resetxylinejoin@@, xyline.doc:347
                                             \resetxylinejoin@i, xyline.doc:346
                                             \resetxylinemiter@, xyline.doc:370
                                             \resetxylinemiter@@, xyline.doc:372
                                             \resetxylinemiter@i, xyline.doc:371
                                             \restore, xy.doc:4581
                                             \restore , 65
                                             \restoreframestyles@, xyframe.doc:1056
                                             \restR@max, xyframe.doc:958
                                             \reverseDirection@, xy.doc:7253
                                             \reversesplineval@, xycurve.doc:3135
                                             \rotate, xyv2.doc:405
                                             \rotate , 558
                                             \rotate@i, xyv2.doc:410
                                             \rotate@ii, xyv2.doc:412
                                             \rounddashframed, xyv2.doc:506
                                             \rounddashframed , 560
                                             \Row, xymatrix.doc:159
                                             \Row , 359

row spacing, 354

                                             \Rp, xyv2.doc:224

\Rp , 556

                                             \rparenthesized, xyframe.doc:860
                                             \rrtod, xyv2.doc:694
                                             \rrtou, xyv2.doc:695

RU, 23

                                             \rungraphescape@, xygraph.doc:614
                                             \runs@, xy.doc:2688
                                             \runxywith@, xy.doc:6445

s, 23

                                             \s@bot, xy.doc:2673
                                             \s@top, xy.doc:2674
                                             \samecurve, xycurve.doc:614
                                             \save, xy.doc:4576
                                             \save , 65
                                             \save@, xy.doc:4579
                                             \savealias@, xyarrow.doc:1061
                                             \saveC, xy.doc:4577
                                             \savecrvobjects@, xycurve.doc:1963

\savecrvparams@, xycurve.doc:815
\savectrlptsnum@, xycurve.doc:2042
\savecurve, xycurve.doc:613
\saveframestyles@, xyframe.doc:1052
\saveid@, xy.doc:2843
\saveid@COORD, xy.doc:2882
\saveid@COORD@@, xy.doc:2856
\saveid@COORDi, xy.doc:2887
\saveid@COORDii, xy.doc:2888
\savesame@, xycurve.doc:341
\savescope@, xycurve.doc:2036
\saveshape@, xycurve.doc:804
\savespline@, xycurve.doc:2106
\savesplineparams@, xycurve.doc:2119
\savesplinerefs@, xycurve.doc:2122
\savetwocellobjects, xy2cell.doc:1103
\saveXyStyle@, xy.doc:4067
\sbendh, xyknot.doc:1652
\sbendv, xyknot.doc:1648
\scanbspline@, xycurve.doc:4106
\scene, xymovie.doc:92
\scene , 250
\scene@, xymovie.doc:97
\scene@frame, movie.cls:196, xymovie.doc:117

scratch register conventions, 8

\sd@X, xy.doc:675
\sd@Y, xy.doc:676
\searchBreakEsegment@, xycurve.doc:2854
\searchBreakSsegment@, xycurve.doc:2835
\searchflag@, xycurve.doc:714
\searchforEndsegment@, xycurve.doc:2710
\searchforStartsegment@, xycurve.doc:2650
\searchnextpt@, xycurve.doc:695
\selectdriver@, xy.doc:6684
\selectdriver@multiple, xy.doc:6693
\selectdriver@single, xy.doc:6687
\SelectTips, xytips.doc:77
\SelectTips , 215

semidirectional, 15

\SemiDirectionChar, xy.doc:689
\sempty@, xy.doc:2752
\senter@, xy.doc:2741
\setafterCURVEaction@, xycurve.doc:551
\setafterCURVEaction@@, xycurve.doc:562
\setbase@, xy.doc:1869
\setbase@@, xy.doc:1875
\setboxz@h, xyidioms.doc:112
\setcrvobjects@, xycurve.doc:2339
\setcubicdir@, xycurve.doc:3847

                                             \setcubicknotdir@, xycurve.doc:3874
                                             \setcubiczerodir@, xycurve.doc:3878
                                             \setcurve@, xycurve.doc:102
                                             \setcurvearexit@, xyarrow.doc:1757
                                             \setcurvearinit@, xyarrow.doc:1753
                                             \setcurvearinit@i, xyarrow.doc:1752
                                             \setcurveSTYLE@, xycurve.doc:528
                                             \setcurveSTYLE@@, xycurve.doc:529
                                             \setm@caption, movie.cls:177
                                             \setsearchflag@, xycurve.doc:715
                                             \setsplinetest@, xycurve.doc:3225
                                             \setsplineundertest@, xycurve.doc:3203
                                             \setsquinedir@, xycurve.doc:3606
                                             \setsquineknotdir@, xycurve.doc:3615
                                             \setsquinezerodir@, xycurve.doc:3619
                                             \setstdsplinedrop@, xycurve.doc:2317
                                             \settomin@, xy.doc:7757
                                             \setTPICcircstyle@, xytp-f.doc:197
                                             \setupcubic@, xycurve.doc:3737
                                             \setupDirection@, xy.doc:7023
                                             \setupDirection@i, xy.doc:7027
                                             \setupDirection@ii, xy.doc:7170
                                             \setupsquine@, xycurve.doc:3534
                                             \setupxyEMTeX@, xyemtex.doc:118
                                             \setupxyPS@, xyps.doc:497
                                             \setupxyPS@@, xyps-ps.doc:165
                                             \setupxyPSlevelA@, xyps.doc:710
                                             \setupxyPSlevelB@, xyps.doc:728
                                             \setupxyPSlevelC@, xyps.doc:734
                                             \setupxyPSlevelD@, xyps.doc:744
                                             \setupxyPSlevelO@, xyps.doc:487
                                             \setupxyTPIC@, xytpic.doc:203
                                             \setxyPSlevel@, xyps.doc:489
                                             \shaded@, xyframe.doc:455
                                             shape [!...], xyps-ps.doc:231
                                             shape [*...], xyrotate.doc:160
                                             shape [.], xy.doc:3764
                                             shape [<...], xyrotate.doc:159
                                             shape [=...], xy.doc:4040
                                             shape [@...], xyrotate.doc:158
                                             shape [], xy.doc:3759
                                             shape [c], xy.doc:3729
                                             shape [d], xy.doc:3725
                                             shape [dblsize], xyrotate.doc:166
                                             shape [F...], xyframe.doc:1013
                                             shape [flip], xyrotate.doc:164
                                             shape [halfsize], xyrotate.doc:165
                                             shape [hflip], xyrotate.doc:168
                                             shape [Inner], xy.doc:3761

shape [l], xy.doc:3717
shape [left], xyrotate.doc:162
shape [o], xy.doc:3762
shape [Outer], xy.doc:3760
shape [psxy], xyps-ps.doc:235
shape [r], xy.doc:3713
shape [right], xyrotate.doc:163
shape [u], xy.doc:3721
shape [vflip], xyrotate.doc:167
\shiftdir@, xy.doc:5810
\ShowOutlines, xy.doc:4874
\ShowOutlines , 69
\showPSmessages, xyps-ps.doc:448
\silencexy@, xy.doc:1540
\SilentMatrices, xymatrix.doc:221
\SilentMatrices , 343
\sinDirection, xy.doc:686
\sinFivePIon, xypoly.doc:701
\sinFourPIon, xypoly.doc:692
\sinit@, xy.doc:2739
\sinPIon, xypoly.doc:666
\sinThreePIon, xypoly.doc:683
\sinTwoPIon, xypoly.doc:674

⟨size⟩, 46

\skewCircle@, xyarc.doc:1323
\skewEllB@, xyarc.doc:1377
\skewEllipse@, xyarc.doc:1318
\skipspecials@, xy.doc:73, xy.doc:74
\sleave@, xy.doc:2746

⟨slide⟩, 23

\SloppyCurves, xycurve.doc:2290
\sloppyendcrv@, xycurve.doc:729
\sm@accumext, xysmart.doc:426
\sm@advancecount@, xysmart.doc:267
\sm@computeext, xysmart.doc:392
\sm@conn, xysmart.doc:165
\sm@conndraw, xysmart.doc:447
\sm@connect@, xysmart.doc:509
\sm@drawseg, xysmart.doc:462
\sm@drawseglist, xysmart.doc:454
\sm@drop@, xysmart.doc:512
\sm@maxcost, xysmart.doc:162
\sm@nil, xysmart.doc:160
\sm@nnil, xysmart.doc:161
\sm@roundcount@, xysmart.doc:284
\sm@showext, xysmart.doc:361
\sm@straight, xysmart.doc:491
\sm@stri, xysmart.doc:505
\sm@trycirclelist, xysmart.doc:301

                                             \sm@trycirclelist@i, xysmart.doc:367
                                             \sm@trycircles, xysmart.doc:221
                                             \sm@tryclcar, xysmart.doc:373
                                             \smap@, xy.doc:2761
                                             \smapp@@, xy.doc:2769
                                             \smapxy@@, xy.doc:2767
                                             \smapxy@i, xy.doc:2771
                                             \smconn, xysmart.doc:519
                                             \Solid, xyv2.doc:303
                                             \solid, xyv2.doc:302
                                             \Solid , 557
                                             \solid , 557
                                             \solid@, xy.doc:5166
                                             \solidcircle@, xycurve.doc:4542
                                             \solidcorner@, xyframe.doc:362
                                             \solidhrule@, xy.doc:5262
                                             \solidhrule@pre, xy.doc:5265
                                             \solidhrule@typeset, xy.doc:5284
                                             \solidhrule@typeset@, xy.doc:5291
                                             \solidpoint@, xy.doc:5910
                                             \solidSpread@, xy.doc:5186
                                             \solidvrule@, xy.doc:5223
                                             \solidvrule@pre, xy.doc:5226
                                             \solidvrule@typeset, xy.doc:5245
                                             \solidvrule@typeset@, xy.doc:5252
                                             \space@, xyidioms.doc:118

spacing, 354

                                             \spline@@find, xycurve.doc:3141
                                             \spline@@knot, xycurve.doc:3178
                                             \spline@end@, xycurve.doc:3071
                                             \spline@end@@, xycurve.doc:3074
                                             \spline@find, xycurve.doc:3115
                                             \splineadvance@@, xycurve.doc:2355
                                             \splinealong@, xycurve.doc:1238
                                             \splinealong@@, xycurve.doc:1265
                                             \splineBErec@, xycurve.doc:2762
                                             \splinebox@, xycurve.doc:2136
                                             \splinebreak@, xycurve.doc:1386
                                             \splinebreakcancel@, xycurve.doc:3451
                                             \splineBreakEndtest@, xycurve.doc:2440
                                             \splineBreakStarttest@, xycurve.doc:2437
                                             \splineBrec@, xycurve.doc:2736
                                             \splineBSrec@, xycurve.doc:2746
                                             \splinecancel@, xycurve.doc:3443
                                             \splineclosest@, xycurve.doc:1595
                                             \splineconn@, xycurve.doc:2331
                                             \splineConnect@, xycurve.doc:4836
                                             \splineconnect@, xycurve.doc:1064
                                             \splinecontinue, xycurve.doc:2391

\splinecontinue@, xycurve.doc:2385
\splinecontinue@@, xycurve.doc:2388
\splined@@@, xycurve.doc:2417
\splineDadvance@, xycurve.doc:3059
\splineDadvance@@, xycurve.doc:3061
\splinedashed@, xycurve.doc:3306
\splinedbldotted@, xycurve.doc:3313
\splinedefaulttol@, xycurve.doc:2283
\splinedepth@, xycurve.doc:2147
\splinedotted@, xycurve.doc:3310
\splinedoubled@, xycurve.doc:3297
\splineDrop@, xycurve.doc:4832
\splinedrop@, xycurve.doc:2316
\splineEdge, xycurve.doc:822
\splineendScan@, xycurve.doc:2527
\splineEndtest, xycurve.doc:2445
\splineEndtest@, xycurve.doc:2434
\splineErec@, xycurve.doc:2685
\splineextra@@, xycurve.doc:2340
\splinef@breakpt, xycurve.doc:2779
\splinef@end, xycurve.doc:3211
\splinef@pt, xycurve.doc:3212
\splinef@pt@@, xycurve.doc:2786
\splinefcontinue@, xycurve.doc:3186
\splinefindBEnd@, xycurve.doc:2946
\splinefindBStart@, xycurve.doc:2884
\splinefindEnd@, xycurve.doc:2696
\splinefindEnd@@, xycurve.doc:2665
\splinefindStart@, xycurve.doc:2632
\splinefindStart@@, xycurve.doc:2624
\splinefindtest@, xycurve.doc:3198
\splinefinish@, xycurve.doc:3461
\splinefinish@@, xycurve.doc:3441
\splinefinishf@, xycurve.doc:3094
\splinefocus@, xycurve.doc:3236
\splinefrec@, xycurve.doc:3081
\splineglue@, xycurve.doc:3425
\splinegoal@, xycurve.doc:3455
\splineHadvance@, xycurve.doc:1821
\splineHadvance@i, xycurve.doc:1822
\splineHadvance@x, xycurve.doc:1825
\splineHnear@test, xycurve.doc:1769
\splineignore@, xycurve.doc:2178
\splineinsidehull@, xycurve.doc:1731
\splineintercept@, xycurve.doc:1470
\splineintercept@i, xycurve.doc:1472
\splineinterceptTest@, xycurve.doc:1582
\splineIplace@, xycurve.doc:1495
\splineIrec@, xycurve.doc:1509

                                             \splineIsegment@, xycurve.doc:1523
                                             \splineknotpoint@, xycurve.doc:2400
                                             \splineknotpoint@@, xycurve.doc:2402
                                             \splinelast@, xycurve.doc:1403
                                             \splinelength@, xycurve.doc:2158
                                             \splinenear@, xycurve.doc:2344
                                             \splineNointercept@, xycurve.doc:1456
                                             \splinenostart@, xycurve.doc:2523
                                             \splineoutsidehull@, xycurve.doc:1750
                                             \splineoutsidehull@@, xycurve.doc:1753
                                             \splineplot@maybe, xycurve.doc:2451
                                             \splineplot@maybe@@, xycurve.doc:2452
                                             \splineplotpt@, xycurve.doc:3417
                                             \splinepoint, xycurve.doc:2383
                                             \splinepoint@, xycurve.doc:2381
                                             \splinepoint@@, xycurve.doc:2377
                                             \splineRecordBreakEValue, xycurve.doc:3021
                                             \splineRecordBreakValue@, xycurve.doc:2980
                                             \splineRecordEBreakValue@, xycurve.doc:2908
                                             \splineRecordEndBreakValue@, xycurve.doc:2993
                                             \splineRecordEndValue@, xycurve.doc:2969
                                             \splineRecordSBreakValue@, xycurve.doc:2916
                                             \splineRecordValue@, xycurve.doc:2958
                                             \splinereset@, xycurve.doc:1110
                                             \splinereverse@@, xycurve.doc:2676
                                             \splinereverse@@@, xycurve.doc:2677
                                             \splineribboned@, xycurve.doc:3300
                                             \splinescan@, xycurve.doc:2465
                                             \splinescanbreak@, xycurve.doc:2544
                                             \splinescanEndtest, xycurve.doc:2729
                                             \splinescanStarttest, xycurve.doc:2724
                                             \splinesegment@, xycurve.doc:3239
                                             \splineset@, xycurve.doc:3252
                                             \splineset@@, xycurve.doc:3325
                                             \splinesetting@, xycurve.doc:3402
                                             \splinesetting@@, xycurve.doc:3404
                                             \splineshavec@, xycurve.doc:1138
                                             \splineshavep@, xycurve.doc:1129
                                             \splineSintercept@, xycurve.doc:1665
                                             \splineslidec@, xycurve.doc:1167
                                             \splineslidec@@, xycurve.doc:1219
                                             \splineslidec@@@, xycurve.doc:1172
                                             \splineslidemore@, xycurve.doc:1198
                                             \splineslidep@, xycurve.doc:1149
                                             \splineslidep@@@, xycurve.doc:1153
                                             \splineslowEnd@, xycurve.doc:2517
                                             \splineSlowEndtest, xycurve.doc:2449
                                             \splineslowScan@, xycurve.doc:2511
                                             \splineSlowStarttest, xycurve.doc:2447

\splinesolid@, xycurve.doc:3294
\splineSrec@, xycurve.doc:2614
\splinestartScan@, xycurve.doc:2493
\splineStarttest, xycurve.doc:2444
\splineStarttest@, xycurve.doc:2432
\splinetest@, xycurve.doc:3073
\splinetestcvxhull@, xycurve.doc:1726
\splinetol@, xycurve.doc:2152
\splinetolerance, xycurve.doc:2285
\splinetolerance@, xycurve.doc:2279
\splinetooclose@, xycurve.doc:2365
\splinetooclose@@, xycurve.doc:2366
\splinetrace@, xycurve.doc:2179
\splinetracing, xycurve.doc:2177
\splinetrebled@, xycurve.doc:3303
\splineTrec@, xycurve.doc:3380
\splineval@, xycurve.doc:2142
\splinewhich, xycurve.doc:3462
\splinewideend, xycurve.doc:2605
\splinewidestart, xycurve.doc:2597
\splinezeroend, xycurve.doc:2590
\splinezerostart, xycurve.doc:2584
\splitRadius@, xyarc.doc:302
\splitRadius@dim, xyarc.doc:293
\spop@, xy.doc:2735
\Spread@@, xy.doc:8043
\spreaddiagramcolumns, xyv2.doc:566
\spreaddiagramcolumns , 561
\spreaddiagramrows, xyv2.doc:565
\spreaddiagramrows , 561
\spushc@, xy.doc:2716
\spushid@, xy.doc:2720
\squarify, xyv2.doc:442
\squarify , 559
\squash, xyv2.doc:425
\squash , 559
\squiggle@, xy.doc:5402
\squiggle@@, xy.doc:5413
\squiggledSpread@, xy.doc:5429

squiggles, 14

\squine@start@, xycurve.doc:3659
\squineconnect@, xycurve.doc:3515
\squined@, xycurve.doc:3669
\squined@@, xycurve.doc:3673
\squineDadvance@@@, xycurve.doc:3594
\squinedecast@, xycurve.doc:3579
\squineDwhich@, xycurve.doc:3472
\squineIadvance@, xycurve.doc:1513
\squineinfo@, xycurve.doc:3633

                                             \squineIpt@, xycurve.doc:1511
                                             \squineplot@maybe, xycurve.doc:3596
                                             \squinerec@, xycurve.doc:3590
                                             \squinereverse@, xycurve.doc:3643
                                             \squinesegment@, xycurve.doc:3518
                                             \squinesetparams@, xycurve.doc:3665
                                             \squinetestcvxhull@, xycurve.doc:1605
                                             \squinewhich@, xycurve.doc:3464
                                             \ssize , 555
                                             \Ssolid, xyv2.doc:304
                                             \Ssolid , 557
                                             \sssize , 555
                                             \ssz, xycurve.doc:203
                                             \STACK@, xy.doc:2698
                                             \STACK@load, xy.doc:2711
                                             \startxycurve@, xycurve.doc:1916
                                             \startxycurve@@, xycurve.doc:1910

state, 21

                                             \stdsplineconn@, xycurve.doc:2332

⟨step⟩, 458

                                             \stop, xyv2.doc:348
                                             \stop , 558
                                             \stopper@, xy.doc:5693
                                             \stopper@@, xy.doc:5695
                                             \straight@, xy.doc:8046
                                             \straight@typeset, xy.doc:8071
                                             \straightArc@, xyarc.doc:1310
                                             \straightCbreak@, xy.doc:8093
                                             \straightcheckoverlap@, xy.doc:8067
                                             \straightClast@, xy.doc:8103
                                             \straighth@, xy.doc:8149
                                             \straightv@, xy.doc:8176
                                             \straitalong@, xycurve.doc:1022
                                             \straitbreak@, xycurve.doc:1057
                                             \straitconnect@, xycurve.doc:984
                                             \straitintercept@, xycurve.doc:1056
                                             \straitlast@, xycurve.doc:1058
                                             \straitreset@, xycurve.doc:1000
                                             \straitshavec@, xycurve.doc:1013
                                             \straitshavep@, xycurve.doc:1006
                                             \straitslidec@, xycurve.doc:1004
                                             \straitslidep@, xycurve.doc:1003
                                             \stripRCS, xy.doc:412
                                             \stripRCS , 13
                                             \stripRCS@, xy.doc:413
                                             \stripRCS@@, xy.doc:415

style, 56

                                             style [bevel], xyline.doc:251
                                             style [butt], xyline.doc:255

style [miter], xyline.doc:253
style [projcap], xyline.doc:257
style [roundcap], xyline.doc:256
style [roundjoin], xyline.doc:252
style [thicker], xyline.doc:119
style [thinner], xyline.doc:118

style option, 11

\styledboxz@, xy.doc:3908
\supermorphism, xy2cell.doc:160
\swap, xyv2.doc:270
\swap , 557
\swap@, xy.doc:1639
\swapdimen@, xy.doc:1635
\swaptoks@@, xy.doc:1637

system dependencies, 7

\tartPi@, xytpic.doc:349
\testAND@, xy.doc:316
\testbreakedges@, xycurve.doc:3012
\tests@, xy.doc:2683
\testsplineedges@, xycurve.doc:2484

TEX reference point, 20

\Text, xyv2.doc:168
\Text , 555
\text , 555
\Text@, xyv2.doc:172
\Text@i, xyv2.doc:176
\Text@ii, xyv2.doc:186
\TextC, xyv2.doc:170
\Textures@, xyps.doc:271
\Textures@@, xytextures.doc:47
\texturesColor@@, xytextures.doc:93
\TexturesColor@push, xytextures.doc:76
\TexturesColours@, xytextures.doc:78
\texturesCrayon@, xytextures.doc:115
\texturesCrayon@@, xytextures.doc:114
\texturesCurrpt@, xytextures.doc:177
\texturesCurrpt@@, xytextures.doc:178
\TexturesDict@, xytextures.doc:162
\texturesFrames@, xytextures.doc:233
\texturesFrames@@, xytextures.doc:231
\TexturesInclude@, xytextures.doc:164
\texturesLine@, xytextures.doc:219
\texturesLine@@, xytextures.doc:217
\TexturesMacro@, xytextures.doc:161
\texturesPS@, xytextures.doc:193
\texturesPS@@, xytextures.doc:123
\texturesPStypes@, xytextures.doc:147
\texturesPSunload@, xytextures.doc:124
\TexturesRaw@, xytextures.doc:165

                                             \texturesRotate@, xytextures.doc:205
                                             \texturesRotate@@, xytextures.doc:203
                                             \TexturesSpecial@, xytextures.doc:160
                                             \TexturesSpecialDict@, xytextures.doc:163
                                             \texturesTiles@, xytextures.doc:247
                                             \texturesTiles@@, xytextures.doc:245
                                             \theF, movie.cls:158, xymovie.doc:78
                                             \theFr, movie.cls:159, xymovie.doc:79
                                             \theFrame, movie.cls:155
                                             \thelineno@, xy.doc:471
                                             \thematrixCOORD@@, xymatrix.doc:804
                                             \thematrixprefix@@, xymatrix.doc:805
                                             \theMOVE@@, xygraph.doc:218
                                             \theScene, movie.cls:156, xymovie.doc:77
                                             \tildeARC@, xyarc.doc:904
                                             \Tip, xyv2.doc:356
                                             \tip, xyv2.doc:352
                                             \Tip , 558
                                             \tip , 558
                                             \Tip@, xy.doc:5644
                                             \tip@, xy.doc:5620
                                             \Tip@@, xy.doc:5651
                                             \tip@@, xy.doc:5629
                                             \Tip@@eu, xytips.doc:146
                                             \tip@cm, xytips.doc:124
                                             \Tip@eu, xytips.doc:140
                                             \tip@x, xy.doc:5624
                                             \Tip@xy, xytips.doc:52
                                             \tip@xy, xytips.doc:48
                                             tipfamily cm, xytips.doc:115
                                             tipfamily eu, xytips.doc:136
                                             \tipfamily@@, xytips.doc:74
                                             \tipjot@, xy.doc:5822
                                             \tipjot@xy, xytips.doc:55
                                             \TIPS, xytips.doc:88

tips, 14

                                             \tipsize@@, xytips.doc:75
                                             \todl, xyv2.doc:705
                                             \todr, xyv2.doc:706
                                             \toks@, 17
                                             \toks@ii, xyidioms.doc:188, xyidioms.doc:208
                                             \told, xyv2.doc:701
                                             \tolu, xyv2.doc:702
                                             \ToPOS, xy.doc:4554
                                             \toradians@, xy.doc:2048
                                             \tord, xyv2.doc:703
                                             \toru, xyv2.doc:704
                                             \toul, xyv2.doc:707
                                             \tour, xyv2.doc:708

\toXY@, xyv2.doc:680
\TPIC, xytpic.doc:32
\TPICalternative@, xytpic.doc:190
\transformConnect@, xyrotate.doc:222
\transformDrop@, xyrotate.doc:218
\transformstyle@, xy.doc:4122
\transformstyle@@, xy.doc:4121
\transxyline@, xyline.doc:608
\transxyline@@, xyline.doc:610
\TrefoilA, xyknot.doc:1466
\TrefoilB, xyknot.doc:1476
\TrefoilC, xyknot.doc:1486
\triple@, xy.doc:5474
\triplecircle@, xycurve.doc:4650
\trpldottedcircle@, xycurve.doc:4672
\tsize , 555
\Ttip, xyv2.doc:364
\Ttip , 558
\Ttip@, xy.doc:5660
\Ttip@@, xy.doc:5667
\Ttip@@eu, xytips.doc:159
\Ttip@eu, xytips.doc:152
\Ttip@xy, xytips.doc:53

⟨turn⟩, 446

\TurnRadius, xyv2.doc:717
\turnradius, xyarrow.doc:872
\turnradius , 305
\turnradius@, xyarrow.doc:870
\tw@@cell@, xy2cell.doc:467
\tw@@cell@@, xy2cell.doc:691
\tw@cell@, xy2cell.doc:463
\tw@cell@@, xy2cell.doc:693
\tw@cell@@@, xy2cell.doc:281
\twocell, xy2cell.doc:1246
\twocell@, xy2cell.doc:267
\twocell@@, xy2cell.doc:1449
\twocell@@@@, xy2cell.doc:1232
\twocell@DONE, xy2cell.doc:1384
\twocell@path, xy2cell.doc:1193
\twocellhead, xy2cell.doc:453
\twocellhead@, xy2cell.doc:455
\twocelll, xy2cell.doc:1251
\twocellmod@, xy2cell.doc:462
\twocellPATH, xy2cell.doc:1224
\twocellpath, xy2cell.doc:1207
\twocellstyle, xy2cell.doc:365
\twocelltail, xy2cell.doc:454
\twocelltail@, xy2cell.doc:456
\twodecimals@, movie.cls:228

                                             \twoPi@, xycurve.doc:4446
                                             \txt, xy.doc:6331
                                             \txt , 89
                                             \txt@, xy.doc:6333
                                             \txt@i, xy.doc:6337
                                             \txt@ii, xy.doc:6354
                                             \txtline@, xy.doc:6343
                                             \txtline@@, xy.doc:6342
                                             \typesetoutline@, xy.doc:4895

U, 20 U, 23, 40

                                             \U@c, xy.doc:613
                                             \U@p, xy.doc:621

U_{c}, 21 U_{p}, 21

                                             \ubraced, xyframe.doc:736
                                             \Uc, xyv2.doc:214

\Uc , 556

                                             \ucurveObject@, xy2cell.doc:1090
                                             \uDirection@, xy.doc:7095
                                             \ulDirection@, xy.doc:7101
                                             \unenter@, xy.doc:775
                                             \uninstallEMline@, xyemtex.doc:207
                                             \UninstallPolylines@, xyline.doc:529
                                             \uninstallTPICcurves@, xytpic.doc:417
                                             \uninstallTPICframes@, xytpic.doc:435
                                             \uninstallTPICline@, xytpic.doc:323
                                             \UnloadColor@, xycolor.doc:108
                                             \UnloadColor@@, xycolor.doc:113
                                             \UnloadDVITOPSrotate@, xydvitops.doc:252
                                             \UnloadFrames@, xyframe.doc:1130
                                             \UnloadLine@, xyline.doc:561
                                             \Unloadpattern@, xytile.doc:221
                                             \UnloadpolySpecials@, xyline.doc:470
                                             \UnloadPS@, xyps-ps.doc:87
                                             \UnloadPS@@, xyps-ps.doc:90
                                             \UnloadPSpatterns@, xyps-t.doc:88
                                             \UnloadPSps@, xyps-ps.doc:71
                                             \UnloadRotate@, xyrotate.doc:362
                                             \Unloadstyle@, xy.doc:3994
                                             \unsetupDirection@, xy.doc:7327
                                             \unsilencexy@, xy.doc:1546
                                             \Up, xyv2.doc:221

\Up , 556

                                             \uparenthesized, xyframe.doc:831
                                             \Upness@, xy.doc:3223
                                             \uppercurveobject, xy2cell.doc:1088
                                             \uppertwocell, xy2cell.doc:1247
                                             \uppertwocell@, xy2cell.doc:269

\uppertwocelll, xy2cell.doc:1255
\urDirection@, xy.doc:7090
\UseAllTwocells, xy2cell.doc:142
\UseCompositeMaps, xy2cell.doc:138
\UseComputerModernTips, xycmtip.doc:51
\UseCrayolaColors, xycolor.doc:269
\UseCrayolaColors , 235
\UseCurveFrames, xyframe.doc:1117
\UseCurveFrames@, xyframe.doc:1114
\UseDVIPSspecials, xyps.doc:235
\UseDVITOPSspecials, xyps.doc:240
\UseEMlinewidth, xyemtex.doc:211
\UseEMspecials, xyemtex.doc:60
\UseFontFrames, xyframe.doc:1122
\UseFontFrames@, xyframe.doc:1119
\UseHalfTwocells, xy2cell.doc:130
\UseOzTeXspecials, xyps.doc:239
\usepackage , 11
\UsePatternFile, xytile.doc:278
\UsePostScriptSpecials, xyps.doc:238
\UsePS@specials, xyps.doc:186
\UsePScolor, xyps-c.doc:73
\UsePSframes, xyps-f.doc:74
\UsePSheader {<filename>}, 260
\UsePSheader {}, 260
\UsePSheader@, xyps-ps.doc:509, xyps.doc:634
\UsePSlines, xyps-l.doc:86
\UsePSrotate, xyps-r.doc:89
\UsePSspecials, xyps.doc:171
\UsePSspecials {}, 255
\UsePSspecials@, xyps.doc:290
\UsePSspecials@i, xyps.doc:172
\UsePSspecials@x, xyps.doc:315
\UsePStiles, xyps-t.doc:90
\UseResizing, xyrotate.doc:121
\UseRules, xy.doc:5215
\UseRules , 74
\UseSingleDriver, xy.doc:6698
\UseSingleDriver , 93
\UseTexturesPSspecials, xyps.doc:236
\UseTexturesSpecials, xyps.doc:237
\UseTips, xytips.doc:174
\UseTips , 216
\UseTPICframes, xytp-f.doc:62
\UseTPICspecials, xytpic.doc:62
\UseTwocells, xy2cell.doc:126
\uutol, xyv2.doc:698
\uutor, xyv2.doc:699

v, 46

                                             \Vcap, xyknot.doc:1983
                                             \vcap, xyknot.doc:1549
                                             \Vcross, xyknot.doc:1953
                                             \vcross, xyknot.doc:381
                                             \vcrossneg, xyknot.doc:389
                                             \vDirection@, xy.doc:7299

⟨vector⟩, 23

                                             \VECTOR@, xy.doc:1420
                                             \VECTOR@a, xy.doc:1435
                                             \VECTOR@letter, xy.doc:1432
                                             \VECTOR@other, xy.doc:1477
                                             \VECTOR@other@open, xy.doc:1498

version, 7, 13

                                             \vfromabsolute@, xy.doc:1647
                                             \vfromabsolute@@, xy.doc:1649
                                             \vfromcartesian@, xy.doc:1863
                                             \vfromcartesian@@, xy.doc:1865
                                             \vfromcartesianangle@, xy.doc:1955
                                             \vfromslide@, xy.doc:2514
                                             \vfromslide@i, xy.doc:2517
                                             \vloop, xyknot.doc:1612
                                             \vover, xyknot.doc:474
                                             \vtwist, xyknot.doc:654
                                             \vtwistneg, xyknot.doc:662
                                             \vuncross, xyknot.doc:397
                                             \vunder, xyknot.doc:484
                                             \vunover, xyknot.doc:494
                                             \vuntwist, xyknot.doc:670
                                             \W@, xyidioms.doc:116
                                             \W@max, xymatrix.doc:522
                                             \W@maxin, xymatrix.doc:499
                                             \W@maxout, xymatrix.doc:500
                                             Warning, 14

warning messages, 3

                                             \Wcol@C, xymatrix.doc:538
                                             \Wcol@c@@, xymatrix.doc:498
                                             \Wcol@HWmax, xymatrix.doc:544
                                             \Wcol@in, xymatrix.doc:496
                                             \Wcol@max, xymatrix.doc:541
                                             \Wcol@out, xymatrix.doc:497
                                             \wdz@, xyidioms.doc:113
                                             \whichCurveObject@, xy2cell.doc:480
                                             \whichframe@@, xyframe.doc:1015
                                             \whichinfo, xy2cell.doc:826
                                             \whichnudge, xy2cell.doc:825
                                             \whichoptions@@, xyframe.doc:1016
                                             \whichPSspecials@, xyps.doc:310
                                             width, 251
                                             \writeoutline@, xy.doc:4878

\writeoutline@@, xy.doc:4866
\writePSdict@@, xyps-ps.doc:533

X, 20

\X, xyframe.doc:898

x, 23, 38

\X@c, xy.doc:611
\X@max, xy.doc:636
\X@min, xy.doc:634
\X@origin, xy.doc:627
\X@p, xy.doc:619
\X@xbase, xy.doc:629
\X@ybase, xy.doc:631

X_{origin}, 21 X_{xbase}, 21 X_{ybase}, 21 X_{c}, 21 X_{p}, 21 X_{max}, 20 X_{min}, 20

\xbendd, xyknot.doc:1674
\xbendl, xyknot.doc:1666
\xbendr, xyknot.doc:1662
\xbendu, xyknot.doc:1670
\Xc, xyv2.doc:212

\Xc , 556

\Xcap, xyknot.doc:1895
\xcaph, xyknot.doc:1557
\xcapv, xyknot.doc:1553
\xdashed , 561
\xdotted , 561
\xdouble , 561
\xdvi@@, xyxdvi.doc:56
\xdvi@Color@, xyxdvi.doc:87
\xdviColor@@, xyxdvi.doc:102
\xdviCrayola@, xyxdvi.doc:136
\xdviCrayola@@, xyxdvi.doc:134
\xdviCurrpt@, xyxdvi.doc:213
\xdviCurrpt@@, xyxdvi.doc:214
\xdviDict@, xyxdvi.doc:182
\xdviFrames@, xyxdvi.doc:270
\xdviFrames@@, xyxdvi.doc:268
\xdviInclude@, xyxdvi.doc:183
\xdviLine@, xyxdvi.doc:257
\xdviLine@@, xyxdvi.doc:255
\xdviMacro@, xyxdvi.doc:181
\xdviPS@, xyxdvi.doc:225
\xdviPS@@, xyxdvi.doc:153
\xdviPS@unload, xyxdvi.doc:155
\xdviPStypes@, xyxdvi.doc:166

                                             \xdviRaw@, xyxdvi.doc:184
                                             \xdviRotate@, xyxdvi.doc:237
                                             \xdviRotate@@, xyxdvi.doc:235
                                             \xdviRotScale@, xyxdvi.doc:244
                                             \xdviSpecial@, xyxdvi.doc:180
                                             \xdviTiles@, xyxdvi.doc:283
                                             \xdviTiles@@, xyxdvi.doc:281
                                             \xdviTPIC@, xyxdvi.doc:296
                                             \xdviTPIC@@, xyxdvi.doc:294
                                             \xline , 561
                                             \Xmax, xyv2.doc:238
                                             \Xmax , 556
                                             \Xmin, xyv2.doc:236
                                             \Xmin , 556
                                             \Xorigin, xyv2.doc:229
                                             \Xorigin , 556
                                             \Xover, xyknot.doc:1870
                                             \xoverh, xyknot.doc:515
                                             \xoverv, xyknot.doc:505
                                             \Xp, xyv2.doc:219

\Xp , 556

                                             \xto , 561
                                             \Xtwist, xyknot.doc:1845
                                             \xunderh, xyknot.doc:520
                                             \xunderv, xyknot.doc:510
                                             \Xunover, xyknot.doc:1882
                                             \xunover, xyknot.doc:525
                                             \xunoverh, xyknot.doc:535
                                             \xunoverv, xyknot.doc:530
                                             \Xuntwist, xyknot.doc:1855
                                             \Xxbase, xyv2.doc:231
                                             \Xxbase , 556
                                             \XXover, xyknot.doc:1916
                                             \XXtoY@, xyv2.doc:673
                                             \XXtwist, xyknot.doc:1930
                                             \XY, xyv2.doc:67
                                             \Xy, xy.doc:451
                                             \xy, xy.doc:1109

xy, 215

                                             \Xy , 13

\xy , 19–22, 64

XY-pic, 13

XY-picture state, 21

                                             xy.sty, 11
                                             \xy@, xy.doc:857
                                             \xy@@, xy.doc:886
                                             \xy@@atfont, xytips.doc:61
                                             \xy@@btfont, xytips.doc:62
                                             \xy@@crvaddstack, xycurve.doc:940

\xy@@crvaddstack@, xycurve.doc:945
\xy@@crvmods@, xycurve.doc:650
\xy@@crvmods@@, xycurve.doc:661
\xy@@crvmods@@@, xycurve.doc:662
\xy@@samecurve@, xycurve.doc:340
\xy@begindvi, xyidioms.doc:165
\xy@cosabs@@, xymatrix.doc:301
\xy@cossign@@, xymatrix.doc:299
\xy@cotabs@@, xymatrix.doc:304
\xy@crv@mods@@, xycurve.doc:655
\xy@crvmods@, xycurve.doc:637
\xy@crvmods@@, xycurve.doc:643
\xy@crvmods@@@, xycurve.doc:656
\xy@crvmods@@@@, xycurve.doc:641
\xy@curve@, xycurve.doc:599
\xy@curve@@, xycurve.doc:600
\xy@curve@@@, xycurve.doc:601
\xy@end, xy.doc:1167
\xy@linecap@, xyline.doc:307
\xy@linecap@@, xyline.doc:557
\xy@linecap@i, xyline.doc:299
\xy@linejoin@, xyline.doc:330
\xy@linejoin@@, xyline.doc:558
\xy@linejoin@i, xyline.doc:300
\xy@linemiter@, xyline.doc:355
\xy@linemiter@@, xyline.doc:559
\xy@linemiter@i, xyline.doc:301
\xy@maxX@@, xymatrix.doc:440
\xy@maxY@@, xymatrix.doc:442
\xy@minX@@, xymatrix.doc:439
\xy@minY@@, xymatrix.doc:441
\xy@newCOORD@, xynecula.doc:67
\xy@newOBJECT@, xynecula.doc:57
\xy@oldCOORD@, xynecula.doc:66
\xy@oldOBJECT@, xynecula.doc:56
\xy@polystyle@, xyline.doc:478
\xy@polystyle@@, xyline.doc:527
\xy@sinabs@@, xymatrix.doc:302
\xy@sinsign@@, xymatrix.doc:300
\xy@spline@, xycurve.doc:4775
\xy@spline@g, xycurve.doc:4804
\xy@spline@i, xycurve.doc:4784
\xy@spline@ii, xycurve.doc:4788
\xy@spline@ii@@, xycurve.doc:4798
\xy@spline@iii, xycurve.doc:4800
\xy@spline@iv, xycurve.doc:4813
\xy@spline@v, xycurve.doc:4822
\xy@spline@x, xycurve.doc:4827
\xy@style@, xy.doc:3969

                                             \xy@tanabs@@, xymatrix.doc:303
                                             \xy@transform@, xyrotate.doc:192
                                             \xyactive@Warning, xycurve.doc:516
                                             \xyadddriversupport@, xy.doc:6831
                                             \xyaddsupport, xy.doc:6828
                                             \xyaddsupport , 95
                                             \xyaddunsupport, xy.doc:6829
                                             \xyaddunsupport , 95
                                             \xyadjustBREAK@i, xyknot.doc:1196
                                             \xyadjustJOIN@i, xyknot.doc:1189
                                             \xyadjustknotPLACE@, xyknot.doc:1161
                                             \xyadjustknotPLACE@@, xyknot.doc:1169
                                             \xyadjustknotPLACE@i, xyknot.doc:1155
                                             xyatip10, 14
                                             \xyatipfont, xy.doc:567
                                             \xyatipfont , 14, 15, 80
                                             \Xybase, xyv2.doc:233
                                             \Xybase , 556
                                             \xyBEcolorcheck@, xycolor.doc:295
                                             \xybox, xy.doc:3390
                                             \xybox , 46
                                             \xybspline@, xycurve.doc:3975
                                             \xybspline@iii, xycurve.doc:3955
                                             \xybspline@iv, xycurve.doc:3963
                                             \xybsplinemethods@, xycurve.doc:3983
                                             xybsql10, 14
                                             \xybsqlfont, xy.doc:570

\xybsqlfont , 14, 15, 77, 81, 82

                                             \xybsqlh@, xy.doc:572
                                             \xybsqll@, xy.doc:571
                                             \xybsqlw@, xy.doc:573
                                             xybtip10, 14
                                             \xybtipfont, xy.doc:568
                                             \xybtipfont , 14, 15, 80
                                             \xybug@, xy.doc:489
                                             \xyc@trlpts@, xycurve.doc:1950
                                             \xyc@trlpts@@, xycurve.doc:1952
                                             \xyc@vxhull@, xycurve.doc:1955
                                             \xyc@vxhull@@, xycurve.doc:1958
                                             \xycapSpecial@@, xyline.doc:324
                                             \xycatcodes, xy.doc:58
                                             \xycatcodes , 4, 92
                                             \xycheck@end, xy.doc:1165
                                             \xycheck@end@, xy.doc:1166
                                             xycirc10, 14
                                             \xycircfont, xy.doc:575
                                             \xycircfont , 14, 15, 87
                                             \xycircle, xycurve.doc:4463
                                             \xycircle@, xycurve.doc:4466

\xycircle@i, xycurve.doc:4473
\xycircleframe@x@, xyframe.doc:1098
\xycircleframe@x@i, xyframe.doc:1101
\xycircleframe@x@x, xyframe.doc:1111
\xyclearcrv@, xycurve.doc:1843
\xyclosedown@@, xyidioms.doc:155
\xycolor@, xycolor.doc:105
\xycolor@@, xycolor.doc:102
\xycolor@begin, xydvitops.doc:121
\xycolor@end, xydvitops.doc:122
\xycolor@pop, xycolor.doc:159
\xycolor@push, xycolor.doc:160
\xycolor@push@@, xycolor.doc:158
\xycolor@raw@@, xyps-c.doc:139
\xycolormessage@, xycolor.doc:83
\xycolorwarning@, xycolor.doc:81
\xycolorwarning@@, xycolor.doc:77
\xycomment@, xy.doc:4789
\xycompile, xy.doc:4738
\xycompile , 65, 67
\xycompile@@, xy.doc:4731
\xycompiled, xy.doc:4805
\xycompileno@@, xy.doc:4732
\xycompileto, xy.doc:4746
\xycompileto , 65
\xycontrolpt, xycurve.doc:1895
\xycontrolpt@, xycurve.doc:1883
\xyCOORD@, xy.doc:1508
\xyCOORD@letter, xy.doc:1515
\xyCOORD@other, xy.doc:1528
\xyCOORD@other@open, xy.doc:1548
\xycroplattice@, xyweb.doc:193
\xycrvconn@, xycurve.doc:1948
\xycrvdrop@, xycurve.doc:1947
\xycrvmods@, xycurve.doc:635
\xyctrlpts, xycurve.doc:2019
\xyctrlpts@, xycurve.doc:2011
\xycubicbezier@, xycurve.doc:3691
\xycubicmethods@, xycurve.doc:3697
\xycurve@, xycurve.doc:595
\xycurve@@, xycurve.doc:597
\xycvxhull, xycurve.doc:2085
\xycvxhull@, xycurve.doc:2070
\xycvxhulldrop@, xycurve.doc:2087
xyd.mf, 15
xyd2.mf, 15
xydash10, 14
\xydashfont, xy.doc:562

\xydashfont , 14, 15, 72, 74, 81

                                             \xydashh@, xy.doc:564
                                             \xydashl@, xy.doc:563
                                             \xydashw@, xy.doc:565
                                             \xydate, xy.doc:421
                                             \xydate , 13
                                             \xydecagon@@, xypoly.doc:1021
                                             \xydef@, xy.doc:39, 3
                                             \xydefaultdriver@, xyps-ps.doc:196
                                             \xydefcsname@, xy.doc:201
                                             \xydelayimport@, xyimport.doc:114
                                             \XYdict@, xyps-ps.doc:599
                                             \XYdict@@, xyps-ps.doc:600
                                             \xydist@, xycurve.doc:3045
                                             \xydodecagon@@, xypoly.doc:1109
                                             \xydopoly@style, xyline.doc:491
                                             \xydopoststyles@, xy.doc:3942
                                             \xydopoststyles@@, xy.doc:3940
                                             \xydoprestyles@, xy.doc:3941
                                             \xydoprestyles@@, xy.doc:3939
                                             \xydoTPICcircle@, xytpic.doc:335
                                             \xydriver@unload@support@@, xy.doc:6668
                                             \xydriverfail@, xy.doc:6935
                                             \xydrivernoload@, xy.doc:6932
                                             \xydriversloaded@@, xy.doc:6655
                                             \xydriversselected@@, xy.doc:6656
                                             \xydropRotated@, xyrotate.doc:400
                                             \xydropRotated@@, xyrotate.doc:398
                                             \xydummyrequires@@, xydummy.doc:46
                                             \xyDVITOPScolor@, xydvitops.doc:99
                                             \xyDVITOPScolor@i, xydvitops.doc:103
                                             \xyeat@, xy.doc:4679
                                             \xyeatall@, xymatrix.doc:382
                                             \xyecho, xy.doc:4619
                                             \xyecho , 66
                                             \xyecho@, xy.doc:4622
                                             \xyellipseframe@x@, xyframe.doc:1099
                                             \xyEM@noisy, xyemtex.doc:84
                                             \xyEM@special, xyemtex.doc:80
                                             \xyEMlinewidth@, xyemtex.doc:200
                                             \xyEMstraight@, xyemtex.doc:151
                                             \xyemtex@line, xyemtex.doc:71
                                             \xyemtex@lineto, xyemtex.doc:69
                                             \xyemtex@moveto, xyemtex.doc:70
                                             \xyemtex@pen, xyemtex.doc:73
                                             \xyemtex@point, xyemtex.doc:72
                                             \xyemtex@solid@, xyemtex.doc:146
                                             \xyemtex@splinesolid@, xyemtex.doc:189
                                             \xyendcompiled, xy.doc:4815
                                             \xyenddocmode@, xy.doc:6586

\xyendinput, xy.doc:6575
\xyendinput , 91, 92, 95
\xyerror@, xy.doc:479
\xyerror@RC, xymatrix.doc:867
\xyescape@@, xyps-s.doc:70
\xyescapeSpecial@, xyps-s.doc:76, xyps-s.doc:77
\xyevery@, xy.doc:6483
\xyeveryrequest, xy.doc:6489
\xyeveryrequest , 91
\xyeverywithoption, xy.doc:6490
\xyeverywithoption , 91
\xyexportwarning@, xyimport.doc:127
\xyextern@, xyimport.doc:117
\xyextern@i, xyimport.doc:119
\xyextern@ii, xyimport.doc:123
\xyextern@x, xyimport.doc:130
\xyFN@, xyidioms.doc:108
\xyfont@, xy.doc:559
\xygetfilepatterns@, xytile.doc:267
\xygetknotPLACE@@, xyknot.doc:1181
\xygetpolyprefix@, xypoly.doc:274
\xygetpostBREAK@, xyknot.doc:1202
\xygraph, xygraph.doc:162
\xygraph , 361
\Xygreet@, xy.doc:423
\xyhcap, xyknot.doc:1567
\xyhcross, xyknot.doc:413
\xyhcrossneg, xyknot.doc:419
\xyheptagon@@, xypoly.doc:919
\xyhexagon@@, xypoly.doc:893
\xyhloop, xyknot.doc:1618
\xyhover, xyknot.doc:547
\xyhtwist, xyknot.doc:692
\xyhtwistneg, xyknot.doc:698
\xyhuncross, xyknot.doc:425
\xyhunder, xyknot.doc:553
\xyhunover, xyknot.doc:559
\xyhuntwist, xyknot.doc:695
xyidioms.doc, 7
\xyidiomsloaded, xyidioms.doc:25
\xyignore, xy.doc:4675
\xyignore , 65
\xyignore@, xy.doc:4677
\xyignorescale@, xyrotate.doc:291
\xyignoreSizeMod@, xyrotate.doc:402
\xyimport, xyimport.doc:112
\xyimport@, xyimport.doc:113
\xyimportdefault@, xyimport.doc:126
\xyinitial@, xy.doc:854

                                             \xyinputorelse@, xy.doc:735
                                             \xyinputorelse@@, xy.doc:741
                                             \xyinside@, xy.doc:1113
                                             \xyjoinSpecial@@, xyline.doc:349
                                             \xyk@@, xyknot.doc:1138
                                             \xyk@joincontrol@, xyknot.doc:1508
                                             \xykbacktemp@, xyknot.doc:1044
                                             \xykbacktips@, xyknot.doc:1038
                                             \xykbreak@, xyknot.doc:1056
                                             \xykcaph, xyknot.doc:1586
                                             \xykcapv, xyknot.doc:1579
                                             \xykcheckscale@, xyknot.doc:857
                                             \xykcheckTIPS@, xyknot.doc:1272
                                             \xykcross@, xyknot.doc:365
                                             \xykcrossh, xyknot.doc:446
                                             \xykcrossv, xyknot.doc:438
                                             \xykflexbase, xyknot.doc:1833
                                             \xykflexbase@, xyknot.doc:1832
                                             \xykflexiscale@, xyknot.doc:866
                                             \xykflexiscale@@, xyknot.doc:883
                                             \xykforetemp@, xyknot.doc:1041
                                             \xykforetips@, xyknot.doc:1035
                                             \xykhadjust@, xyknot.doc:906
                                             \xykhobject@, xyknot.doc:800
                                             \xykholesize, xyknot.doc:1799
                                             \xykholetemp@, xyknot.doc:1047
                                             \xykhscale@@, xyknot.doc:897
                                             \xykhuadjust@, xyknot.doc:918
                                             \xykhuobject@, xyknot.doc:815
                                             \xykhvadjust@, xyknot.doc:914
                                             \xykhvobject@, xyknot.doc:810
                                             \xykillstyles@, xyps.doc:1042
                                             \xykillstyles@@, xyps-s.doc:50
                                             \xykjoin@, xyknot.doc:1529
                                             \xykjoincontrol, xyknot.doc:1512
                                             \xykjoincontrol@, xyknot.doc:1514
                                             \xykjoincontrol@@, xyknot.doc:1507
                                             \xykjoincontrol@i, xyknot.doc:1520
                                             \xykkeepscale@, xyknot.doc:843
                                             \xyklooph, xyknot.doc:1634
                                             \xykloopv, xyknot.doc:1628
                                             \xykmidbreak@, xyknot.doc:953
                                             \xykmidbreak@@, xyknot.doc:1812
                                             \xykmidPLACE@, xyknot.doc:1816
                                             \xyknegflexscale@, xyknot.doc:893
                                             \xyknegflexscale@@, xyknot.doc:892
                                             \xyknoflexscale@, xyknot.doc:888
                                             \xyknoflexscale@@, xyknot.doc:887
                                             \xyknotTIPS@, xyknot.doc:1804

\xyknottips@, xyknot.doc:1286
\xyknotTIPS@@, xyknot.doc:1805
\xyknulltemp@, xyknot.doc:1055
\xykoverh, xyknot.doc:601
\xykoverstring@, xyknot.doc:368
\xykoverv, xyknot.doc:594
\xykparsebreak@, xyknot.doc:1008
\xykparsecross@, xyknot.doc:324
\xykparsecross@@, xyknot.doc:342
\xykparsejoin@, xyknot.doc:1391
\xykparsejoin@@, xyknot.doc:1424
\xykparsescale@, xyknot.doc:754
\xykparsetips@, xyknot.doc:1243
\xykparsetips@@, xyknot.doc:1248
\xykPLACE@, xyknot.doc:1817
\xykpostbreak@, xyknot.doc:949
\xykpostbreak@@, xyknot.doc:1811
\xykpostPLACE@, xyknot.doc:1815
\xykprebreak@, xyknot.doc:945
\xykprebreak@@, xyknot.doc:1810
\xykprePLACE@, xyknot.doc:1814
\xykrescale@, xyknot.doc:855
\xykrescale@@, xyknot.doc:870
\xyksavescale@, xyknot.doc:822
\xyksbendh, xyknot.doc:1718
\xyksbendv, xyknot.doc:1711
\xykSCALE@@, xyknot.doc:1807
\xykscaleerror@, xyknot.doc:767
\xyksetjoin@, xyknot.doc:1532
\xyktwisth, xyknot.doc:727
\xyktwistv, xyknot.doc:711
\xykuncrossh, xyknot.doc:462
\xykuncrossv, xyknot.doc:454
\xykunderstring@, xyknot.doc:369
\xykunoverh, xyknot.doc:617
\xykunoverv, xyknot.doc:609
\xykuntwisth, xyknot.doc:734
\xykuntwistv, xyknot.doc:719
\xykvadjust@, xyknot.doc:910
\xykvobject@, xyknot.doc:805
\xykvscale@@, xyknot.doc:901
\xykxbendd, xyknot.doc:1750
\xykxbendl, xyknot.doc:1738
\xykxbendr, xyknot.doc:1732
\xykxbendu, xyknot.doc:1744
\xykxcaph, xyknot.doc:1598
\xykxcapv, xyknot.doc:1592
\xykxoverh, xyknot.doc:629
\xykxoverv, xyknot.doc:623

                                             \xykxunoverh, xyknot.doc:642
                                             \xykxunoverv, xyknot.doc:635
                                             \xykz, xyknot.doc:1136
                                             \xykzbendh, xyknot.doc:1704
                                             \xykzbendv, xyknot.doc:1725
                                             \xylargePolygon@, xypoly.doc:1161
                                             \xylattice, xyweb.doc:161
                                             \xylattice@, xyweb.doc:163
                                             \xylet@, xy.doc:40, 3
                                             \xyletcsnamecsname@, xy.doc:211
                                             \xylinecap@, xyline.doc:221
                                             \xylinejoin@, xyline.doc:222
                                             \xylinemiter@, xyline.doc:223
                                             \xylineSpecial@@, xyline.doc:611
                                             \xylinethick@, xyline.doc:132
                                             \xylinewidth@, xyline.doc:587
                                             \xylinewidth@@, xyline.doc:556
                                             \xylinewidth@i, xyline.doc:137
                                             \xyLoadDrivers@, xy.doc:6701
                                             \xyloaded, xy.doc:24
                                             \xylocalColor@, xycolor.doc:106
                                             \xylocalpattern@, xytile.doc:213
                                             \xylowtolerance@, xycurve.doc:2292
                                             \xymakeADD@, xy.doc:306
                                             \xymath@, xy.doc:1110
                                             \xymatrix, xymatrix.doc:238
                                             \xymatrix , 59, 342
                                             \xymatrix@addop, xymatrix.doc:982
                                             \xymatrix@addop@, xymatrix.doc:983
                                             \xymatrix@addop@@, xymatrix.doc:942
                                             \xymatrix@addop@x, xymatrix.doc:989
                                             \xymatrix@at, xymatrix.doc:944
                                             \xymatrix@C, xymatrix.doc:993
                                             \xymatrix@change, xymatrix.doc:1157
                                             \xymatrix@fix, xymatrix.doc:965
                                             \xymatrix@fix@, xymatrix.doc:973
                                             \xymatrix@fix@x, xymatrix.doc:979
                                             \xymatrix@H, xymatrix.doc:998
                                             \xymatrix@ii, xymatrix.doc:255
                                             \xymatrix@insert, xymatrix.doc:693
                                             \xymatrix@insert@, xymatrix.doc:697
                                             \xymatrix@L, xymatrix.doc:996
                                             \xymatrix@M, xymatrix.doc:995
                                             \xymatrix@measureit, xymatrix.doc:552
                                             \xymatrix@measureit@@, xymatrix.doc:568
                                             \xymatrix@mods, xymatrix.doc:1143
                                             \xymatrix@mods@error, xymatrix.doc:1184
                                             \xymatrix@mods@x, xymatrix.doc:1165
                                             \xymatrix@mods@xx, xymatrix.doc:1177

\xymatrix@prefix, xymatrix.doc:242
\xymatrix@pretypeset, xymatrix.doc:348
\xymatrix@R, xymatrix.doc:992
\xymatrix@rotation, xymatrix.doc:306
\xymatrix@set, xymatrix.doc:1153
\xymatrix@setup, xymatrix.doc:247
\xymatrix@typeset, xymatrix.doc:586
\xymatrix@W, xymatrix.doc:999
\xymatrixcolsep, xymatrix.doc:1018
\xymatrixcolsep@, xymatrix.doc:1015
\xymatrixcompile, xymatrix.doc:280
\xymatrixcompile , 343
\xymatrixcompile@, xymatrix.doc:281
\xymatrixCOORD@, xymatrix.doc:807
\xymatrixCOORD@after, xymatrix.doc:863
\xymatrixCOORD@error, xymatrix.doc:835
\xymatrixCOORD@i, xymatrix.doc:813
\xymatrixCOORD@i@d, xymatrix.doc:824
\xymatrixCOORD@i@l, xymatrix.doc:825
\xymatrixCOORD@i@r, xymatrix.doc:826
\xymatrixCOORD@i@u, xymatrix.doc:823
\xymatrixCOORD@ii, xymatrix.doc:828
\xymatrixCOORD@other, xymatrix.doc:839
\xymatrixCOORD@x, xymatrix.doc:847
\xymatrixCOORD@xx, xymatrix.doc:855
\xymatrixnocompile, xymatrix.doc:224
\xymatrixnocompile , 343
\xymatrixprefix@@, xymatrix.doc:240
\xymatrixrowsep, xymatrix.doc:1017
\xymatrixrowsep@, xymatrix.doc:1014
\xymatrixsavedCOORD@, xymatrix.doc:346
\xymidcross@, xyknot.doc:356
\xymiterSpecial@@, xyline.doc:374
\xynamestyle@, xy.doc:4042
\xynamestyle@@, xy.doc:4048
\xynametransform@, xyrotate.doc:255
\xynew@, xy.doc:41, 3
\xyNoColor@, xycolor.doc:101
\xyNoColor@@, xycolor.doc:103
\xynoedgespline@, xycurve.doc:2491
\xynolinecap@, xyline.doc:546
\xynolinejoin@, xyline.doc:547
\xynolinemiter@, xyline.doc:548
\xynolinewidth@, xyline.doc:544
\xynomath@, xy.doc:1111
\xynonagon@@, xypoly.doc:983
\xyNopattern@, xytile.doc:208
\xyNopattern@@, xytile.doc:210
\xynopolystyle@, xyline.doc:492

                                             \xyNoResizing@, xyrotate.doc:123
                                             \xyNoResizing@@, xyrotate.doc:130
                                             \xynumctrlpts@, xycurve.doc:85
                                             \xyoctagon@@, xypoly.doc:949
                                             \xyoldOzTeXheader, xy17oztex.doc:194
                                             \xyoption, xy.doc:6404
                                             \xyoption , 11, 90, 91
                                             \xyoption@@, xy.doc:6402
                                             \xyoption@truncated, xy.doc:6412
                                             \xyOzTeXheader, xyoztex.doc:192
                                             \xypattern@, xytile.doc:212
                                             \xypattern@@, xytile.doc:209
                                             \xypatternmessage@, xytile.doc:106
                                             \xypatternwarning@, xytile.doc:104
                                             \xypatternwarning@@, xytile.doc:100
                                             \xypentagon@@, xypoly.doc:871
                                             xypic.sty, 563
                                             xypic.tex, 563
                                             \xypoly@, xypoly.doc:224
                                             \xypoly@@, xypoly.doc:316
                                             \xypoly@@@, xypoly.doc:751
                                             \xypoly@@@x, xypoly.doc:771
                                             \xypoly@@i, xypoly.doc:305
                                             \xypoly@i, xypoly.doc:262
                                             \xypoly@n, xypoly.doc:252
                                             \xypoly@SIDES@, xypoly.doc:489
                                             \xypoly@SPOKES@, xypoly.doc:477
                                             \xypoly@x, xypoly.doc:246
                                             \xypolybody@, xypoly.doc:1172
                                             \xypolydash@Special, xyline.doc:468
                                             \xypolydashPS@Special, xyps-l.doc:134
                                             \xypolydefaults@, xypoly.doc:320
                                             \xypolydot@Special, xyline.doc:467
                                             \xypolydotPS@Special, xyps-l.doc:133
                                             \xypolyeofill@Special, xyline.doc:466
                                             \xypolyeofillPS@Special, xyps-l.doc:136
                                             \xypolyfill@Special, xyline.doc:465
                                             \xypolyfillPS@Special, xyps-l.doc:135
                                             \xypolygon, xypoly.doc:222
                                             \xypolygon@@, xypoly.doc:1183
                                             \xyPolygon@@@, xypoly.doc:784
                                             \xypolyiterate@, xypoly.doc:1173
                                             \xypolyline, xyline.doc:389
                                             \xypolyline@, xyline.doc:391
                                             \xypolyline@Special, xyline.doc:464
                                             \xypolylinePS@Special, xyps-l.doc:132
                                             \xypolyloop@, xypoly.doc:1174
                                             \xypolyname, xypoly.doc:272
                                             \xypolynode, xypoly.doc:212

\xypolynode@, xypoly.doc:211
\xypolynospec@, xyline.doc:501
\xypolynullvertex@, xypoly.doc:353
\xypolynum, xypoly.doc:215
\xypolyNUMSIDES@, xypoly.doc:214
\xypolyparams@, xypoly.doc:361
\xypolyPREFIX@, xypoly.doc:270
\xypolyPREFIX@@, xypoly.doc:271
\xypolyprefix@@, xypoly.doc:285
\xypolyrepeat@, xypoly.doc:1171
\xypolystraight@, xyline.doc:516
\xypolytoosmall@, xypoly.doc:773
\xypolyvertex@, xypoly.doc:356
\xypolyVERTEXerror@, xypoly.doc:377
\xypolywhich@, xypoly.doc:463
\xypolywidevertex@, xypoly.doc:359
\xyPOS@, xy.doc:1560
\xypost@Style@, xy.doc:3932
\xypostcross@, xyknot.doc:351
\xypostcurve@, xycurve.doc:3248
\xypre@skipStyle@, xy.doc:3936
\xypre@Style@, xy.doc:3923
\xyprecross@, xyknot.doc:346
\xyprecurve@, xycurve.doc:3247
\XYpredict@, xyps-ps.doc:597
\XYpredict@@, xyps-ps.doc:588
\XYpredict@r, xyps-ps.doc:596
\xyprovide, xy.doc:6558
\xyprovide , 91, 92
\xyPS@@, xyps-ps.doc:527
\xyPS@@@, xyps-ps.doc:528
\xyPS@color@@, xyps-c.doc:138
\xyps@options, xyps.doc:307
\xyPS@pattern@@, xyps-t.doc:129
\xyPSabtip@, xyps.doc:847
\xyPSabtip@i, xyps.doc:860
\xyPSahook@, xyps.doc:876
\xyPSalternative@, xyps.doc:695
\xyPSatip@, xyps.doc:843
\xyPSatip@i, xyps.doc:856
\xyPSaturn@, xyps.doc:883
\xyPSbhook@, xyps.doc:877
\xyPSbtip@, xyps.doc:845
\xyPSbtip@i, xyps.doc:858
\xyPSbturn@, xyps.doc:884
\xyPScapSpecial@, xyps-l.doc:99
\xyPSchar@, xyps.doc:772
\xyPScharmessage@, xyps-ps.doc:643
\xyPScharwarning@@, xyps-ps.doc:638

                                             \xyPScirbuild@, xyps.doc:988
                                             \xyPScirc@, xyps.doc:977
                                             \xyPScirc@Special, xyps-f.doc:174
                                             \xyPScirchar@, xyps.doc:937
                                             \xyPScirchar@@, xyps.doc:955
                                             \xyPScirchar@@@, xyps.doc:967
                                             \xypscircle@, xyps-f.doc:162
                                             \xyPScircled@x@, xyps-f.doc:102
                                             \xyPScircled@x@@, xyps-f.doc:109
                                             \xyPSCIRfull@, xyps.doc:985
                                             \xyPScirrest@, xyps.doc:949
                                             \xyPScm@, xyps.doc:820
                                             \xyPScm@@, xyps.doc:821
                                             \xyPScmatip@, xyps.doc:829
                                             \xyPScmbtip@, xyps.doc:830
                                             \xyPScmtip@, xyps.doc:828
                                             \xyPScolor@, xyps-c.doc:126
                                             \xyPScolor@@, xyps-c.doc:128
                                             \xyPScubic@, xyps.doc:1117
                                             \xyPScurrpt@, xyps-ps.doc:325
                                             \xyPScurrpt@@, xyps-ps.doc:336
                                             \xyPScurrpt@@@, xyps-ps.doc:335
                                             \xyPSdash@, xyps.doc:915
                                             \xyPSdashcirc@Special, xyps-f.doc:176
                                             \xyPSdashed@, xyps.doc:1056
                                             \xyPSdashedSpread@, xyps.doc:1057
                                             \xyPSdashhfill@, xyps-f.doc:135
                                             \xyPSdashoval@Special, xyps-f.doc:178
                                             \xyPSdashvfill@, xyps-f.doc:136
                                             \xyPSdefaultdict, xyps-ps.doc:503, xyps.doc:628
                                             \xyPSdefaultdict , 260
                                             \xyPSdictknown@, xyps-ps.doc:475
                                             \xyPSdotcirc@Special, xyps-f.doc:175
                                             \xyPSdotoval@Special, xyps-f.doc:177
                                             \xyPSdottedSpread@, xyps.doc:1054
                                             \xyPSdriver, xyps-ps.doc:197
                                             \xypsellipse@, xyps-f.doc:166
                                             \xyPSellipsed@x@, xyps-f.doc:117
                                             \xyPSellipsed@x@@, xyps-f.doc:125
                                             \xyPSescapestyle@, xyps-s.doc:60
                                             \xyPSfillcirc@Special, xyps-f.doc:225
                                             \xyPSfilledRegion, xyps-f.doc:189
                                             \xyPSfillellipse@Special, xyps-f.doc:228
                                             \xyPSfilloval@Special, xyps-f.doc:222
                                             \xyPSfliptrue@, xyps.doc:913
                                             \xyPSfont@, xyps.doc:784
                                             \xyPSframed@body@, xyps-f.doc:86
                                             \xyPSframed@oval@, xyps-f.doc:98
                                             \xyPShook@, xyps.doc:875

\xyPSjoinSpecial@, xyps-l.doc:100
\xyPSlineSpecial@, xyps-l.doc:98
\xyPSmath@, xyps-c.doc:105
\xyPSmiterSpecial@, xyps-l.doc:101
\xyPSnewcolor@, xyps-c.doc:113
\xyPSnewpattern@, xyps-t.doc:104
\xyPSnomath@, xyps-c.doc:106
\xyPSnotfinished@@, xyps-ps.doc:697
\xyPSnotimplemented@@, xyps-ps.doc:694
\xyPSobeylines@@, xyps-ps.doc:68
\xypsoval@, xyps-f.doc:148
\xyPSoval@Special, xyps-f.doc:173
\xyPSpattern@, xyps-t.doc:117
\xyPSpattern@@, xyps-t.doc:120
\xyPSpoint@, xyps.doc:1083
\xyPSpost@, xyps-ps.doc:438
\xyPSposttransform@, xyps-r.doc:111
\xyPSpre@, xyps-ps.doc:437
\xyPSpretransform@, xyps-r.doc:110
\xyPSpsxy@, xyps-ps.doc:320
\xyPSrawA@, xyps-ps.doc:401
\xyPSrawAA@, xyps-ps.doc:402
\xyPSrawstyleA@, xyps-s.doc:98
\xyPSrawZ@, xyps-ps.doc:404
\xyPSrotate@@, xyps-r.doc:136
\xyPSrotSplit@, xyps-r.doc:116
\xyPSscale@@, xyps-r.doc:126
\xyPSsemichar@, xyps.doc:775
\xyPSsemifont@, xyps.doc:785
\xyPSshapechar@, xyps-ps.doc:391
\xyPSshipout@, xyps-ps.doc:110
\xyPSshipout@i, xyps-ps.doc:112
\xyPSshipout@ii, xyps-ps.doc:113
\xyPSshipout@PSii, xyps-ps.doc:125
\xyPSsolid@, xyps.doc:1051
\xyPSsolidSpread@, xyps.doc:1052
\xyPSspecialRotate@, xyps-r.doc:140
\xyPSsplinedashed@, xyps.doc:1132
\xyPSsplinedotted@, xyps.doc:1135
\xyPSsplinesolid@, xyps.doc:1129
\xyPSsplitescape@, xyps-s.doc:61
\xyPSsplitPS@, xyps-s.doc:67
\xyPSsplitshape@, xyps-ps.doc:392
\xyPSspread@, xyps.doc:1060
\xyPSsquiggle@, xyps.doc:893
\xyPSsquine@, xyps.doc:1122
\xyPSstopper@, xyps.doc:910
\xyPSstraight@, xyps.doc:1014
\xyPSTip@, xyps.doc:802

                                             \xyPStip@, xyps.doc:799
                                             \xyPSTip@eu@, xyps.doc:806
                                             \xyPStips@, xyps.doc:837
                                             \xyPSTtip@, xyps.doc:803
                                             \xyPSTtip@eu@, xyps.doc:807
                                             \xyPSTtips@, xyps.doc:863
                                             \xyPSwarning@, xyps.doc:317
                                             \xyPSwhichabtip@, xyps.doc:854
                                             \xyPSwhichatip@, xyps.doc:850
                                             \xyPSwhichbtip@, xyps.doc:852
                                             \xyPSzerodot@, xyps.doc:1091
                                             \xyq@, xymatrix.doc:675
                                             \xyq@@toksix@, xymatrix.doc:677
                                             \xyq@@toksix@i, xymatrix.doc:680
                                             \xyqall@, xymatrix.doc:670
                                             \xyqs@, xymatrix.doc:684
                                             \xyquadbezier@, xycurve.doc:3488
                                             \xyquadmethods@, xycurve.doc:3495
                                             \xyquiet, xy.doc:4659
                                             \xyquiet , 65, 66
                                             \xyread@, xy.doc:697
                                             \xyreadpatfile@, xytile.doc:294
                                             \xyrealshipout@, xyps-ps.doc:109
                                             \xyrecat, xy.doc:310
                                             xyrecat.tex, 5
                                             \xyrecat@, xy.doc:309
                                             \xyrecompile@, xy.doc:4764
                                             \xyrecompile@@, xy.doc:4744
                                             \xyReloadDrivers, xy.doc:6703
                                             \xyReloadDrivers , 93, 94
                                             \xyReloadDrivers@, xy.doc:6702
                                             \xyrequire, xy.doc:6421
                                             \xyrequire , 90
                                             \xyrescale@, xyrotate.doc:281
                                             \xyresetcatcodes, xy.doc:311
                                             \xyreuncatcodes, xy.doc:47
                                             \xyRotate@, xyrotate.doc:357
                                             \xyrotatechar@, xyrotate.doc:325
                                             \xyrotateSizeMod@, xyrotate.doc:379
                                             \xyRotScale@@, xyps-r.doc:164
                                             \xysave@, xy.doc:4783
                                             \xysave@@toksix@, xy.doc:4786
                                             \xysaveMinMax@, xy2cell.doc:1215
                                             \xysaving@, xy.doc:4778
                                             \xysbendh, xyknot.doc:1686
                                             \xysbendv, xyknot.doc:1685
                                             \xyscale@, xyrotate.doc:360
                                             \xyscalechar@, xyrotate.doc:269
                                             \xyscalechars@, xyrotate.doc:271

\xyselectoptionsupport@, xy.doc:6721
\xysetjoincontrol@, xyknot.doc:1206
\xysetknotPLACE@, xyknot.doc:1172
\xysetknotPLACE@@, xyknot.doc:1176
\xysetlinecap@, xyline.doc:269
\xysetlinecap@@, xyline.doc:294
\xysetlinejoin@, xyline.doc:275
\xysetlinejoin@@, xyline.doc:295
\xysetmiterlimit@, xyline.doc:281
\xysetmiterlimit@@, xyline.doc:296
\xysetpostbreak@, xyknot.doc:1205
\xysetup@@, xyidioms.doc:133
\xysetup@dummy, xyidioms.doc:132
\xyshape@bevel@, xyline.doc:267
\xyshape@butt@, xyline.doc:261
\xyshape@dblsize@, xyrotate.doc:301
\xyshape@flip@, xyrotate.doc:302
\xyshape@halfsize@, xyrotate.doc:300
\xyshape@hflip@, xyrotate.doc:304
\xyshape@left@, xyrotate.doc:408
\xyshape@miter@, xyline.doc:265
\xyshape@projcap@, xyline.doc:263
\xyshape@rdcap@, xyline.doc:262
\xyshape@rdjoin@, xyline.doc:266
\xyshape@right@, xyrotate.doc:409
\xyshape@thicker@, xyline.doc:134
\xyshape@thinner@, xyline.doc:135
\xyshape@vflip@, xyrotate.doc:303
\xyshearchar@, xyrotate.doc:424
\xyShowDrivers, xy.doc:6735
\xyShowDrivers , 94
\xysidesofhull@, xycurve.doc:1624
\xysidesofinterval@, xycurve.doc:1555
\xySpecialRotate@, xyrotate.doc:358
\xySpecialRotate@i, xyrotate.doc:328
\xysplinespecialcases@, xycurve.doc:3270
\xysquare@@, xypoly.doc:853
\xystackcolor@, xycolor.doc:143
\xystackcolor@i, xycolor.doc:147
\xystandardcolors@, xycolor.doc:230
\xystandardpatterns@, xytile.doc:254
\xystatus, xy2cell.doc:1245
\xystatus@, xy.doc:4640
\xystatus@c, xy.doc:4655
\xystatus@cp, xy.doc:4648
\xysupportwarning@, xy.doc:6903
\xysupportwarnings@@, xy.doc:6917
\xytestforsupport@, xy.doc:6855
\xytilde@Warning, xycurve.doc:518

                                             \xytotoks@, xy.doc:2758
                                             \xytotoks@@toksix@, xy.doc:2759
                                             \xytpfloaded, xytp-f.doc:25
                                             \xyTPIC@accumulate, xytpic.doc:399
                                             \xytpic@ar, xytpic.doc:119
                                             \xytpic@bk, xytpic.doc:126
                                             \xytpic@circhar@, xytpic.doc:355
                                             \xytpic@cnt, xytpic.doc:79
                                             \xytpic@da, xytpic.doc:116
                                             \xytpic@dad, xytpic.doc:170
                                             \xytpic@dashed@, xytpic.doc:241
                                             \xytpic@dashed@@, xytpic.doc:168
                                             \xytpic@dot@@, xytpic.doc:157
                                             \xytpic@dotted@@, xytpic.doc:169
                                             \xytpic@dt, xytpic.doc:117
                                             \xytpic@dtd, xytpic.doc:172
                                             \xytpic@fp, xytpic.doc:114
                                             \xytpic@ia, xytpic.doc:120
                                             \xytpic@in, xytpic.doc:149
                                             \xytpic@ip, xytpic.doc:115
                                             \xytpic@line, xytpic.doc:162
                                             \xytpic@max, xytpic.doc:80
                                             \xyTPIC@noisy, xytpic.doc:129
                                             \xytpic@pa, xytpic.doc:109
                                             \xytpic@pn, xytpic.doc:108
                                             \xytpic@point@, xytpic.doc:244
                                             \xytpic@polydashed@, xytpic.doc:176
                                             \xytpic@polydotted@, xytpic.doc:177
                                             \xytpic@polysolid@, xytpic.doc:175
                                             \xytpic@postpoly@, xytpic.doc:178
                                             \xytpic@pt, xytpic.doc:146
                                             \xytpic@reset@, xytpic.doc:100
                                             \xytpic@set@, xytpic.doc:102
                                             \xytpic@sh, xytpic.doc:121
                                             \xytpic@solid@, xytpic.doc:236
                                             \xytpic@solid@@, xytpic.doc:167
                                             \xytpic@sp, xytpic.doc:118
                                             \xyTPIC@special, xytpic.doc:128
                                             \xyTPIC@spline@ii@, xytpic.doc:387
                                             \xytpic@splinedashed@, xytpic.doc:295
                                             \xytpic@splinedotted@, xytpic.doc:297
                                             \xytpic@splinesolid@, xytpic.doc:294
                                             \xytpic@style@@, xytpic.doc:99
                                             \xytpic@wh, xytpic.doc:125
                                             \xytpic@width@, xytpic.doc:158
                                             \xyTPICcirc@Special, xytp-f.doc:222
                                             \xyTPICcirchar@i, xytpic.doc:381
                                             \xyTPICcircle@, xytp-f.doc:200
                                             \xyTPICcircled@x@, xytp-f.doc:92

\xyTPICcircled@xx, xytp-f.doc:97
\xyTPICdashcirc@, xytp-f.doc:102
\xyTPICdashcirc@Special, xytp-f.doc:224
\xyTPICdashellip@, xytp-f.doc:105
\xyTPICdashrect@Special, xytp-f.doc:221
\xyTPICdotcirc@, xytp-f.doc:100
\xyTPICdotcirc@Special, xytp-f.doc:223
\xyTPICdotellip@, xytp-f.doc:104
\xyTPICdotrect@Special, xytp-f.doc:220
\xyTPICellipse@, xytp-f.doc:214
\xyTPICellipsed@x@, xytp-f.doc:111
\xyTPICellipsed@xx, xytp-f.doc:116
\xyTPICfillcirc@Special, xytp-f.doc:267
\xyTPICfilledoval@, xytp-f.doc:163
\xyTPICfilledRegion, xytp-f.doc:235
\xyTPICfillellipse@Special, xytp-f.doc:270
\xyTPICfilloval@Special, xytp-f.doc:264
\xyTPICfillrect@Special, xytp-f.doc:261
\xyTPICframed@body@, xytp-f.doc:71
\xyTPICframed@rect@i, xytp-f.doc:81
\xyTPICfullcircle@, xytpic.doc:341
\xyTPIClinewidth@, xytpic.doc:316
\xyTPICmaxwarning@, xytpic.doc:84
\xyTPICoval@, xytp-f.doc:150
\xyTPICoval@i, xytp-f.doc:161
\xyTPICpartcircle@, xytpic.doc:343
\xyTPICqspline@, xytpic.doc:403
\xyTPICrect@, xytp-f.doc:126
\xyTPICrect@Special, xytp-f.doc:219
\xyTPICrect@x, xytp-f.doc:145
\xyTPICspline@, xytpic.doc:300
\xyTPICspline@dot, xytpic.doc:306
\xyTPICsplit@, xytpic.doc:137
\xyTPICstraight@, xytpic.doc:249
\xytracelineno@, xy.doc:474
\xytracing, xy.doc:4633
\xytracing , 65, 66
\xytracing@, xy.doc:4637
\xytriangle@@, xypoly.doc:839
\xytrigerror@, xypoly.doc:661
\xyuncatcodes, xy.doc:46
\xyuncatcodes , 4
\xyundecagon@@, xypoly.doc:1063
\xyundefinedEffect@, xyps-ps.doc:671
\xyundefinedLine@, xyline.doc:541
\xyundefinedRotate@, xyrotate.doc:53
\xyundefinedStyle@, xy.doc:4098
\xyunload@, xy.doc:6937
\xyunloadEM@, xyemtex.doc:125

                                             \xyunloadTPIC@, xytpic.doc:215
                                             \xyunsupportwarning@, xy.doc:6884
                                             \xyunsupportwarnings@@, xy.doc:6898
                                             \xyUseResizing@, xyrotate.doc:135
                                             \xyUseResizing@@, xyrotate.doc:136
                                             \xyvcap, xyknot.doc:1566
                                             \xyvcross, xyknot.doc:410
                                             \xyvcrossneg, xyknot.doc:416
                                             \xyVECTOR@, xy.doc:1415
                                             \xyverbose, xy.doc:4625
                                             \xyverbose , 65, 66
                                             \xyverbose@, xy.doc:4629
                                             \xyversion, xy.doc:418
                                             \xyversion , 13
                                             \xyviitoi, xyv2.doc:670
                                             \xyviitoii, xyv2.doc:671
                                             \xyvloop, xyknot.doc:1617
                                             \xyvover, xyknot.doc:544
                                             \xyvtwist, xyknot.doc:683
                                             \xyvtwistneg, xyknot.doc:686
                                             \xyvuncross, xyknot.doc:422
                                             \xyvunder, xyknot.doc:550
                                             \xyvunover, xyknot.doc:556
                                             \xyvuntwist, xyknot.doc:689
                                             \xywarnifdefined, xy.doc:36
                                             \xywarnifdefined , 3
                                             \xywarning@, xy.doc:476
                                             \xywidthchar@, xyline.doc:144
                                             \xywith@@, xy.doc:6443
                                             \xywithoption, xy.doc:6447
                                             \xywithoption , 8, 90, 91
                                             \xywithrun@, xy.doc:6457
                                             \xywithtest@, xy.doc:6454
                                             \xywrite@, xy.doc:698
                                             \xyxbendd, xyknot.doc:1692
                                             \xyxbendl, xyknot.doc:1690
                                             \xyxbendr, xyknot.doc:1689
                                             \xyxbendu, xyknot.doc:1691
                                             \xyxcaph, xyknot.doc:1569
                                             \xyxcapv, xyknot.doc:1568
                                             \xyxoverh, xyknot.doc:569
                                             \xyxoverv, xyknot.doc:563
                                             \xyxunderh, xyknot.doc:572
                                             \xyxunderv, xyknot.doc:566
                                             \xyxunover, xyknot.doc:575
                                             \xyxunoverh, xyknot.doc:581
                                             \xyxunoverv, xyknot.doc:578
                                             \xyxy@, xy.doc:1125
                                             \xyxy@@ix@, xy.doc:879

\xyzbendh, xyknot.doc:1684
\xyzbendv, xyknot.doc:1687

Y, 20 y, 23, 38

\Y@c, xy.doc:612
\Y@max, xy.doc:637
\Y@min, xy.doc:635
\Y@origin, xy.doc:628
\Y@p, xy.doc:620
\Y@xbase, xy.doc:630
\Y@ybase, xy.doc:632

Y_{origin}, 21 Y_{xbase}, 21 Y_{ybase}, 21 Y_{c}, 21 Y_{p}, 21 Y_{max}, 20 Y_{min}, 20

\Yc, xyv2.doc:213

\Yc , 556

\Ymax, xyv2.doc:239
\Ymax , 556
\Ymin, xyv2.doc:237
\Ymin , 556
\Yorigin, xyv2.doc:230
\Yorigin , 556
\Yp, xyv2.doc:220

\Yp , 556

\Yxbase, xyv2.doc:232
\Yxbase , 556
\Yybase, xyv2.doc:234
\Yybase , 556
\zbendh, xyknot.doc:1644
\zbendv, xyknot.doc:1656

zero position, 20

\zerocorner, xyframe.doc:360
\zerodash@i, xycurve.doc:4683
\zeroDivide@, xy.doc:2470
\zeroDivide@@, xy.doc:2468
\zeroDivide@message, xy.doc:2469
\zeroDivideLimit, xy.doc:2478
\zeroDivideLimit@, xy.doc:2476
\zeroDivideLimit@@, xy.doc:2472
\zerodot, xy.doc:5321
\zerodot , 16, 76
\zerodot@i, xycurve.doc:4678
\zerodotbox@, xy.doc:654
\zeroEdge, xy.doc:7406
\zeroEdge , 48

                                             \zeroit@, xy.doc:1448
                                             \Zoom@, movie.cls:252
                                             \zz@, xy.doc:660, 16