1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29\definemeasure [layout:margin] [\paperheight20]
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
79
80
81
82
83\setupitemize
84 [symbol=2]
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
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 = {88100}
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 = {103–103},
169 month = {Jan},
170 doi = {10.1103PhysRev.55.103},
171 issue = {1},
172 publisher = {American Physical Society},
173 XXurl = {http:link.aps.orgdoi10.1103PhysRev.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 = {434–456},
184 month = {Mar},
185 doi = {10.1103PhysRev.55.434},
186 issue = {5},
187 publisher = {American Physical Society},
188 XXurl = {http:link.aps.orgdoi10.1103PhysRev.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 = {08963207},
212 url = {https:www.tug.orgTUGboatContentscontents391.html},
213 language = {english},
214 }
215\stopbuffer
216
217\usebtxdefinitions [apa]
218\setupbtxrendering [apa] [pagestate=start]
219
220\usebtxdataset [bib.buffer]
221
222
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 ;
240 ahdimple := 45 ;
241
242 node_loopback_yscale := .7 ;
243\stopMPinitializations
244
245
246
247\defineframed
248 [mynode]
249 [node]
250 [offset=1pt,
251 foregroundcolor=white]
252
253\startreusableMPgraphic{nodes::krebs}
254
255
256
257
258 save p ; path p[] ;
259 p1 := (for i=0 step 60 until 300: dir(90i).. 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(310,p0,0,p1,0.5) withcolor white ;
283 drawarrow fromtopaths(310,p0,2,p1,2.5) withcolor white ;
284 drawarrow fromtopaths(310,p0,3,p1,3.5) withcolor white ;
285 drawarrow fromtopaths(310,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(-110,p1,0.5,p2,1) withcolor white ;
295 drawarrow fromtopaths(-110,p1,1.5,p2,2) withcolor white ;
296 drawarrow fromtopaths(-110,p1,2.5,p2,3) withcolor white ;
297 drawarrow fromtopaths(-110,p1,3.5,p2,4) withcolor white ;
298 drawarrow fromtopaths(-110,p1,4.5,p2,5) withcolor white ;
299 drawarrow fromtopaths(-110,p1,5.5,p2,0) withcolor white ;
300
301\stopreusableMPgraphic
302
303\startuseMPgraphic{CoverPage}
304
305 StartPage ;
306
307
308
309
310
311
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 (15 randomized 15))
319 shifted (center Page randomized (PaperWidth,PaperHeight)) ;
320 endfor ;
321
322 draw (textext.ulft("\word{\documentvariable{title}}") xsized (PaperWidth2))
323 shifted (lrcorner Page)
324 shifted (PaperWidth10,2PaperWidth10)
325 withcolor white;
326
327 draw (textext.ulft("\word{\documentvariable{author}}") xsized (PaperWidth2))
328 shifted (lrcorner Page)
329 shifted (PaperWidth10,PaperWidth10)
330 withcolor white;
331
332 StopPage ;
333
334\stopuseMPgraphic
335
336\startsetups document:start
337
338
339
340 \doifmodeelse {atpragma} {
341 \startMPpage[imagename=nodessunpia-03150]
342 \includeMPgraphic{CoverPage}
343 \stopMPpage
344 } {
345 \startMPpage[imagename=nodessunpia-03149]
346 \includeMPgraphic{CoverPage}
347 \stopMPpage
348 }
349
350\stopsetups
351
352\startsetups document:stop
353
354\stopsetups
355
356
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
378nonspecialists, 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 nodebased 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 nodebased 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 := 45 ;} The loopback arrow paths used here deviate from a
442 circular segment, becoming ellipsoidal, through the value \type
443 {nodeloopbackyscale := .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
448nodebased 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 andor 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 vectorgraphics 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 pseudoarray 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
555 setbounds currentpicture to boundingbox currentpicture
556 enlarged (.5cm,0) ;
557 \stopMPcode
558\stopplacefigure
559
560Lets 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
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
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
653turnedoff), 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 builtin 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 3cm 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
765commaseparated 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 loopback is set by the keyword \type
795{offset=} (normally used to curve or bowaway a path connecting nodes from the
796straightline 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(in), usind(720(in))) endfor ;
841 p3 := for i=0 upto n : if i>0 : .. fi (3u(in), ucosd(720(in))) 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
859fullfeatured \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 spunoff 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
889 p1 := (for i=0 step 60 until 300: dir(90i) .. 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
927bowedaway from this straight line by a transverse displacement given by the
928functions 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 nonnumeric 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 bowedarrows 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 {310} and \type {110} (to and from
957halfinteger indices, thus midstep, on path \type {p1}):
958
959\startTEX
960drawarrow fromtopaths( 310,p0,0,p1,0.5) withcolor .6white ;
961drawarrow fromtopaths(110,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=)] [Bethe1939aBethe1939b] in a
967 \cite[author] [Krebs1946] representation of a catalytic process
968 \cite[alternative=year,left=(,right=)] [Krebs1946].}]
969\startMPcode
970
971
972
973
974
975 save p ; path p[] ;
976 p1 := (for i=0 step 60 until 300: dir(90i).. 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(310,p0,0,p1,0.5) withcolor .6white ;
1002 drawarrow fromtopaths(310,p0,2,p1,2.5) withcolor .6white ;
1003 drawarrow fromtopaths(310,p0,3,p1,3.5) withcolor .6white ;
1004 drawarrow fromtopaths(310,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(-110,p1,0.5,p2,1) withcolor .6white ;
1014 drawarrow fromtopaths(-110,p1,1.5,p2,2) withcolor .6white ;
1015 drawarrow fromtopaths(-110,p1,2.5,p2,3) withcolor .6white ;
1016 drawarrow fromtopaths(-110,p1,3.5,p2,4) withcolor .6white ;
1017 drawarrow fromtopaths(-110,p1,4.5,p2,5) withcolor .6white ;
1018 drawarrow fromtopaths(-110,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{p1} 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 (1866–1952)]:
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
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{$Fγ$}}]
1099 \connectnodes [1,4] [offset=.1,position=left, label={\node{$Fγ$}}]
1100 \connectnodes [3,2] [offset=.1,position=right, label={\node{$Gγ$}}]
1101 \connectnodes [2,3] [offset=.1,position=left, label={\node{$Gγ$}}]
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
1136
1137 save u ; u := 2.25cm ;
1138 save n ; n := 2 ;
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 (ic)>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 ;
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
1193commentedout.
1194
1195\startdescription {Warning:}
1196Solving equations in \METAPOST\ can be nontrivial for those who are less
1197mathematically inclined. One needs to establish a coupled set of equations that
1198is solvable: that is, fully but not overdetermined.
1199\stopdescription
1200
1201A few helper functions have been defined: \type {makenode()} returns a suffix
1202(variable name) corresponding to the nodes position. The first such node can be
1203placed at any finite point, for example the drawings origin. The following nodes
1204can be placed in relation to this first node:
1205
1206
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
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 arrowhead 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 nodes 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,i1) ;
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 overdetermined 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 ;
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
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 ddown ;
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
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 ddown ;
1352 .5[grandchild3,grandchild4] = child2 ddown ;
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 comeup 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, predefined types of diagrams. However, such cases would involve a loss
1387of generality and flexibility. Nevertheless, the \ConTeXtNodes 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
1403 forsuffixes $=People,from,the,country,can,become,quite,lonely :
1404 p[n] = makenode(p[n],0,"\node{\it" & (str $) & "}")
1405 = (n,0) ;
1406 n := n 1 ;
1407 endfor
1408 save u ; u := MakeupWidthn ;
1409
1410
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
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
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., pseudo3D 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 righthand 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 hiddenline 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:tikzcd]
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) ldir(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
1626
1627\startbuffer[mp:tikzcd]
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:tikzcd,
1649 location={right,3*hang}]
1650 \getbuffer[mp:tikzcd]
1651\stopplacefigure
1652
1653We end this manual with two examples of more advanced commutative diagrams. The
1654following example, shown in \in {Figure} [fig:tikzcd], 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:tikzcd] [option=TEX]
1663
1664The previous diagram was drawn using the \CONTEXT\ interface. Our final example,
1665shown in \in {Figure} [fig:tikzcd2], gives another \quotation {reallife}
1666example of a categorical pullback, also inspired by TikZCD, but this time drawn
1667through the \METAPOST\ interface and solving for positions.
1668
1669\startbuffer[mp:tikzcd2]
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:tikzcd2]
1702 \getbuffer[mp:tikzcd2]
1703\stopplacefigure
1704
1705\typebuffer[mp:tikzcd2] [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 cowritten 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 |