nodes.tex /size: 64 Kb    last modification: 2021-10-28 13:50
1% language=us runpath=texruns:manuals/nodes
2
3% author    : Alan Braslau
4% copyright : ConTeXt Development Team
5% license   : Creative Commons Attribution ShareAlike 4.0 International
6% reference : pragma-ade.nl | contextgarden.net | texlive (related) distributions
7% origin    : the ConTeXt distribution
8%
9% comment   : Because this manual is distributed with TeX distributions it comes with a rather
10%             liberal license. We try to adapt these documents to upgrades in the (sub)systems
11%             that they describe. Using parts of the content otherwise can therefore conflict
12%             with existing functionality and we cannot be held responsible for that. Many of
13%             the manuals contain characteristic graphics and personal notes or examples that
14%             make no sense when used out-of-context.
15%
16% comment   : A prototype of the nodes module was presented at the ConTeXt 2016 user meeting
17%             and the first release was presented at the 2017 meeting. The module is part of
18%             the MetaFun code modules.
19%
20% comment   : This manual orginates in an article by Alan so anything wrong in here is Hans
21%             fault as he converted it.
22%
23% comment   : It is also being published as an article in TugBoat.
24%
25% comment   : The cover images are from the NASA website.
26
27%\enabletrackers[metapost.showlog]
28
29\definemeasure [layout:margin] [\paperheight/20]
30
31\setuplayout
32  [topspace=\measure{layout:margin},
33   bottomspace=\measure{layout:margin},
34   backspace=\measure{layout:margin},
35   header=0pt,
36   footer=\measure{layout:margin},
37   width=middle,
38   height=middle]
39
40\setupbodyfont
41  [dejavu,11pt]
42
43\setupwhitespace
44  [big]
45
46\setuphead
47  [chapter]
48  [style=\bfc,
49   interaction=all]
50
51\setuppagenumbering
52  [alternative=doublesided,
53   location=]
54
55\setupfootertexts
56  [\documentvariable{title}][\pagenumber]
57  [\pagenumber][\documentvariable{title}]
58
59\setuphead
60  [section]
61  [style=\bfb]
62
63\setuphead
64  [subsection]
65  [style=\bfa]
66
67\setuphead
68  [subsubsection]
69  [style=\bf,
70   after=]
71
72\setuplist
73  [interaction=all]
74
75\setupalign
76  [verytolerant,stretch]
77
78% \definesymbol [1] [$\cdot$]
79
80% Dot rather than bullet ... Alan hates bullets! Hans hates too small dots.
81% So, a dash is OK? ;-)
82
83\setupitemize
84  [symbol=2] % dash rather than bullet, I hate bullets!
85
86\setupnote
87  [footnote]
88  [next={ },
89   split=verystrict,
90   scope=page]
91
92\setupinteraction
93  [state=start,
94   option=bookmark,
95   color=darkmagenta,
96   contrastcolor=darkmagenta]
97
98\setupinteractionscreen
99  [option=bookmark]
100
101\placebookmarks
102  [title,subject]
103  [title,subject]
104
105\enabledirectives
106  [references.bookmarks.preroll]
107
108\kindofpagetextareas\plusone % partial page. HH: low level, no high level switch (yet)
109
110\definetextbackground
111  [aside]
112  [location=paragraph,
113   frame=off,
114   leftoffset=1ex,
115   rightoffset=1ex,
116   topoffset=1ex,
117   bottomoffset=1ex,
118   background=color,
119   backgroundcolor=lightgray]
120
121\definedescription
122  [description]
123  [location=hanging,
124   width=broad,
125   before={\blank},
126   after={\blank}]
127
128\defineparagraphs
129  [two]
130  [n=2,
131   offset=1ex,
132   background=color,
133   backgroundcolor=gray]
134
135\defineframed
136  [node]
137  [offset=1pt,
138   foregroundstyle=\tfa]
139
140\defineframed
141  [nodeGreen]
142  [node]
143  [foregroundcolor=darkgreen,
144   foregroundstyle=italic]
145
146\defineframed
147  [nodeSmall]
148  [node]
149  [foregroundstyle=\tfx]
150
151\startbuffer [bib]
152    @ARTICLE{Krebs1946,
153        author   = {Krebs, H. A.},
154        title    = {Cyclic processes in living matter},
155        journal  = {Enzymologia},
156        year     = {1946},
157        volume   = {12},
158        pages    = {88--100}
159        language = {english},
160    }
161
162    @ARTICLE{Bethe1939a,
163        author    = {Bethe, H. A.},
164        title     = {Energy Production in Stars},
165        journal   = {Phys. Rev.},
166        year      = {1939},
167        volume    = {55},
168        pages     = {103103},
169        month     = {Jan},
170        doi       = {10.1103/PhysRev.55.103},
171        issue     = {1},
172        publisher = {American Physical Society},
173        XXurl     = {http://link.aps.org/doi/10.1103/PhysRev.55.103}
174        language  = {english},
175    }
176
177    @ARTICLE{Bethe1939b,
178        author    = {Bethe, H. A.},
179        title     = {Energy Production in Stars},
180        journal   = {Phys. Rev.},
181        year      = {1939},
182        volume    = {55},
183        pages     = {434456},
184        month     = {Mar},
185        doi       = {10.1103/PhysRev.55.434},
186        issue     = {5},
187        publisher = {American Physical Society},
188        XXurl     = {http://link.aps.org/doi/10.1103/PhysRev.55.434}
189        language  = {english},
190    }
191
192    @BOOK{Lawvere2009,
193        author    = {Lawvere, F. William and Schanuel, Stephen H.},
194        title     = {Conceptual Mathematics}
195        subtitle  = {A first introduction to categories},
196        edition   = {2\high{nd}},
197        publisher = {Cambridge University Press},
198        address   = {Cambridge, UK},
199        year      = {2009}
200        language  = {english},
201    }
202
203    @ARTICLE{Braslau2018,
204        title     = {ConTeXt nodes},
205        subtitle  = {commutative diagrams and related graphics},
206        author    = {Braslau, Alan and Hamid, Idris Samawi and Hagen, Hans},
207        year      = {2018},
208        journal   = {TUGboat},
209        volume    = {39},
210        number    = {1},
211        ISSN      = {0896-3207},
212        url       = {https://www.tug.org/TUGboat/Contents/contents39-1.html},
213        language  = {english},
214    }
215\stopbuffer
216
217\usebtxdefinitions [apa]
218\setupbtxrendering [apa] [pagestate=start] % index cite pages in bibliography
219
220\usebtxdataset  [bib.buffer]
221
222% Say, MP math arrows rather than font arrows:
223
224\useMPlibrary[mat]
225
226\definemathstackers
227   [mp]
228   [alternative=mp]
229
230\definemathextensible [mp] [leftarrow]          ["2190]
231\definemathextensible [mp] [rightarrow]         ["2192]
232\definemathextensible [mp] [leftrightarrow]     ["2194]
233\definemathextensible [mp] [longleftrightarrow] ["27F7]
234\definemathextensible [mp] [rightoverleftarrow] ["21C4]
235
236\startMPinitializations
237  ahlength  := EmWidth ;
238  ahangle   := 30 ;
239  ahvariant := 1 ; % dimpled curved
240  ahdimple  := 4/5 ;
241
242  node_loopback_yscale := .7 ;
243\stopMPinitializations
244
245% Only here do we use the special nodes:: instance
246
247\defineframed
248  [mynode]
249  [node]
250  [offset=1pt,
251   foregroundcolor=white]
252
253\startreusableMPgraphic{nodes::krebs}
254
255   % The Bethe cycle for energy production in stars (1939), following
256   % Krebs (1946)
257
258   save p ; path p[] ;
259   p1 := (for i=0 step 60 until 300: dir(90-i).. endfor cycle) scaled 2.75cm ;
260   p0 := p1 scaled  .5 ;
261   p2 := p1 scaled 1.5 ;
262
263   draw node(p1,0,"\mynode{\chemical{^{12}C}}") ;
264   draw node(p1,1,"\mynode{\chemical{^{13}N}}") ;
265   draw node(p1,2,"\mynode{\chemical{^{13}C}}") ;
266   draw node(p1,3,"\mynode{\chemical{^{14}N}}") ;
267   draw node(p1,4,"\mynode{\chemical{^{15}O}}") ;
268   draw node(p1,5,"\mynode{\chemical{^{15}N}}") ;
269
270   drawarrow fromtopaths.urt (true,p1,0,p1,1,"\mynode{a}") withcolor white ;
271   drawarrow fromtopaths.rt  (true,p1,1,p1,2,"\mynode{b}") withcolor white ;
272   drawarrow fromtopaths.lrt (true,p1,2,p1,3,"\mynode{c}") withcolor white ;
273   drawarrow fromtopaths.llft(true,p1,3,p1,4,"\mynode{d}") withcolor white ;
274   drawarrow fromtopaths.lft (true,p1,4,p1,5,"\mynode{e}") withcolor white ;
275   drawarrow fromtopaths.ulft(true,p1,5,p1,6,"\mynode{f}") withcolor white ;
276
277   draw node(p0,0,"\mynode{\chemical{^1H}}") ;
278   draw node(p0,2,"\mynode{\chemical{^1H}}") ;
279   draw node(p0,3,"\mynode{\chemical{^1H}}") ;
280   draw node(p0,5,"\mynode{\chemical{^1H}}") ;
281
282   drawarrow fromtopaths(3/10,p0,0,p1,0.5) withcolor white ;
283   drawarrow fromtopaths(3/10,p0,2,p1,2.5) withcolor white ;
284   drawarrow fromtopaths(3/10,p0,3,p1,3.5) withcolor white ;
285   drawarrow fromtopaths(3/10,p0,5,p1,5.5) withcolor white ;
286
287   draw node     (p2,0,"\mynode{\chemical{^4He}}")                ;
288   draw node     (p2,1,"\mynode{$γ$}")                            ;
289   draw node.lrt (p2,2,"\mynode{$\mathrm{e}^+ + ν_\mathrm{e}$}")  ;
290   draw node     (p2,3,"\mynode{$γ$}")                            ;
291   draw node     (p2,4,"\mynode{$γ$}")                            ;
292   draw node.ulft(p2,5,"\mynode{$\mathrm{e}^+ + ν_\mathrm{e}$}")  ;
293
294   drawarrow fromtopaths(-1/10,p1,0.5,p2,1) withcolor white ;
295   drawarrow fromtopaths(-1/10,p1,1.5,p2,2) withcolor white ;
296   drawarrow fromtopaths(-1/10,p1,2.5,p2,3) withcolor white ;
297   drawarrow fromtopaths(-1/10,p1,3.5,p2,4) withcolor white ;
298   drawarrow fromtopaths(-1/10,p1,4.5,p2,5) withcolor white ;
299   drawarrow fromtopaths(-1/10,p1,5.5,p2,0) withcolor white ;
300
301\stopreusableMPgraphic
302
303\startuseMPgraphic{CoverPage}
304
305    StartPage ;
306
307        % Alan wanted a sun in the background combined somehow with the energy
308        % harvesting molecule so here we go. The images that are used come from
309        % the NASA website and I used them as screen saver for a while. The
310        % version that I generate uses a variant from the one on the user's
311        % machine.
312
313        draw textext("\externalfigure[\framedparameter{imagename}]")
314            xsized PaperWidth ysized (PaperHeight+4cm)
315            shifted center Page shifted (0,2cm);
316
317        for i=1 upto 512 :
318            draw (textext("\reuseMPgraphic{nodes::krebs}") scaled (1/5 randomized 1/5))
319            shifted (center Page randomized (PaperWidth,PaperHeight)) ;
320        endfor ;
321
322        draw (textext.ulft("\word{\documentvariable{title}}") xsized (PaperWidth/2))
323            shifted (lrcorner Page)
324            shifted (-PaperWidth/10,2PaperWidth/10)
325            withcolor white;
326
327        draw (textext.ulft("\word{\documentvariable{author}}") xsized (PaperWidth/2))
328            shifted (lrcorner Page)
329            shifted (-PaperWidth/10,PaperWidth/10)
330            withcolor white;
331
332    StopPage ;
333
334\stopuseMPgraphic
335
336\startsetups document:start
337
338    % We each have our preferred cover... ;-)
339
340    \doifmodeelse {atpragma} {
341        \startMPpage[imagename=nodes-sun-pia-03150]
342            \includeMPgraphic{CoverPage}
343        \stopMPpage
344    } {
345        \startMPpage[imagename=nodes-sun-pia-03149]
346            \includeMPgraphic{CoverPage}
347        \stopMPpage
348    }
349
350\stopsetups
351
352\startsetups document:stop
353
354\stopsetups
355
356% And now, the document!
357
358\startdocument
359  [title=Nodes,
360   author=Alan Braslau,
361   copyright=\ConTeXt\ development team,
362   version=1.0]
363
364\startsubject [title=Introduction]
365
366A draft version of this manual was published in \cite[journal] [Braslau2018].
367\cite [Braslau2018]
368
369\blank
370
371The graphical representation of textual diagrams is a very useful tool in the
372communication of ideas. In category and topos theory, for example, many key
373concepts, formulas, and theorems are expressed by means of \emph {commutative
374diagrams}; these involve objects and arrows between them. Certain concepts
375discovered by category theory, such as \emph {natural transformations}, are
376becoming useful in areas outside of mathematics and natural science, e.g., in
377philosophy. To make category and topos methods usable by both specialists and
378non|-|specialists, commutative diagrams are an indispensable tool.
379\startfootnote
380    For many examples of formal and informal commutative diagrams, see \cite
381    [authoryears] [Lawvere2009].
382\stopfootnote
383The use of nodal diagrams is not limited to category theory, for they may
384represent a flow diagram (of a process, for example), a chemical reaction
385sequence or pathways, or that of phases and phase transitions, a hierarchical
386structure (of anything), a timeline or sequence of events or dependencies, a tree
387of descendance or ascendance, etc.
388
389The basic units of a node|-|based diagram include \emph {node objects}, each
390attached to some point (= the \emph {node}) in some spatial relationship. Note
391that to a single node might be associated a set of objects. Given a node, it also
392stands in a spatial relation to some other node. The spatial relationship between
393the set of nodes of a diagram need not be in a regular network, although they
394quite often are. Note that the spatial relationship between nodes is graphical
395and may represent, e.g., a temporal or logical relationship, or a transformation
396of one object into another or into others (one interesting example might be that
397representing cell division or, mitosis).
398
399Given a spatial relation between any two nodes, a node|-|based diagram often
400includes some \emph {path segment} or segments (such as arrows or other curves)
401between two given nodes that \emph {relates} them. Each path segment may be
402augmented by some textual or graphical label.
403
404A very simple example of a node diagram is shown in \in{Figure} [fig:AB].
405
406\startbuffer
407\startMPcode
408  clearnodepath ;
409  nodepath = (left -- right) scaled .75cm ;
410  draw node(0,"A") ;
411  draw node(1,"B") ;
412  drawarrow fromto(0,0,1) ;
413\stopMPcode
414\stopbuffer
415
416\startplacefigure [reference=fig:AB]
417    \getbuffer
418\stopplacefigure
419
420\startplacefigure [reference=fig:ID,
421                   location={right,+2*hang}]
422\startMPcode
423  clearnodepath ; nodepath = origin ;
424  draw node(0,"$O$") ;
425  drawarrow fromto.urt  (.75cm,0,0) ;
426  setbounds currentpicture to boundingbox currentpicture
427      enlarged (1.2cm,0) ;
428\stopMPcode
429\stopplacefigure
430
431More precisely, a \emph {node} is a point of intersection or branching of paths,
432often a point on a regular lattice. (The nodes of the above diagram are the two
433endpoints of a straight line segment.) Sometimes, however, a node might be a
434single point as in an \emph {identity map} of category theory, referring to
435itself:
436\startfootnote
437    The standard arrowhead in \METAPOST\ is a simple triangle, whose length and
438    angle can be adjusted. \METAFUN\ provides further options, allowing this
439    arrowhead to be barbed or dimpled. In the present article, we use the
440    settings: \type {ahlength := EmWidth ; ahangle := 30 ; ahvariant := 1 ;
441    ahdimple := 4/5 ;} The loop|-|back arrow paths used here deviate from a
442    circular segment, becoming ellipsoidal, through the value \type
443    {node_loopback_yscale := .7 ;} These are all set, of course, between a \type
444    {\startMPinitializations}  \type {\stopMPinitializations} pair.
445\stopfootnote
446
447In this article we discuss a new \METAPOST\ module designed for handling
448node|-|based graphics as well as a derivative simple \CONTEXT\ interface. To
449illustrate, the code producing \inlinebuffer\ {could} be, in \METAPOST\ and the
450\CONTEXT\ interface respectively:
451
452\starttwo
453    \METAPOST
454    \startTEX
455        \startMPcode
456          draw node(0,"A") ;
457          draw node(1,"B") ;
458          drawarrow fromto(0,1) ;
459        \stopMPcode
460    \stopTEX
461\two
462    \CONTEXT
463    \startbuffer
464      \startnodes [dx=1.5cm]
465        \placenode [0,0] {A}
466        \placenode [1,0] {B}
467        \connectnodes [0,1]
468                      [alternative=arrow]
469      \stopnodes
470    \stopbuffer
471    \typebuffer [option=TEX]
472\stoptwo
473
474drawing an arrow from A to B (or from node 0 to node 1): \getbuffer
475
476\startitemize[packed]
477    \startitem
478        The \METAPOST\ code shown above has been slightly simplified, as will be
479        seen later.
480    \stopitem
481    \startitem
482        The \CONTEXT\ interface as used here is limited and will be explained a
483        little later.
484    \stopitem
485\stopitemize
486
487For beginners or casual users of \CONTEXT\ |<|including those who might be
488intimidated by \METAPOST\ syntax|>| the ability to construct simple diagrams by
489means of standard \CONTEXT\ syntax is very helpful. For those who have tried the
490\CONTEXT\ interface and/or want to draw more advanced diagrams, the \METAPOST\
491module is much more powerful and flexible.
492
493\stopsubject
494
495\startsubject [title=\METAPOST]
496
497\METAPOST\ is a vector|-|graphics language which calls upon \TeX\ to typeset text
498(such as labels); in \CONTEXT, furthermore, \METAPOST\ is integrated natively
499through the library MPlib as well as the macro package \METAFUN. The tight
500integration of \CONTEXT\ and \METAPOST\ provides advantages over the use of
501other, external graphics engines. These advantages include ease of maintaining
502coherence of style, as well as extensive flexibility without bloat. \METAPOST\
503has further advantages over most other graphics engines, including a very high
504degree of precision as well as the possibility to solve certain types of
505algebraic equations. This last feature is rarely used but should not be
506overlooked.
507
508It is quite natural in \METAPOST\ to locate our node objects along a path or on
509differing paths. This is a much more powerful concept than merely locating a node
510at some pair of coordinates, e.g., on a square or a rectangular lattice, for
511example (as in a table). Furthermore, these paths may be in three dimensions (or
512more); of course the printed page will only involve some projection onto two
513dimensions. Nor are the nodes restricted to location on the points defining a
514path: they may have, as index, any \emph {time} along a given path \type {p}
515ranging from the first defining point ($t = 0$) up to the last point of that path
516($t  \mathtt {length(p)}$), the number of defining points of a path.
517\startfootnote
518    Note that the time of a cyclic path is taken modulo the length of the path,
519    that is $t$ outside of the range $[\mathtt0,\mathtt{length(p)}]$ will return
520    the first or the last point of an open path, but will \quotation {wrap} for a
521    closed path.
522\stopfootnote
523
524Given a path \type {p}, nodes are defined (implicitly) as \type {picture}
525elements: \type {picture p.pic[] ;} This is a pseudo|-|array where the square
526brackets indicates a set of numerical tokens, as in \type {p.pic[0]} or \type
527{p.pic[i]} (for \type {i=0}), but also \type {p.pic0}. This number need not be an
528integer, and \type {p.pic[.5]} or \type {p.pic.5} (not to be confused with \type
529{p.pic5}) are also valid. These picture elements are taken to be located relative
530to the path \type {p}, with the index \type {t} corresponding to a time along the
531path, as in \type {draw p.pic[t] shifted point t of p;} (although it is not
532necessary to draw them in this way). This convention allows the nodes to be
533oriented and offset with respect to the path in an arbitrary manner.
534
535Note that a path can be defined, then nodes placed relative to this path. Or the
536path may be declared but remain undefined, to be determined only after the nodes
537are declared. In yet another possibility, the path may be adjusted as needed, as
538a function of whatever nodes are to be occupied. This will be illustrated through
539examples further down.
540
541\stopsubject
542
543\startsubject [title=A few simple examples]
544
545\startplacefigure [location=right,reference=fig:square]
546    \startMPcode
547        path p ; p := fullsquare scaled 3cm ;
548        draw p ;
549        for i=0 upto length p:
550            draw point i of p
551            withcolor red
552            withpen pencircle scaled 5pt ;
553        endfor ;
554        % this looks better in the figure placement:
555        setbounds currentpicture to boundingbox currentpicture
556            enlarged (.5cm,0) ;
557    \stopMPcode
558\stopplacefigure
559
560Let's begin with illustration of a typical commutative diagram from category
561theory. Although it may appear trivial, this example helps to introduce
562\METAPOST\ syntax. At the same time, a large part of the idea behind this module
563is to facilitate use of this system without having to learn much \METAPOST.
564
565A path is drawn as well as the points defining the path.
566
567%\flushsidefloats
568
569\startTEX
570\startMPcode
571  path p ; p := fullsquare scaled 3cm ; draw p ;
572  for i=0 upto length p:
573    draw point i of p
574    withcolor red
575    withpen pencircle scaled 5pt ;
576  endfor ;
577\stopMPcode
578\stopTEX
579
580\startbuffer
581\startMPcode
582  clearnodepath ;
583  nodepath = p ;
584  draw node(0,"\node{$G(X)$}") ;
585  draw node(1,"\node{$G(Y)$}") ;
586  draw node(2,"\node{$F(Y)$}") ;
587  draw node(3,"\node{$F(X)$}") ;
588  drawarrow fromto.bot(0,0,1, "\nodeSmall{$G(f)$}") ;
589  drawarrow fromto.top(0,3,2, "\nodeSmall{$F(f)$}") ;
590  drawarrow fromto.rt (0,2,1, "\nodeSmall{$η_Y$}") ;
591  drawarrow fromto.lft(0,3,0, "\nodeSmall{$η_X$}") ;
592\stopMPcode
593\stopbuffer
594
595\startplacefigure [location={right,+1*hang},reference=fig:natural,
596    title={Drawn using \METAPOST\ interface}]
597    \getbuffer
598\stopplacefigure
599
600Given the named path \type {nodepath}, we can now define and draw nodes as well
601as connections between them (see \in{Figure} [fig:natural]):
602
603%\flushsidefloats
604
605\typebuffer [option=TEX]
606
607\startaside
608In working with \METAPOST, it is good practice to reset or clear a variable using
609the directive \type {save} for the \emph {suffix} (or variable name) \type
610{nodepath} contained in the directive \type {clearnodepath} (defined as
611\quotation {\type {save nodepath ; path nodepath}}). The macros used here rely on
612the creation of certain internal variables and may not function correctly if the
613variable structure is not cleared. Indeed, any node may contain a combination of
614picture elements, added successively, so it is very important to \type {save} the
615variable, making its use local, rather than global. This point is particularly
616true with \CONTEXT, where a single MPlib instance is used and maintained over
617multiple runs.
618
619The \CONTEXT\ directives \type {\startMPcode}  \type {\stopMPcode} include
620grouping (\METAPOST\ \type {begingroup ;} \type {endgroup ;}) and the use of
621\type {save} (in \type {clearnodepath}) will make the suffix \type {nodepath}
622local to this code block. In the code for \in{Figures} [fig:square] and \in
623[fig:natural], the path \type {p} itself is not declared local (through the use
624of a \type {save}); it therefore remains available for other \METAPOST\ code
625blocks. We cannot do this with the default suffix name \type {nodepath} without
626undesired consequences.
627
628The directive \type {clearnodepath} used in the example above, much like the
629\METAPOST\ command \type {clearxy} clearing the \type {(x,y)} pair also known as
630\type {z}, uses \type {save} to clear the default suffix \type {nodepath}.
631\stopaside
632
633Note that one should not confuse the \METAPOST\ function \type {node()} with the
634\CONTEXT\ command \type {\node{}}, defined as follows:
635
636\starttwo
637  \startTEX
638  \defineframed
639    [node]
640    [frame=off,
641     offset=1pt]
642  \stopTEX
643\two
644  \startTEX
645  \defineframed
646    [nodeSmall]
647    [node]
648    [foregroundstyle=small]
649  \stopTEX
650\stoptwo
651
652\type {\node{}} places the text within a \CONTEXT\ frame (with the frame border
653turned|-|off), whereas the \METAPOST\ function \type {node(i,"")} sets and
654returns a picture element associated with a point on path \type {nodepath}
655indexed by its first argument. The second argument here is a string that gets
656typeset by \TEX. (The use of \type {\node{}} adds an \type {offset}).
657
658By default, the \METAPOST\ function \type {fromto()} returns a path segment going
659between two points of the path \type {nodepath}. The first argument (\type {0} in
660the example above) can be used as a displacement to skew the path away from a
661straight line (by an amount in units of the straight path length). The last
662argument is a string to be typeset and placed midpoint of the segment. The
663{suffix} appended to the function name gives an offset around this halfway point.
664This follows standard \METAPOST\ conventions.
665
666It is important to draw or declare the nodes \emph {before} drawing the
667connections, using \type {fromto()}, in order to be able to avoid overlapping
668symbols, as one notices that the arrows drawn in the example above begin and end
669on the border of the frame (or bounding box) surrounding the node text. This
670would of course not be possible if the arrow were to be drawn before this text
671was known.
672
673As will be seen further on, one can actually specify the use of any defined path,
674without restriction to the built|-|in name \type {nodepath} that is used by
675default. Furthermore, a function \type {fromtopaths()} can be used to draw
676segments connecting any two paths which may be distinct. This too will be
677illustrated further on.
678
679The \CONTEXT\ syntax for the current example looks like this:
680
681\startbuffer
682  \startnodes [dx=3cm,dy=3cm]
683    \placenode [0,0] {\node{$G(X)$}}
684    \placenode [1,0] {\node{$G(Y)$}}
685    \placenode [1,1] {\node{$F(Y)$}}
686    \placenode [0,1] {\node{$F(X)$}}
687    \connectnodes [0,1] [alternative=arrow,
688      label={\nodeSmall{$G(f)$}},position=bottom]
689    \connectnodes [3,2] [alternative=arrow,
690      label={\nodeSmall{$F(f)$}},position=top]
691    \connectnodes [2,1] [alternative=arrow,
692      label={\nodeSmall{$η_Y$}}, position=right]
693    \connectnodes [3,0] [alternative=arrow,
694      label={\nodeSmall{$η_X$}}, position=left]
695  \stopnodes
696\stopbuffer
697
698\startplacefigure [location=right,reference=fig:ConTeXt,
699    title={Drawn using \CONTEXT\ interface}]
700  \getbuffer
701\stopplacefigure
702
703\typebuffer [option=TEX]
704
705\startplacefigure [reference=fig:indices,
706  location=right,
707  title={Coordinates and indices.\footnote {For variety, a rectangular oblique
708         lattice is drawn in \in{Figure} [fig:indices].}}
709  ]
710  \startframed [frame=off,width=.33\textwidth,align=flushright]
711  \startnodes [dx=3cm,dy=2cm,rotation=60]
712    \placenode [0,0] {\node{(0,0)}}
713    \placenode [1,0] {\node{(1,0)}}
714    \placenode [1,1] {\node{(1,1)}}
715    \placenode [0,1] {\node{(0,1)}}
716    \connectnodes [0,1] [alternative=arrow,
717      label={\nodeSmall{$0\rightarrow1$}},position=bottom]
718    \connectnodes [3,2] [alternative=arrow,
719      label={\nodeSmall{$3\rightarrow2$}},position=top]
720    \connectnodes [2,1] [alternative=arrow,
721      label={\nodeSmall{$~2\rightarrow1$}}, position=right]
722    \connectnodes [3,0] [alternative=arrow,
723      label={\nodeSmall{$3\rightarrow0$}}, position=upperleft]
724  \stopnodes
725  \stopframed
726\stopplacefigure
727
728This follows the more classic (and limited) approach of placing nodes on the
729coordinates of a regular lattice, here defined as a 3~cm square network.
730\startfootnote
731    The lattice can be square (\type {dx} $=$ \type {dy}), rectangular
732    (\type {dx}  \type {dy}), or oblique (through \type {rotation}  90).
733\stopfootnote
734The arguments are then $(x,y)$ coordinates of this lattice and the nodes are indexed
7350, 1, 2,  in the order that they are drawn. These are used as reference indices
736in the commands \type {\connectnodes} (rather than requiring two \emph {pairs} of
737coordinates); see \in {Figure} [fig:indices]. This might seem a bit confusing at
738first view, but it simplifies things in the end, really!
739
740To avoid such confusion, in particular when drawing complicated diagrams
741containing many nodes, the \CONTEXT\ interface allows the use of a \type
742{reference} or tag, assigning a symbolic name to a numbered node. The example of
743\in{Figure} [fig:ConTeXt] can be redrawn a little more verbosely as:
744
745\startbuffer
746  \startnodes [dx=3cm,dy=3cm]
747    \placenode [0,0] [reference=GX] {\node{$G(X)$}}
748    \placenode [1,0] [reference=GY] {\node{$G(Y)$}}
749    \placenode [1,1] [reference=FY] {\node{$F(Y)$}}
750    \placenode [0,1] [reference=FX] {\node{$F(X)$}}
751    \connectnodes [GX,GY] [alternative=arrow,
752      label={\nodeSmall{$G(f)$}},position=bottom]
753    \connectnodes [FX,FY] [alternative=arrow,
754      label={\nodeSmall{$F(f)$}},position=top]
755    \connectnodes [FY,GY] [alternative=arrow,
756      label={\nodeSmall{$η_Y$}}, position=right]
757    \connectnodes [FX,GX] [alternative=arrow,
758      label={\nodeSmall{$η_X$}}, position=left]
759  \stopnodes
760\stopbuffer
761
762\typebuffer [option=TEX]
763
764Notice that, like for all \CONTEXT\ macros, one never mixes a
765comma|-|separated list of arguments (\type {[0,0]}) with a key=value list
766(i.e. \type {[reference=GX]}). Symbolic references are very useful for longer,
767more complicated diagrams; additionally, this easily allows modification such as
768the addition of nodes without having to keep track of counting the order in
769which they were drawn.
770
771An identity map, as shown in \in {Figure} [fig:ID], earlier, and, below, in \in
772{Figure} [fig:Me] is achieved by connecting a node to itself:
773
774\startbuffer
775\startnodes [dx=2cm,dy=1cm]
776  \placenode [0,0]  {\node{Me}}
777  \placenode [1,-1] {\node{You}}
778  \connectnodes [0,0] [alternative=arrow,
779    offset=.75cm,position=topright,
780    label=myself]
781  \connectnodes [1,1] [alternative=arrow,
782    offset=.75cm,position=bottomright,
783    label=yourself]
784\stopnodes
785\stopbuffer
786
787\startplacefigure [reference=fig:Me,title=Identity maps,
788                   location=right]
789  \getbuffer
790\stopplacefigure
791
792\typebuffer [option=TEX]
793
794The scale (diameter) of the circular loop|-|back is set by the keyword \type
795{offset=} (normally used to curve or bow|-|away a path connecting nodes from the
796straight|-|line segment between them), and the \type {position=} keyword sets its
797orientation.
798
799\startbuffer
800\startMPcode
801clearnodepath ;
802nodepath = fullsquare scaled 2cm ;
803save A ; A = 3 ; draw node(A,"\node{A}") ;
804save B ; B = 2 ; draw node(B,"\node{B}") ;
805save C ; C = 0 ; draw node(C,"\node{C}") ;
806save D ; D = 1 ; draw node(D,"\node{D}") ;
807
808drawarrow fromto(0,B,C) ;
809drawarrow fromto(0,A,D) crossingunder fromto(0,B,C) ;
810\stopMPcode
811\stopbuffer
812
813\startplacefigure [reference=fig:crossingunder,
814                   location={right,+3*hang},
815                   title=A$\rightarrow$D under B$\rightarrow$C]
816  \startframed [frame=off,width=5cm,align=middle]
817    \getbuffer
818  \stopframed
819\stopplacefigure
820
821Let us now consider the following code which illustrates the \METAFUN\ operator
822\type {crossingunder}
823\startfootnote
824    The operator \type {crossingunder} is of such general use that it has been
825    added to the \METAFUN\ base.
826\stopfootnote
827(see \in {Figure}[fig:crossingunder]). The \type {nodepath} indices are put into
828variables \type {A}, \type {B}, \type {C}, and \type {D}, thus simplifying the
829code.
830
831\typebuffer [option=TEX]
832
833\startplacefigure [reference=fig:sincos,
834                   location=right,
835                   title={\type{crossingunder}}]
836    \startMPcode
837        save u ; u := 2cm ;
838        save p ; path p[] ;
839        n := 64 ;
840        p2 := for i=0 upto n : if i>0 : .. fi (3u*(i/n), u*sind(720*(i/n))) endfor ;
841        p3 := for i=0 upto n : if i>0 : .. fi (3u*(i/n), u*cosd(720*(i/n))) endfor ;
842        p4 := point 0 of p2 -- point (length p2) of p2 shifted (left*.01u) ;
843
844        draw p2 withcolor red ;
845        begingroup ;
846            interim crossingscale := 20 ;
847            draw (p3 crossingunder p2) crossingunder p4 withcolor blue ;
848        endgroup ;
849        drawarrow (p4 crossingunder p2) ;
850    \stopMPcode
851\stopplacefigure
852
853Another illustration of the \type {crossingunder} operator in use is shown in \in
854{figure} [fig:sincos]. Because the diagrams are all defined and drawn in
855\METAPOST, one can easily use the power of \METAPOST\ to extend a simple node
856drawing with any kind of graphical decoration.
857
858This brings up an important point that has limited the development of a
859full|-|featured \CONTEXT\ module up to now. A pure \METAPOST\ interface affords
860much more flexibility than can be conveniently reduced to a set of \TeX\ macros;
861the \CONTEXT\ interface has been written to maintain only basic functionality.
862\startfootnote
863    One can use \type {\nodeMPcode{}} to inject arbitrary \METAPOST\ code within
864    a \type {\startnode}  \type {\stopnode} pair, although in this example one
865    is probably better off using the straight \METAPOST\ interface.
866\stopfootnote
867
868\stopsubject
869
870\startsubject [title=Cyclic diagrams]
871
872For a somewhat more complicated example, let us consider the representation of a
873catalytic process such as that given by \cite [author] [Krebs1946]. \cite
874[Krebs1946] The input is shown coming into the cycle from the center of a circle;
875the products of the cycle are spun|-|off from the outside of the circle. We start
876by defining a circular path where each point corresponds to a step in the cyclic
877process. Our example will use six steps (see \in {Figure} [fig:circles]).
878
879We also want to define a second circular path with the same number of points at
880the interior of this first circle for the input, and a third circular path at the
881exterior for the output.
882
883The code is as follows:
884
885\startbuffer
886\startMPcode
887  save p ; path p[] ;
888  % define a fullcircle path with nodes at 60° (rather than 45°)
889  p1 := (for i=0 step 60 until 300: dir(90-i) .. endfor cycle) scaled 2.5cm ;
890  p0 := p1 scaled  .5 ;
891  p2 := p1 scaled 1.5 ;
892
893  for i=0 upto 2:
894    draw p[i] ;
895    label.bot("\bf p" & decimal i, point 0 of p[i]) ;
896    for j=1 upto length p[i]:
897      draw point j of p[i] withpen currentpen scaled 10 withcolor red ;
898      if i=1:
899        label.autoalign(angle point j of p[i]) (decimal j, point j of p[i])
900                                                        withcolor red ;
901      fi
902    endfor
903  endfor
904\stopMPcode
905\stopbuffer
906
907\typebuffer [option=TEX]
908
909\startplacefigure [reference=fig:circles,
910  location=right,
911  title={The paths that we will use for the anchoring of nodes.}]
912  \getbuffer
913\stopplacefigure
914
915[\type {autoalign()} is a feature defined within \METAFUN.]
916
917Nodes will then be drawn on each of these three circles and arrows will be used
918to connect these various nodes, either on the same path or else between paths.
919
920The \METAPOST\ function \type {fromto()} is used to give a path segment that
921points from one node to another. It \emph {assumes} the path \type {nodepath},
922and in fact calls the function \type {fromtopaths} that explicitly takes path
923names as arguments. That is, \type {fromto (d, i, j, )} is equivalent to \type
924{fromtopaths (d, nodepath, i, nodepath, j, )}.
925
926As stated above, this segment can be a straight line or else a path that can be
927bowed|-|away from this straight line by a transverse displacement given by the
928function's first argument (given in units of the straight segment length). When
929both nodes are located on a single, defined path, this segment can be made to lie
930on or follow this path, such as one of the circular paths defined above. This
931behavior is obtained by using any non|-|numeric value (such as \type {true}) in
932place of the first argument. Of course, this cannot work if the two nodes are not
933located on the same path.
934
935The circular arc segments labeled \emph {\darkgreen a–f} are drawn on \in
936{figure} [fig:Bethe] using the following:
937
938\startTEX
939drawarrow fromtopaths.urt (true,p1,0,p1,1,"\nodeGreen{a}") ;
940\stopTEX
941
942for example, where \type {\nodeGreen} is a frame that inherits from \type
943{\node}, changing style and color:
944
945\startTEX
946\defineframed
947  [nodeGreen]
948  [node]
949  [foregroundcolor=darkgreen,
950   foregroundstyle=italic]
951\stopTEX
952
953The bowed|-|arrows feeding into the cyclic process and leading out to the
954products, thus between different paths, from the path \type {p0} to the path
955\type {p1} and from the path \type {p1} to the path \type {p2}, respectively, are
956drawn using the deviations \type {+3/10} and \type {-1/10} (to and from
957half|-|integer indices, thus mid|-|step, on path \type {p1}):
958
959\startTEX
960drawarrow fromtopaths( 3/10,p0,0,p1,0.5) withcolor .6white ;
961drawarrow fromtopaths(-1/10,p1,0.5,p2,1) withcolor .6white ;
962\stopTEX
963
964\startplacefigure [reference=fig:Bethe,
965  title={The \cite[author] [Bethe1939a] cycle for the energy production in stars
966         \cite[alternative=year,left=(,right=)] [Bethe1939a+Bethe1939b] in a
967         \cite[author] [Krebs1946] representation of a catalytic process
968         \cite[alternative=year,left=(,right=)] [Krebs1946].}]
969\startMPcode
970
971  % differs slightly from \reuseMPgraphic{nodes::krebs}
972
973  % The Bethe cycle for energy production in stars (1939), following Krebs (1946)
974
975  save p ; path p[] ;
976  p1 := (for i=0 step 60 until 300: dir(90-i).. endfor cycle) scaled 2.75cm ;
977  p0 := p1 scaled  .5 ;
978  p2 := p1 scaled 1.5 ;
979
980  bboxmargin := 0pt ;
981
982  draw node(p1,0,"\node{\chemical{^{12}C}}") ;
983  draw node(p1,1,"\node{\chemical{^{13}N}}") ;
984  draw node(p1,2,"\node{\chemical{^{13}C}}") ;
985  draw node(p1,3,"\node{\chemical{^{14}N}}") ;
986  draw node(p1,4,"\node{\chemical{^{15}O}}") ;
987  draw node(p1,5,"\node{\chemical{^{15}N}}") ;
988
989  drawarrow fromtopaths.urt (true,p1,0,p1,1,"\nodeGreen{a}") ;
990  drawarrow fromtopaths.rt  (true,p1,1,p1,2,"\nodeGreen{b}") ;
991  drawarrow fromtopaths.lrt (true,p1,2,p1,3,"\nodeGreen{c}") ;
992  drawarrow fromtopaths.llft(true,p1,3,p1,4,"\nodeGreen{d}") ;
993  drawarrow fromtopaths.lft (true,p1,4,p1,5,"\nodeGreen{e}") ;
994  drawarrow fromtopaths.ulft(true,p1,5,p1,6,"\nodeGreen{f}") ;
995
996  draw node(p0,0,"\node{\chemical{^1H}}") ;
997  draw node(p0,2,"\node{\chemical{^1H}}") ;
998  draw node(p0,3,"\node{\chemical{^1H}}") ;
999  draw node(p0,5,"\node{\chemical{^1H}}") ;
1000
1001  drawarrow fromtopaths(3/10,p0,0,p1,0.5) withcolor .6white ;
1002  drawarrow fromtopaths(3/10,p0,2,p1,2.5) withcolor .6white ;
1003  drawarrow fromtopaths(3/10,p0,3,p1,3.5) withcolor .6white ;
1004  drawarrow fromtopaths(3/10,p0,5,p1,5.5) withcolor .6white ;
1005
1006  draw node     (p2,0,"\node{\chemical{^4He}}") ;
1007  draw node     (p2,1,"\node{$γ$}") ;
1008  draw node.lrt (p2,2,"\node{$\mathrm{e}^+ + ν_\mathrm{e}$}") ;
1009  draw node     (p2,3,"\node{$γ$}") ;
1010  draw node     (p2,4,"\node{$γ$}") ;
1011  draw node.ulft(p2,5,"\node{$\mathrm{e}^+ + ν_\mathrm{e}$}") ;
1012
1013  drawarrow fromtopaths(-1/10,p1,0.5,p2,1) withcolor .6white ;
1014  drawarrow fromtopaths(-1/10,p1,1.5,p2,2) withcolor .6white ;
1015  drawarrow fromtopaths(-1/10,p1,2.5,p2,3) withcolor .6white ;
1016  drawarrow fromtopaths(-1/10,p1,3.5,p2,4) withcolor .6white ;
1017  drawarrow fromtopaths(-1/10,p1,4.5,p2,5) withcolor .6white ;
1018  drawarrow fromtopaths(-1/10,p1,5.5,p2,0) withcolor .6white ;
1019
1020\stopMPcode
1021\stopplacefigure
1022
1023\startsubsubject [title={A lesson in \METAPOST}]
1024
1025An \quote {array} of paths is declared through \type {path p[] ;} it is not a
1026formal array, but rather a syntactic definition of a collection of path variables
1027\type {p0}, \type {p1},  each of whose name is prefixed with the tag \quotation
1028{p} followed by any number, not necessarily an integer (e.g., \type {p3.14} is a
1029valid path name). The syntax allows enclosing this \quotation {index} within
1030square brackets, as in \type {p[0]} or, more typically, \type {p[i]}, where \type
1031{i} would be a numeric variable or the index of a loop. Note that the use of
1032brackets is required when using a negative index, as in \type {p[-1]} (for \type
1033{p-1} is interpreted as three tokens, representing a subtraction). Furthermore,
1034the variable \type {p} itself, would here be a numeric (by default), so \type
1035{p[p]} would be a valid syntactic construction! One could, additionally, declare
1036a set of variables \type {path p[][] ;} and so forth, defining also \type
1037{p[0][0]} (equivalently, \type {p0 0}) for example as a valid path, coexisting
1038with yet different from the path \type {p0}.
1039
1040\METAPOST\ also admits variable names reminiscent of a structure: \type {picture
1041p.pic[] ;} for example is used internally in the \type {node} macros, but this
1042becomes \type {picture p[]pic[] ;} when using a path \quote {array} syntax. These
1043variable names are associated with the suffix \type {p} and become all undefined
1044by \type {save p ;}.
1045
1046\stopsubsubject
1047
1048\startsubsubject [title={Putting it together}]
1049
1050What follows is simple example of a natural transformation, discovered and
1051articulated in the course of a philosophical research project (by Idris Samawi
1052Hamid). \in {Figure} [fig:NT] represents what is called the Croce Topos [named
1053after the Italian philosopher Benedetto Croce (18661952)]:
1054
1055\startbuffer
1056\startMPcode
1057  save nodepath ;
1058  path nodepath ;
1059  nodepath = ((0,0) -- (1,0) -- (3,0) --
1060              (3,1) -- (1,1) -- (0,1) --
1061              cycle) scaled 4cm ;
1062  draw node(0,"\node{Practical}") ;
1063  draw node(1,"\node{Economic}") ;
1064  draw node(2,"\node{Moral}") ;
1065  draw node(3,"\node{Conceptual}") ;
1066  draw node(4,"\node{Aesthetic}") ;
1067  draw node(5,"\node{Theoretical}") ;
1068
1069  drawarrow fromto.rt (.1,5,0,"\node{$γ$}") ;
1070  drawarrow fromto.lft(.1,0,5,"\node{$γ'$}") ;
1071  drawarrow fromto.rt (.1,4,1,"\node{$Fγ$}") ;
1072  drawarrow fromto.lft(.1,1,4,"\node{$Fγ'$}") ;
1073  drawarrow fromto.rt (.1,3,2,"\node{$Gγ$}") ;
1074  drawarrow fromto.lft(.1,2,3,"\node{$Gγ'$}") ;
1075
1076  drawarrow fromto.top( 0,4,3,"\node{\it concretization$_1$}") ;
1077  drawarrow fromto.bot(.1,3,4,"\node{\it abstraction$_1$}")
1078      dashed evenly ;
1079  drawarrow fromto.top( 0,1,2,"\node{\it concretization$_2$}") ;
1080  drawarrow fromto.bot(.1,2,1,"\node{\it abstraction$_2$}")
1081      dashed evenly ;
1082\stopMPcode
1083\stopbuffer
1084
1085% Let's forget that and rather use \startnodes...
1086
1087\startbuffer
1088\startnodes [dx=4cm,dy=4cm,alternative=arrow]
1089  \placenode [0,0] {\node{Practical}}
1090  \placenode [1,0] {\node{Economic}}
1091  \placenode [3,0] {\node{Moral}}
1092  \placenode [3,1] {\node{Conceptual}}
1093  \placenode [1,1] {\node{Aesthetic}}
1094  \placenode [0,1] {\node{Theoretical}}
1095
1096  \connectnodes [5,0] [offset=.1,position=right, label={\node{$γ$}}]
1097  \connectnodes [0,5] [offset=.1,position=left,  label={\node{$γ'$}}]
1098  \connectnodes [4,1] [offset=.1,position=right, label={\node{$$}}]
1099  \connectnodes [1,4] [offset=.1,position=left,  label={\node{$'$}}]
1100  \connectnodes [3,2] [offset=.1,position=right, label={\node{$$}}]
1101  \connectnodes [2,3] [offset=.1,position=left,  label={\node{$'$}}]
1102
1103  \connectnodes [4,3] [position=top, label={\node{\it concretization$_1$}}]
1104  \connectnodes [3,4] [postition=bottom,offset=.1, option=dashed,
1105                                     label={\node{\it abstraction$_1$}}]
1106  \connectnodes [1,2] [position=top, label={\node{\it concretization$_2$}}]
1107  \connectnodes [2,1] [position=bottom,offset=.1, option=dashed,
1108                                     label={\node{\it abstraction$_2$}}]
1109\stopnodes
1110\stopbuffer
1111
1112\startplacefigure [reference=fig:NT,
1113    title={A representation of the Croce Topos}]
1114    \getbuffer
1115\stopplacefigure
1116
1117Here we use the \CONTEXT\ interface to the node package:
1118
1119\typebuffer [option=TEX]
1120
1121\stopsubsubject
1122
1123\stopsubject
1124
1125\startsubject [title=Tree diagrams]
1126
1127The tree diagram shown in \in {Figure} [fig:DNA] is drawn using four paths, each
1128one defining a row or generation in the branching. The definition of the spacing
1129of nodes was crafted by hand and is somewhat arbitrary: 3.8, 1.7, and 1 for the
1130first, second and third generations. This might not be the best approach, but
1131this is how I was thinking when I first created this figure.
1132
1133\startplacefigure [location=force,reference=fig:DNA]
1134\startMPcode
1135  % third example: A tree diagram
1136
1137  save u ; u := 2.25cm ;
1138  save n ; n := 2 ; % n children per generation
1139
1140  save p ; path p[] ;
1141  p0 := origin ;
1142  numeric d[] ; d1 := 3.8 ; d2 := 1.7 ; d3 := 1 ;
1143  for g=1 upto 3:
1144    p[g] :=
1145      for i=0 upto length(p[g-1]):
1146        for c=0 upto n-1:
1147          if (i+c)>0: -- fi
1148          ((point i of p[g-1]) shifted (d[g]*(c/(n-1)-.5)*u,-u))
1149        endfor
1150      endfor ;
1151  endfor
1152
1153  draw node(p0,0,  "\node{DNA interactions with surfaces}") ;
1154  draw node(p1,0,  "\node{repulsive:}") ;
1155  draw node(p1,1,  "\node{attractive: adsorption}") ;
1156  draw node(p2,0,  "\node{confinement}") ;
1157  draw node(p2,1,  "\node[align=middle,location=high]{depletion,\\macromolecular\\crowding}") ;
1158  draw node(p2,2,  "\node{chemisorption}") ;
1159  draw node(p2,3,  "\node{physisorption}") ;
1160  draw node(p3,5.5,"\node{immobilized}") ;
1161  draw node(p3,7,  "\node{mobile}") ;
1162
1163  drawarrow fromtopaths(0,p0,0,p1,0) ;
1164  drawarrow fromtopaths(0,p0,0,p1,1) ;
1165
1166  drawarrow fromtopaths(0,p1,0,p2,0) ;
1167  drawarrow fromtopaths(0,p1,0,p2,1) ;
1168  drawarrow fromtopaths(0,p1,1,p2,2) ;
1169  drawarrow fromtopaths(0,p1,1,p2,3) ;
1170
1171  drawarrow fromtopaths(0,p2,2,p3,5.5) ;
1172  drawarrow fromtopaths(0,p2,3,p3,5.5) ;
1173  drawarrow fromtopaths(0,p2,3,p3,7) ;
1174
1175\stopMPcode
1176\stopplacefigure
1177
1178Ultimately, one can do better by allowing \METAPOST\ to solve the relevant
1179equations and to determine this spacing automatically. Because it is a somewhat
1180advanced procedure, this approach will be first illustrated through a very simple
1181example of a diagram where the nodes will be placed on a declared but undefined
1182path:
1183
1184\startTEX
1185save p ; % path p ;
1186\stopTEX
1187
1188The \type {save p ;} assures that the path is undefined. This path will later be
1189defined based on the contents of the nodes and a desired relative placement. In
1190fact, it is not even necessary to declare that the suffix will be a path, as the
1191path will be declared and automatically built once the positions of all the nodes
1192are determined. To emphasize this point, the \type {path} declaration above is
1193commented|-|out.
1194
1195\startdescription {Warning:}
1196Solving equations in \METAPOST\ can be non|-|trivial for those who are less
1197mathematically inclined. One needs to establish a coupled set of equations that
1198is solvable: that is, fully but not over|-|determined.
1199\stopdescription
1200
1201A few helper functions have been defined: \type {makenode()} returns a suffix
1202(variable name) corresponding to the node's position. The first such node can be
1203placed at any finite point, for example the drawing's origin. The following nodes
1204can be placed in relation to this first node:
1205
1206% \startframed [frame=off,align=text,offset=overlay] % keep this together on one page.
1207\startTEX
1208save nodepath ;
1209save first, second, third, fourth ;
1210pair first, second, third, fourth ;
1211first.i  = 0 ; first  = makenode(first.i, "\node{first}") ;
1212second.i = 1 ; second = makenode(second.i,"\node{second}") ;
1213third.i  = 2 ; third  = makenode(third.i, "\node{third}") ;
1214fourth.i = 3 ; fourth = makenode(fourth.i,"\node{fourth}") ;
1215
1216first  = origin ;
1217second = first
1218       + betweennodes.urt(nodepath,first.i, nodepath,second.i,whatever) ;
1219third  = second
1220       + betweennodes.lft(nodepath,second.i,nodepath,third.i, whatever) ;
1221fourth = third
1222       + betweennodes.bot(nodepath,fourth.i,nodepath,first.i,3ahlength) ;
1223\stopTEX
1224% \stopframed
1225
1226The helper function \type {betweennodes()} returns a vector pointing in a certain
1227direction, here following the standard \METAPOST\ suffixes: \type {urt}, \type
1228{lft}, and \type {bot}, that takes into account the bounding boxes of the
1229contents of each node, plus an (optional) additional distance (here given in
1230units of the arrow|-|head length, \type {ahlength}). Using the keyword \type
1231{whatever} tells \METAPOST\ to adjust this distance as necessary. The above set
1232of equations is incomplete as written, so a fifth and final relation needs to be
1233added; the fourth node is also to be located directly to the left of the very
1234first node:
1235\startfootnote
1236    Equivalently, we could declare that the first node located to the right of
1237    the fourth node: \type {first = fourth + betweennodes.rt (nodepath, first.i,
1238    nodepath, fourth.i, 3ahlength) ;}
1239\stopfootnote
1240
1241\startTEX
1242fourth = first
1243       + betweennodes.lft(nodepath,fourth.i,nodepath,first.i,3ahlength) ;
1244\stopTEX
1245
1246Note that the helper function \type {makenode()} can be used as many times as
1247needed; if given no content, only returning the node's position. Additional nodes
1248can be added to this diagram along with appropriate relational equations, keeping
1249in mind that the equations must, of course, be solvable. This last issue is the
1250one challenge that most users might face. The function \type {node()} that was
1251used previously and returning a picture element to be drawn itself calls the
1252function \type {makenode()}, used here. The nodes have not yet been drawn:
1253
1254\startplacefigure [location=right,reference=fig:relative]
1255\startMPcode
1256  save nodepath ;
1257  save first, second, third, fourth ;
1258  pair first, second, third, fourth ;
1259  first.i  = 0 ; first  = makenode(first.i, "\node{first}") ;
1260  second.i = 1 ; second = makenode(second.i,"\node{second}") ;
1261  third.i  = 2 ; third  = makenode(third.i, "\node{third}") ;
1262  fourth.i = 3 ; fourth = makenode(fourth.i,"\node{fourth}") ;
1263
1264  first  = origin ;
1265  second = first  + betweennodes.urt(nodepath,first.i, nodepath,second.i,whatever) ;
1266  third  = second + betweennodes.lft(nodepath,second.i,nodepath,third.i, whatever) ;
1267  fourth = third  + betweennodes.bot(nodepath,fourth.i,nodepath,first.i,3ahlength) ;
1268  fourth = first  + betweennodes.lft(nodepath,fourth.i,nodepath,first.i,3ahlength) ;
1269
1270  for i = first.i, second.i, third.i, fourth.i :
1271    draw node(i) ;
1272    drawarrow fromto(0,i,i+1) ;
1273  endfor
1274\stopMPcode
1275\stopplacefigure
1276
1277\startTEX
1278for i = first.i, second.i, third.i, fourth.i :
1279  draw node(i) ;
1280  drawarrow fromto(0,i,i+1) ;
1281endfor
1282\stopTEX
1283
1284This results in \in {Figure} [fig:relative]. The path is now defined as one
1285running through the position of all of the defined nodes, and is cyclic.
1286
1287Using this approach, that of defining but not drawing the nodes until a complete
1288set of equations defining their relative positions has been constructed, imposes
1289several limitations. First, the nodes are expected to be numbered from $0$ up to
1290$n$, continuously and without any gaps for each defined path. This is just an
1291implicit, heuristic convention of the path construction. Second, when finally
1292defining all the nodes and their positions, the path needs to be constructed. A
1293function, \type {makenodepath(p) ;} accomplishes this; it gets implicitly called
1294(once) upon the drawing of any \type {node()} or connecting \type {fromto}. Of
1295course, \type {makenodepath()} can always be called explicitly once the set of
1296equations determining the node positions is completely defined.
1297
1298\startparagraph [style=bold]
1299We once again stress that the writing of a solvable yet not over|-|determined set
1300of equations can be a common source of error for many \METAPOST\ users.
1301\startfootnote
1302    The generous use of descriptive variables as we try to illustrate in the
1303    examples here can help tremendously in keeping track of multiple equations.
1304\stopfootnote
1305\stopparagraph
1306
1307Another such example is the construction of a simple tree of descendance or
1308family tree. There are many ways to draw such a tree; in \in {figure}
1309[fig:descendance] we will show only three generations.
1310
1311\startplacefigure [location=here,reference=fig:descendance,
1312  title={A tree of descendance}]
1313\startMPcode
1314  save p ; % path p[], p[][] ; get automagically defined
1315  save spacing ; spacing = 5pt ;
1316  save d ; d = 4ahlength ;
1317
1318  save mother, father ; pair mother, father ;
1319
1320  mother = makenode(p,0,"\node{mother}") ;
1321  father = makenode(p,1,"\node{father}") ;
1322
1323  mother = origin ;
1324  father = mother + betweennodes.rt(p,0,p,1,spacing) ;
1325
1326  % first generation
1327  save child, spouse ; pair child[], spouse[] ;
1328  child = 0 ; spouse = 1 ;
1329
1330  child1  = makenode(p0,child, "\node{child1}") ;
1331  spouse1 = makenode(p0,spouse,"\node{spouse}") ;
1332  child2  = makenode(p1,child, "\node{child2}") ;
1333  spouse2 = makenode(p1,spouse,"\node{spouse}") ;
1334
1335  .5[child1,child2] = mother + d*down ;
1336  spouse1 = child1  + betweennodes.rt(p0,child, p0,spouse,spacing) ;
1337  child2  = spouse1 + betweennodes.rt(p0,spouse,p1,child, whatever) ;
1338  spouse2 = child2  + betweennodes.rt(p1,child, p1,spouse,spacing) ;
1339
1340  % second generation
1341  save grandchild, grandspouse ; pair grandchild[], grandspouse[] ;
1342  grandchild1  = makenode(p0 0,child, "\node{grandchild1}") ;
1343  grandspouse1 = makenode(p0 0,spouse,"\node{spouse}") ;
1344  grandchild2  = makenode(p0 1,child, "\node{grandchild2}") ;
1345  grandspouse2 = makenode(p0 1,spouse,"\node{spouse}") ;
1346  grandchild3  = makenode(p1 0,child, "\node{grandchild3}") ;
1347  grandspouse3 = makenode(p1 0,spouse,"\node{spouse}") ;
1348  grandchild4  = makenode(p1 1,child, "\node{grandchild4}") ;
1349  grandspouse4 = makenode(p1 1,spouse,"\node{spouse}") ;
1350
1351  .5[grandchild1,grandchild2]  = child1 + d*down ;
1352  .5[grandchild3,grandchild4]  = child2 + d*down ;
1353  grandchild2  = grandchild1 + betweennodes.rt(p0 0,child,p0 1,child,spacing) ;
1354  grandchild3  = grandchild2 + betweennodes.rt(p0 1,child,p1 0,child,spacing) ;
1355  grandchild4  = grandchild3 + betweennodes.rt(p1 0,child,p1 1,child,spacing) ;
1356  grandspouse1 = grandchild1 + nodeboundingpoint.bot(p0 0,child)
1357                             + nodeboundingpoint.lrt(p0 0,spouse) ;
1358  grandspouse2 = grandchild2 + nodeboundingpoint.bot(p0 1,child)
1359                             + nodeboundingpoint.lrt(p0 1,spouse) ;
1360  grandspouse3 = grandchild3 + nodeboundingpoint.bot(p1 0,child)
1361                             + nodeboundingpoint.lrt(p1 0,spouse) ;
1362  grandspouse4 = grandchild4 + nodeboundingpoint.bot(p1 1,child)
1363                             + nodeboundingpoint.lrt(p1 1,spouse) ;
1364
1365  draw node(p,0) ;
1366  draw node(p,1) withcolor blue ;
1367
1368  for i=0,1 :
1369    draw node(p[i],child) ;
1370    drawarrow fromtopaths(0,p,0,p[i],child) ;
1371    draw node(p[i],spouse) withcolor blue ;
1372    for j=0,1 :
1373      draw node(p[i][j],child) ;
1374      draw node(p[i][j],spouse) withcolor blue ;
1375    endfor
1376    drawarrow fromtopaths(0,p[i],child,p[i][0],child) ;
1377    drawarrow fromtopaths(0,p[i],child,p[i][1],child) ;
1378  endfor
1379\stopMPcode
1380\stopplacefigure
1381
1382We leave it as an exercise to the reader to come|-|up with the equations used to
1383determine this tree (one can look at source of this document, if necessary).
1384
1385The requisite set of equations could be hidden from the user wishing to construct
1386simple, pre|-|defined types of diagrams. However, such cases would involve a loss
1387of generality and flexibility. Nevertheless, the \ConTeXt-Nodes module \emph
1388{could} be extended in the future to provide a few simple models. One might be a
1389branching tree structure, although even the above example (as drawn) does not
1390easily fit into a simple, general model.
1391
1392\blank
1393
1394A user on the \CONTEXT\ mailing list asked if it is possible to make structure
1395trees for English sentences with categorical grammar, an example of which is
1396shown in \in {Figure} [fig:grammar].
1397
1398\startbuffer
1399\startMPcode
1400  save p ; path p[] ;
1401  save n ; n = 0 ;
1402  % rather than parsing a string, we can use "suffixes":
1403  forsuffixes $=People,from,the,country,can,become,quite,lonely :
1404    p[n] = makenode(p[n],0,"\node{\it" & (str $) & "}")
1405         = (n,0) ; % we work first with unit paths.
1406    n := n + 1 ;
1407  endfor
1408  save u ; u := MakeupWidth/n ; %(columns) TextWidth/n ;
1409
1410  % build upward tree
1411
1412  vardef makeparentnode(text t) =
1413    save i, xsum, xaverage, ymax ;
1414    i = xsum = 0 ;
1415    forsuffixes $ = t :
1416      clearxy ; z = point infinity of $ ;
1417      xsum := xsum + x ;
1418      if unknown ymax : ymax = y ; elseif y > ymax : ymax := y ; fi
1419      i := i + 1 ;
1420    endfor
1421    xaverage = xsum / i ;
1422    ymax := ymax + 1 ;
1423    forsuffixes $ = t :
1424      clearxy ;
1425      z = point infinity of $ ;
1426      $ := $ & z -- (x,ymax) if i>1 : -- (xaverage,ymax) fi ;
1427    endfor
1428  enddef ;
1429
1430  makeparentnode(p2,p3) ;
1431  makeparentnode(p4,p5) ;
1432  makeparentnode(p6,p7) ;
1433  makeparentnode(p1,p2) ;
1434  makeparentnode(p0,p1) ;
1435  makeparentnode(p4,p6) ;
1436  makeparentnode(p0,p4) ;
1437  makeparentnode(p0) ;
1438
1439  % the paths are all defined but need to be scaled.
1440
1441  for i=0 upto n-1 :
1442    p[i] := p[i] xyscaled (u,.8u) ;
1443    draw node(p[i],0) ;
1444  endfor
1445
1446  save followpath ; boolean followpath ; followpath = true ;
1447
1448  draw fromtopaths(followpath,p0,0,p0,1,"\node{H:N}") ;
1449  draw fromtopaths(followpath,p1,0,p1,1,"\node{Rel:Prep}") ;
1450  draw fromtopaths(followpath,p2,0,p2,1,"\node{Dr:Dv}") ;
1451  draw fromtopaths(followpath,p3,0,p3,1,"\node{H:N}") ;
1452  draw fromtopaths(followpath,p4,0,p4,1,"\node{M:Aux}") ;
1453  draw fromtopaths(followpath,p5,0,p5,1,"\node{H:Mv}") ;
1454  draw fromtopaths(followpath,p6,0,p6,1,"\node{M:Adv}") ;
1455  draw fromtopaths(followpath,p7,0,p7,1,"\node{H:Adj}") ;
1456
1457  draw fromtopaths(followpath,p1,1,p1,2) ;
1458  draw fromtopaths(followpath,p2,3,p2,4) ;
1459  draw fromtopaths(followpath,p1,2,p1,3,"\node{M:PP}") ;
1460  draw fromtopaths(followpath,p2,1,p2,2) ;
1461  draw fromtopaths(followpath,p3,1,p3,2) ;
1462  draw fromtopaths(followpath,p2,2,p2,3,"\node{Ax:NP}") ;
1463  draw fromtopaths(followpath,p4,1,p4,2) ;
1464  draw fromtopaths(followpath,p5,1,p5,2) ;
1465  draw fromtopaths(followpath,p4,2,p4,3,"\node{P:VP}") ;
1466  draw fromtopaths(followpath,p6,1,p6,2) ;
1467  draw fromtopaths(followpath,p7,1,p7,2) ;
1468  draw fromtopaths(followpath,p6,2,p6,3,"\node{PCs:AdjP}") ;
1469  draw fromtopaths(followpath,p0,1,p0,2) ;
1470  draw fromtopaths(followpath,p1,3,p1,4) ;
1471  draw fromtopaths(followpath,p0,2,p0,3,"\node{S:NP}") ;
1472  draw fromtopaths(followpath,p4,3,p4,4) ;
1473  draw fromtopaths(followpath,p6,3,p6,4) ;
1474  draw fromtopaths(followpath,p4,4,p4,5,"\node{Pred:PredP}") ;
1475  draw node(p0,4.5,"\node{Cl}") ;
1476  draw fromtopaths(followpath,p0,3,p0,4.5) ;
1477  draw fromtopaths(followpath,p4,5,p4,6) ;
1478\stopMPcode
1479\stopbuffer
1480
1481\startplacefigure [reference=fig:grammar,
1482    title={A categorical grammer structure tree}]
1483    \getbuffer
1484\stopplacefigure
1485
1486Here, I chose to define a series of parallel paths, one per word, with one path
1487terminating whenever it joins another path (or paths) at a common parent.
1488Naturally, labeling each branch of the tree structure requires a knowledge of the
1489tree structure. The code is not short, but hopefully it is mostly clear.
1490
1491\typebuffer [option=TEX]
1492
1493Note that diagrams such as those constructed here will each be significantly
1494different, making the writing of a general mechanism rather complex. For example,
1495one might need to construct a tree branching up rather than down, or to the right
1496(or left), or even following an arbitrary path, such as a random walk. These can
1497all be achieved individually in \METAPOST\ without too much difficulty.
1498
1499\stopsubject
1500
1501\startsubject [title=A 3D projection]
1502
1503Although \METAPOST\ is a 2D drawing language, it can be easily extended to work
1504in 3D. Several attempts have been made in the past ranging from simple to
1505complicated. Here, we will take a simple approach.
1506
1507The \METAPOST\ language includes a triplet variable type, used to handle \type
1508{rgb} colors (it also has a quadruplet type used for \type {cmyk} colors). We
1509will use this \type {triplet} type to hold 3D coordinates. There is a separate
1510\CONTEXT\ module, entitled \type {three}, which creates a new \METAPOST\ instance
1511(also named \type {three}), which loads a set of macros that can be used to
1512manipulate these triplet coordinates.
1513
1514\usemodule [three]
1515
1516\startTEX
1517\usemodule [three]
1518
1519\startMPcode{three}
1520  % code here
1521\stopMPcode
1522\stopTEX
1523
1524For our purposes here, only one function is really necessary: \type
1525{projection()} that maps a 3D coordinate to a 2D projection on the page. This
1526will not be a perspective projection having a viewpoint and a focus point, but
1527rather a very simple oblique projection, useful for, e.g., pseudo|-|3D schematic
1528drawings. The \type {Z} coordinate is taken to be \type {up} and the \type {Y}
1529coordinate taken to be \type {right}, both in the page of the paper. The third
1530coordinate \type {X} is an oblique projection in a right|-|hand coordinate
1531system.
1532
1533\startbuffer
1534\startMPcode{three}
1535  save nodepath ;
1536  path nodepath ;
1537  nodepath = (projection Origin --
1538              projection (1,0,0) --
1539              projection (1,1,0) --
1540              projection (0,1,0) --
1541              projection (0,1,1) --
1542              projection (1,1,1) --
1543              projection (1,0,1) --
1544              projection (0,0,1) --
1545              cycle) scaled 5cm ;
1546
1547  draw node(0,"\node{${\cal C}_{i\cal P}^{\mathrm{nt}}$}") ;
1548  draw node(1,"\node{${\cal C}_{i\cal G}^{\mathrm{nt}}$}") ;
1549  draw node(2,"\node{${\cal C}_{j\cal P}^{\mathrm{nt}}$}") ;
1550  draw node(3,"\node{${\cal C}_{j\cal G}^{\mathrm{nt}}$}") ;
1551  draw node(4,"\node{${\cal C}_{j\cal G}$}") ;
1552  draw node(5,"\node{${\cal C}_{j\cal P}$}") ;
1553  draw node(6,"\node{${\cal C}_{i\cal G}$}") ;
1554  draw node(7,"\node{${\cal C}_{i\cal P}$}") ;
1555
1556  interim crossingscale := 30 ;
1557  drawdoublearrows fromto(0,0,1) ;
1558  drawdoublearrows fromto(0,1,2) ;
1559  drawdoublearrows fromto(0,2,3) ;
1560  drawdoublearrows fromto(0,3,0) crossingunder fromto(0,2,5) ;
1561
1562  drawdoublearrows fromto(0,7,6) ;
1563  drawdoublearrows fromto(0,6,5) ;
1564  drawdoublearrows fromto.ulft(0,5,4,"\node{$τ_j$~}") ;
1565  drawdoublearrows fromto.top (0,7,4,"\node{$σ$}") ;
1566
1567  drawdoublearrows fromto.lrt(0,0,7,"\node{$Ψ^{\mathrm{nt}}$}")
1568                                  crossingunder fromto(0,6,5) ;
1569  drawdoublearrows fromto(0,1,6) ;
1570  drawdoublearrows fromto(0,2,5) ;
1571  drawdoublearrows fromto(0,3,4) ;
1572\stopMPcode
1573\stopbuffer
1574
1575\startplacefigure [location=right,
1576  reference=fig:cube]
1577  \getbuffer
1578\stopplacefigure
1579
1580Intended for schematic drawings, there is no automatic hidden|-|line removal nor
1581effects like shading, and line crossings need to be handled manually (using \type
1582{crossingunder} introduced previously). In \in{Figure} [fig:cube] we draw a
1583simple cubical commutative diagram, with a node at each corner.
1584
1585\typebuffer [option=TEX]
1586
1587Note the use of \type {drawdoublearrows}, a new \METAFUN\ command that is
1588introduced here.
1589
1590\stopsubject
1591
1592\startsubject [title=Two final examples]
1593
1594\startbuffer[mp:tikz-cd]
1595\startMPcode
1596  save nodepath ; save l ; l = 5ahlength ;
1597  save X, Y, Z, XxY, T ;
1598  pair X, Y, Z, XxY, T ;
1599  XxY.i = 0 ; XxY = makenode(XxY.i,"\node{$X\times_Z Y$}") ;
1600  X.i   = 1 ; X   = makenode(X.i,  "\node{$X$}") ;
1601  Z.i   = 2 ; Z   = makenode(Z.i,  "\node{$Z$}") ;
1602  Y.i   = 3 ; Y   = makenode(Y.i,  "\node{$Y$}") ;
1603  T.i   = 4 ; T   = makenode(T.i,  "\node{$T$}") ;
1604  XxY = origin ;
1605  X   = XxY + betweennodes.rt (nodepath,XxY.i,nodepath,X.i) + (l,0) ;
1606  Z   = X   + betweennodes.bot(nodepath,X.i,  nodepath,Z.i) + (0,-.8l);
1607  Y   = XxY + betweennodes.bot(nodepath,XxY.i,nodepath,Y.i) + (0,-.8l) ;
1608  T   = XxY + nodeboundingpoint.ulft(XxY.i)
1609            + nodeboundingpoint.lft (T.i) + l*dir(135) ;
1610  for i = XxY.i, X.i, Z.i, Y.i, T.i:
1611    draw node(i) ;
1612  endfor
1613  drawarrow fromto.top(0, XxY.i,X.i,  "\nodeSmall{$p$}") ;
1614  drawarrow fromto.rt (0,   X.i,Z.i,  "\nodeSmall{$f$}") ;
1615  drawarrow fromto.top(0,   Y.i,Z.i,  "\nodeSmall{$g$}") ;
1616  drawarrow fromto.rt (0, XxY.i,Y.i,  "\nodeSmall{$q$}") ;
1617  drawarrow fromto.top( .13,T.i,X.i,  "\nodeSmall{$x$}") ;
1618  drawarrow fromto.urt(-.13,T.i,Y.i,  "\nodeSmall{$y$}") ;
1619  drawarrow fromto    (0,   T.i,XxY.i,"\nodeSmall{$(x,y)$}")
1620      dashed withdots scaled .5
1621      withpen currentpen scaled 2 ;
1622\stopMPcode
1623\stopbuffer
1624
1625% Rather, let's do it similarly to TikZ.
1626
1627\startbuffer[mp:tikz-cd]
1628\startnodes [dx=2.5cm,dy=2cm,alternative=arrow]
1629  \placenode [0, 0] {\node{$X\times_Z Y$}}
1630  \placenode [1, 0] {\node{$X$}}
1631  \placenode [1,-1] {\node{$Z$}}
1632  \placenode [0,-1] {\node{$Y$}}
1633  \placenode [-1,1] {\node{$T$}}
1634
1635  \connectnodes [0,1] [position=top,   label={\nodeSmall{$p$}}]
1636  \connectnodes [1,2] [position=right, label={\nodeSmall{$f$}}]
1637  \connectnodes [0,3] [position=right, label={\nodeSmall{$q$}}]
1638  \connectnodes [3,2] [position=top,   label={\nodeSmall{$g$}}]
1639  \connectnodes [4,0] [option=dotted,rulethickness=1pt,
1640                                       label={\nodeSmall{$(x,y)$}}]
1641  \connectnodes [4,1] [offset=+.13,position=top,
1642                                       label={\nodeSmall{$x$}}]
1643  \connectnodes [4,3] [offset=-.13,position=topright,
1644                                       label={\nodeSmall{$y$}}]
1645\stopnodes
1646\stopbuffer
1647
1648\startplacefigure [reference=fig:tikz-cd,
1649                   location={right,+3*hang}]
1650    \getbuffer[mp:tikz-cd]
1651\stopplacefigure
1652
1653We end this manual with two examples of more advanced commutative diagrams. The
1654following example, shown in \in {Figure} [fig:tikz-cd], illustrates what in
1655category theory is called a \emph {pullback}. It is inspired from an example
1656given in the TikZ CD (commutative diagrams) package.
1657
1658The arrow labeled \quotation {$(x,y)$} is drawn \type {dashed withdots} and
1659illustrates how the line gets broken, implicitly \type {crossingunder} its
1660centered label.
1661
1662\typebuffer[mp:tikz-cd] [option=TEX]
1663
1664The previous diagram was drawn using the \CONTEXT\ interface. Our final example,
1665shown in \in {Figure} [fig:tikz-cd2], gives another \quotation {real|-|life}
1666example of a categorical pullback, also inspired by TikZ-CD, but this time drawn
1667through the \METAPOST\ interface and solving for positions.
1668
1669\startbuffer[mp:tikz-cd2]
1670\startMPcode
1671  save nodepath ; save l ; l = 5ahlength ;
1672  save A, B, C, D, E ;
1673  pair A, B, C, D, E ;
1674  A.i = 0 ; A = makenode(A.i,"\node{$\pi_1(U_1\cap U_2)$}") ;
1675  B.i = 1 ; B = makenode(B.i,
1676  "\node{$\pi_1(U_1)\ast_{\pi_1(U_1\cap U_2)}\pi_1(U_2)$}") ;
1677  C.i = 2 ; C = makenode(C.i,"\node{$\pi_1(X)$}") ;
1678  D.i = 3 ; D = makenode(D.i,"\node{$\pi_1(U_2)$}") ;
1679  E.i = 4 ; E = makenode(E.i,"\node{$\pi_1(U_1)$}") ;
1680  A = origin ;
1681  B = A + betweennodes.rt(nodepath,A.i,nodepath,B.i) + (  l,0) ;
1682  C = B + betweennodes.rt(nodepath,B.i,nodepath,C.i) + (.7l,0) ;
1683  D = .5[A,B] + (0,-.9l) ;
1684  E = .5[A,B] + (0, .9l) ;
1685
1686  for i = A.i, B.i, C.i, D.i, E.i :
1687      draw node(i) ;
1688  endfor
1689  drawarrow fromto.llft( 0,A.i,D.i,"\smallnode{$i_2$}") ;
1690  drawarrow fromto.ulft( 0,A.i,E.i,"\smallnode{$i_1$}") ;
1691  drawarrow fromto     ( 0,D.i,B.i) ;
1692  drawarrow fromto     ( 0,E.i,B.i) ;
1693  drawarrow fromto.urt( .1,E.i,C.i,"\smallnode{$j_1$}") ;
1694  drawarrow fromto.lrt(-.1,D.i,C.i,"\smallnode{$j_2$}") ;
1695  drawarrow fromto.top(  0,B.i,C.i) dashed evenly ;
1696  draw textext.top("{\tfxx\strut$\simeq$}")
1697      shifted point .4 of fromto(0,B.i,C.i) ;
1698\stopMPcode
1699\stopbuffer
1700
1701\startplacefigure [location=here,reference=fig:tikz-cd2]
1702    \getbuffer[mp:tikz-cd2]
1703\stopplacefigure
1704
1705\typebuffer[mp:tikz-cd2] [option=TEX]
1706
1707\stopsubject
1708
1709\startsubject [title=Conclusions]
1710
1711There was initial consensus at the 2017 \CONTEXT\ Meeting in Maibach, Germany,
1712where a version of this package was presented, that there was little use of
1713developing a purely \CONTEXT\ interface. Rather, the \METAPOST\ package should be
1714sufficiently accessible. Since then, however, we decided that the development of
1715a derivative \CONTEXT\ interface implementing some basic functionality could
1716indeed be useful for many users, although it will necessarily remain somewhat
1717limited. Users are recommended to turn to the pure \METAPOST\ interface when more
1718sophisticated functionality is needed.
1719
1720\stopsubject
1721
1722\startsubject [title=Acknowledgements]
1723
1724This module was inspired by a request made by Idris Samawi Hamid to draw a
1725natural transformation diagram (\in{Figure} [fig:natural]). The \METAPOST\ macros
1726that were developed then benefited from improvements suggested by Hans Hagen as
1727well as inspiration provided by Taco Hoekwater.
1728
1729The cover artwork one can recognize as coming under the hand of Hans Hagen that
1730he produced when I mentioned that I wanted to do something along these lines. It
1731fits very well into the style of manual covers that we distribute with \CONTEXT.
1732This manual therefore has been co|-|written by Hans and Alan.
1733
1734\stopsubject
1735
1736\startsubject [title=References]
1737
1738    \placelistofpublications
1739
1740\stopsubject
1741
1742\stoptitle
1743
1744\stoptext
1745