diff options
Diffstat (limited to 'doc/context/sources/general/manuals/nodes/nodes.tex')
-rw-r--r-- | doc/context/sources/general/manuals/nodes/nodes.tex | 1706 |
1 files changed, 1706 insertions, 0 deletions
diff --git a/doc/context/sources/general/manuals/nodes/nodes.tex b/doc/context/sources/general/manuals/nodes/nodes.tex new file mode 100644 index 000000000..e9857f37e --- /dev/null +++ b/doc/context/sources/general/manuals/nodes/nodes.tex @@ -0,0 +1,1706 @@ +% interface=english modes=screen + +% author : Alan Braslau +% copyright : ConTeXt Development Team +% license : Creative Commons Attribution ShareAlike 4.0 International +% reference : pragma-ade.nl | contextgarden.net | texlive (related) distributions +% origin : the ConTeXt distribution +% +% comment : Because this manual is distributed with TeX distributions it comes with a rather +% liberal license. We try to adapt these documents to upgrades in the (sub)systems +% that they describe. Using parts of the content otherwise can therefore conflict +% with existing functionality and we cannot be held responsible for that. Many of +% the manuals contain characteristic graphics and personal notes or examples that +% make no sense when used out-of-context. +% +% comment : A prototype of the nodes module was presented at the ConTeXt 2016 user meeting +% and the first release was presented at the 2017 meeting. The module is part of +% the MetaFun code modules. +% +% comment : This manual orginates in an article by Alan so anything wrong in here is Hans +% fault as he converted it. +% +% comment : It is also being published as an article in TugBoat. +% +% comment : The cover images are from the NASA website. + + +% Alan : There is no need for % before \startfootnote .. the less such crap the better +% (as it might give disappearing content if one wraps). +% +% Alan : ḻṯ What is this? An editor glitch? +% +% Alan : $≠$ -> just use ≠ (also, soon the gyre fonts will have more symbols in text +% that match text. +% +% Alan : You can use \typ {x = 0} for something that breaks accross lines. + +%\enabletrackers[metapost.showlog] + +\definemeasure [layout:margin] [\paperheight/20] + +\setuplayout + [topspace=\measure{layout:margin}, + bottomspace=\measure{layout:margin}, + backspace=\measure{layout:margin}, + header=0pt, + footer=\measure{layout:margin}, + width=middle, + height=middle] + +\setupbodyfont + [dejavu,11pt] + +\setupwhitespace + [big] + +\setuphead + [chapter] + [style=\bfc, + interaction=all] + +\setuppagenumbering + [alternative=doublesided, + location=] + +\setupfootertexts + [\documentvariable{title}][\pagenumber] + [\pagenumber][\documentvariable{title}] + +\setuphead + [section] + [style=\bfb] + +\setuphead + [subsection] + [style=\bfa] + +\setuphead + [subsubsection] + [style=\bf, + after=] + +\setuplist + [interaction=all] + +\setupalign + [verytolerant,stretch] + +% \definesymbol [1] [$\cdot$] + +% Dot rather than bullet ... Alan hates bullets! Hans hates too small dots. + +\setupitemize + [symbol=2] % dash rather than bullet, I hate bullets! + +\setupnote + [footnote] + [next={ }, + split=verystrict, + scope=page] + +\setupinteraction + [state=start, + option=bookmark, + color=darkmagenta, + contrastcolor=darkmagenta] + +\setupinteractionscreen + [option=bookmark] + +\placebookmarks + [title,subject] + [title,subject] + +\enabledirectives + [references.bookmarks.preroll] + +\kindofpagetextareas\plusone % partial page. HH: low level, no high level switch (yet) + +\definetextbackground + [aside] + [location=paragraph, + frame=off, + leftoffset=1ex, + rightoffset=1ex, + topoffset=1ex, + bottomoffset=1ex, + background=color, + backgroundcolor=lightgray] + +\definedescription + [description] + [location=hanging, + width=broad, + before={\blank}, + after={\blank}] + +\defineparagraphs + [two] + [n=2, + offset=1ex, + background=color, + backgroundcolor=gray] + +\defineframed + [node] + [offset=1pt, + foregroundstyle=\tfa] + +\defineframed + [nodeGreen] + [node] + [foregroundcolor=darkgreen, + foregroundstyle=italic] + +\defineframed + [nodeSmall] + [node] + [foregroundstyle=\tfx] + +\startbuffer [bib] + @ARTICLE{Krebs1946, + author = {Krebs, H. A.}, + title = {Cyclic processes in living matter}, + journal = {Enzymologia}, + year = {1946}, + volume = {12}, + pages = {88--100} + } + + @ARTICLE{Bethe1939a, + author = {Bethe, H. A.}, + title = {Energy Production in Stars}, + journal = {Phys. Rev.}, + year = {1939}, + volume = {55}, + pages = {103–103}, + month = {Jan}, + doi = {10.1103/PhysRev.55.103}, + issue = {1}, + publisher = {American Physical Society}, + XXurl = {http://link.aps.org/doi/10.1103/PhysRev.55.103} + } + + @ARTICLE{Bethe1939b, + author = {Bethe, H. A.}, + title = {Energy Production in Stars}, + journal = {Phys. Rev.}, + year = {1939}, + volume = {55}, + pages = {434–456}, + month = {Mar}, + doi = {10.1103/PhysRev.55.434}, + issue = {5}, + publisher = {American Physical Society}, + XXurl = {http://link.aps.org/doi/10.1103/PhysRev.55.434} + } + + @BOOK{Lawvere2009, + author = {Lawvere, F. William and Schanuel, Stephen H.}, + title = {Conceptual Mathematics} + subtitle = {A first introduction to categories}, + edition = {2\high{nd}}, + publisher = {Cambridge University Press}, + address = {Cambridge, UK}, + year = {2009} + } +\stopbuffer + +\usebtxdefinitions [apa] +\setupbtxrendering [apa] [pagestate=start] % index cite pages in bibliography + +\usebtxdataset [bib.buffer] + +% Say, MP math arrows rather than font arrows: + +\useMPlibrary[mat] + +\definemathstackers + [mp] + [alternative=mp] + +\definemathextensible [mp] [leftarrow] ["2190] +\definemathextensible [mp] [rightarrow] ["2192] +\definemathextensible [mp] [leftrightarrow] ["2194] +\definemathextensible [mp] [longleftrightarrow] ["27F7] +\definemathextensible [mp] [rightoverleftarrow] ["21C4] + +\startMPinitializations + ahlength := EmWidth ; + ahangle := 30 ; + ahvariant := 1 ; % dimpled curved + ahdimple := 4/5 ; + + node_loopback_yscale := .7 ; +\stopMPinitializations + +% Only here do we use the special nodes:: instance + +\defineframed + [mynode] + [node] + [offset=1pt, + foregroundcolor=white] + +\startreusableMPgraphic{nodes::krebs} + + % The Bethe cycle for energy production in stars (1939), following + % Krebs (1946) + + save p ; path p[] ; + p1 := (for i=0 step 60 until 300: dir(90-i).. endfor cycle) scaled 2.75cm ; + p0 := p1 scaled .5 ; + p2 := p1 scaled 1.5 ; + + draw node(p1,0,"\mynode{\chemical{^{12}C}}") ; + draw node(p1,1,"\mynode{\chemical{^{13}N}}") ; + draw node(p1,2,"\mynode{\chemical{^{13}C}}") ; + draw node(p1,3,"\mynode{\chemical{^{14}N}}") ; + draw node(p1,4,"\mynode{\chemical{^{15}O}}") ; + draw node(p1,5,"\mynode{\chemical{^{15}N}}") ; + + drawarrow fromtopaths.urt (true,p1,0,p1,1,"\mynode{a}") withcolor white ; + drawarrow fromtopaths.rt (true,p1,1,p1,2,"\mynode{b}") withcolor white ; + drawarrow fromtopaths.lrt (true,p1,2,p1,3,"\mynode{c}") withcolor white ; + drawarrow fromtopaths.llft(true,p1,3,p1,4,"\mynode{d}") withcolor white ; + drawarrow fromtopaths.lft (true,p1,4,p1,5,"\mynode{e}") withcolor white ; + drawarrow fromtopaths.ulft(true,p1,5,p1,6,"\mynode{f}") withcolor white ; + + draw node(p0,0,"\mynode{\chemical{^1H}}") ; + draw node(p0,2,"\mynode{\chemical{^1H}}") ; + draw node(p0,3,"\mynode{\chemical{^1H}}") ; + draw node(p0,5,"\mynode{\chemical{^1H}}") ; + + drawarrow fromtopaths(3/10,p0,0,p1,0.5) withcolor white ; + drawarrow fromtopaths(3/10,p0,2,p1,2.5) withcolor white ; + drawarrow fromtopaths(3/10,p0,3,p1,3.5) withcolor white ; + drawarrow fromtopaths(3/10,p0,5,p1,5.5) withcolor white ; + + draw node (p2,0,"\mynode{\chemical{^4He}}") ; + draw node (p2,1,"\mynode{$γ$}") ; + draw node.lrt (p2,2,"\mynode{$\mathrm{e}^+ + ν_\mathrm{e}$}") ; + draw node (p2,3,"\mynode{$γ$}") ; + draw node (p2,4,"\mynode{$γ$}") ; + draw node.ulft(p2,5,"\mynode{$\mathrm{e}^+ + ν_\mathrm{e}$}") ; + + drawarrow fromtopaths(-1/10,p1,0.5,p2,1) withcolor white ; + drawarrow fromtopaths(-1/10,p1,1.5,p2,2) withcolor white ; + drawarrow fromtopaths(-1/10,p1,2.5,p2,3) withcolor white ; + drawarrow fromtopaths(-1/10,p1,3.5,p2,4) withcolor white ; + drawarrow fromtopaths(-1/10,p1,4.5,p2,5) withcolor white ; + drawarrow fromtopaths(-1/10,p1,5.5,p2,0) withcolor white ; + +\stopreusableMPgraphic + +\startuseMPgraphic{CoverPage} + + StartPage ; + + % Alan wanted a sun in the background combined somehow with the energy + % harvesting molecule so here we go. The images that are used come from + % the NASA website and I used them as screen saver for a while. The + % version that I generate uses a variant from the one on the user's + % machine. + + draw textext("\externalfigure[\framedparameter{imagename}]") + xsized PaperWidth ysized (PaperHeight+4cm) + shifted center Page shifted (0,2cm); + + for i=1 upto 512 : + draw (textext("\reuseMPgraphic{nodes::krebs}") scaled (1/5 randomized 1/5)) + shifted (center Page randomized (PaperWidth,PaperHeight)) ; + endfor ; + + draw (textext.ulft("\word{\documentvariable{title}}") xsized (PaperWidth/2)) + shifted (lrcorner Page) + shifted (-PaperWidth/10,2PaperWidth/10) + withcolor white; + + draw (textext.ulft("\word{\documentvariable{author}}") xsized (PaperWidth/2)) + shifted (lrcorner Page) + shifted (-PaperWidth/10,PaperWidth/10) + withcolor white; + + StopPage ; + +\stopuseMPgraphic + +\startsetups document:start + + % We each have our preferred cover... ;-) + + \doifmodeelse {atpragma} { + \startMPpage[imagename=nodes-sun-pia-03150] + \includeMPgraphic{CoverPage} + \stopMPpage + } { + \startMPpage[imagename=nodes-sun-pia-03149] + \includeMPgraphic{CoverPage} + \stopMPpage + } + +\stopsetups + +\startsetups document:stop + +\stopsetups + +% And now, the document! + +\startdocument + [title=Nodes, + author=Alan Braslau, + copyright=\ConTeXt\ development team, + version=1.0] + +\startsubject [title=Introduction] + +The graphical representation of textual diagrams is a very useful tool in the +communication of ideas. In category and topos theory, for example, many key +concepts, formulas, and theorems are expressed by means of \emph {commutative +diagrams}; these involve objects and arrows between them. Certain concepts +discovered by category theory, such as \emph {natural transformations}, are +becoming useful in areas outside of mathematics and natural science, e.g., in +philosophy. To make category and topos methods usable by both specialists and +non|-|specialists, commutative diagrams are an indispensable tool. +\startfootnote + For many examples of formal and informal commutative diagrams, see \cite + [authoryears] [Lawvere2009]. +\stopfootnote +The use of nodal diagrams is not limited to category theory, for they may +represent a flow diagram (of a process, for example), a chemical reaction +sequence or pathways, or that of phases and phase transitions, a hierarchical +structure (of anything), a timeline or sequence of events or dependencies, a tree +of descendance or ascendance, etc. + +The basic units of a node|-|based diagram include \emph {node objects}, each +attached to some point (= the \emph {node}) in some spatial relationship. Note +that to a single node might be associated a set of objects. Given a node, it also +stands in a spatial relation to some other node. The spatial relationship between +the set of nodes of a diagram need not be in a regular network, although they +quite often are. Note that the spatial relationship between nodes is graphical +and may represent, e.g., a temporal or logical relationship, or a transformation +of one object into another or into others (one interesting example might be that +representing cell division or, mitosis). + +Given a spatial relation between any two nodes, a node|-|based diagram often +includes some \emph {path segment} or segments (such as arrows or other curves) +between two given nodes that \emph {relates} them. Each path segment may be +augmented by some textual or graphical label. + +A very simple example of a node diagram is shown in \in{Figure} [fig:AB]. + +\startbuffer +\startMPcode + clearnodepath ; + nodepath = (left -- right) scaled .75cm ; + draw node(0,"A") ; + draw node(1,"B") ; + drawarrow fromto(0,0,1) ; +\stopMPcode +\stopbuffer + +\startplacefigure [reference=fig:AB] + \getbuffer +\stopplacefigure + +\startplacefigure [reference=fig:ID, + location={right,+2*hang}] +\startMPcode + clearnodepath ; nodepath = origin ; + draw node(0,"$O$") ; + drawarrow fromto.urt (.75cm,0,0) ; + setbounds currentpicture to boundingbox currentpicture + enlarged (1.2cm,0) ; +\stopMPcode +\stopplacefigure + +More precisely, a \emph {node} is a point of intersection or branching of paths, +often a point on a regular lattice. (The nodes of the above diagram are the two +endpoints of a straight line segment.) Sometimes, however, a node might be a +single point as in an \emph {identity map} of category theory, referring to +itself: +\startfootnote + The standard arrowhead in \METAPOST\ is a simple triangle, whose length and + angle can be adjusted. \METAFUN\ provides further options, allowing this + arrowhead to be barbed or dimpled. In the present article, we use the + settings: \type {ahlength := EmWidth ; ahangle := 30 ; ahvariant := 1 ; + ahdimple := 4/5 ;} The loop|-|back arrow paths used here deviate from a + circular segment, becoming ellipsoidal, through the value \type + {node_loopback_yscale := .7 ;} These are all set, of course, between a \type + {\startMPinitializations} … \type {\stopMPinitializations} pair. +\stopfootnote + +In this article we discuss a new \METAPOST\ module designed for handling +node|-|based graphics as well as a derivative simple \CONTEXT\ interface. To +illustrate, the code producing \inlinebuffer\ {could} be, in \METAPOST\ and the +\CONTEXT\ interface respectively: + +\starttwo + \METAPOST + \startTEX + \startMPcode + draw node(0,"A") ; + draw node(1,"B") ; + drawarrow fromto(0,1) ; + \stopMPcode + \stopTEX +\two + \CONTEXT + \startbuffer + \startnodes [dx=1.5cm] + \placenode [0,0] {A} + \placenode [1,0] {B} + \connectnodes [0,1] + [alternative=arrow] + \stopnodes + \stopbuffer + \typebuffer [option=TEX] +\stoptwo + +drawing an arrow from A to B (or from node 0 to node 1): \getbuffer + +\startitemize[packed] + \startitem + The \METAPOST\ code shown above has been slightly simplified, as will be + seen later. + \stopitem + \startitem + The \CONTEXT\ interface as used here is limited and will be explained a + little later. + \stopitem +\stopitemize + +For beginners or casual users of \CONTEXT\ |<|including those who might be +intimidated by \METAPOST\ syntax|>| the ability to construct simple diagrams by +means of standard \CONTEXT\ syntax is very helpful. For those who have tried the +\CONTEXT\ interface and/or want to draw more advanced diagrams, the \METAPOST\ +module is much more powerful and flexible. + +\stopsubject + +\startsubject [title=\METAPOST] + +\METAPOST\ is a vector|-|graphics language which calls upon \TeX\ to typeset text +(such as labels); in \CONTEXT, furthermore, \METAPOST\ is integrated natively +through the library MPlib as well as the macro package \METAFUN. The tight +integration of \CONTEXT\ and \METAPOST\ provides advantages over the use of +other, external graphics engines. These advantages include ease of maintaining +coherence of style, as well as extensive flexibility without bloat. \METAPOST\ +has further advantages over most other graphics engines, including a very high +degree of precision as well as the possibility to solve certain types of +algebraic equations. This last feature is rarely used but should not be +overlooked. + +It is quite natural in \METAPOST\ to locate our node objects along a path or on +differing paths. This is a much more powerful concept than merely locating a node +at some pair of coordinates, e.g., on a square or a rectangular lattice, for +example (as in a table). Furthermore, these paths may be in three dimensions (or +more); of course the printed page will only involve some projection onto two +dimensions. Nor are the nodes restricted to location on the points defining a +path: they may have, as index, any \emph {time} along a given path \type {p} +ranging from the first defining point ($t = 0$) up to the last point of that path +($t ≤ \mathtt {length(p)}$), the number of defining points of a path. +\startfootnote + Note that the time of a cyclic path is taken modulo the length of the path, + that is $t$ outside of the range $[\mathtt0,\mathtt{length(p)}]$ will return + the first or the last point of an open path, but will \quotation {wrap} for a + closed path. +\stopfootnote + +Given a path \type {p}, nodes are defined (implicitly) as \type {picture} +elements: \type {picture p.pic[] ;} This is a pseudo|-|array where the square +brackets indicates a set of numerical tokens, as in \type {p.pic[0]} or \type +{p.pic[i]} (for \type {i=0}), but also \type {p.pic0}. This number need not be an +integer, and \type {p.pic[.5]} or \type {p.pic.5} (not to be confused with \type +{p.pic5}) are also valid. These picture elements are taken to be located relative +to the path \type {p}, with the index \type {t} corresponding to a time along the +path, as in \type {draw p.pic[t] shifted point t of p;} (although it is not +necessary to draw them in this way). This convention allows the nodes to be +oriented and offset with respect to the path in an arbitrary manner. + +Note that a path can be defined, then nodes placed relative to this path. Or the +path may be declared but remain undefined, to be determined only after the nodes +are declared. In yet another possibility, the path may be adjusted as needed, as +a function of whatever nodes are to be occupied. This will be illustrated through +examples further down. + +\stopsubject + +\startsubject [title=A few simple examples] + +\startplacefigure [location=right,reference=fig:square] + \startMPcode + path p ; p := fullsquare scaled 3cm ; + draw p ; + for i=0 upto length p: + draw point i of p + withcolor red + withpen pencircle scaled 5pt ; + endfor ; + % this looks better in the figure placement: + setbounds currentpicture to boundingbox currentpicture + enlarged (.5cm,0) ; + \stopMPcode +\stopplacefigure + +Let's begin with illustration of a typical commutative diagram from category +theory. Although it may appear trivial, this example helps to introduce +\METAPOST\ syntax. At the same time, a large part of the idea behind this module +is to facilitate use of this system without having to learn much \METAPOST. + +A path is drawn as well as the points defining the path. + +%\flushsidefloats + +\startTEX +\startMPcode + path p ; p := fullsquare scaled 3cm ; draw p ; + for i=0 upto length p: + draw point i of p + withcolor red + withpen pencircle scaled 5pt ; + endfor ; +\stopMPcode +\stopTEX + +\startbuffer +\startMPcode + clearnodepath ; + nodepath = p ; + draw node(0,"\node{$G(X)$}") ; + draw node(1,"\node{$G(Y)$}") ; + draw node(2,"\node{$F(Y)$}") ; + draw node(3,"\node{$F(X)$}") ; + drawarrow fromto.bot(0,0,1, "\nodeSmall{$G(f)$}") ; + drawarrow fromto.top(0,3,2, "\nodeSmall{$F(f)$}") ; + drawarrow fromto.rt (0,2,1, "\nodeSmall{$η_Y$}") ; + drawarrow fromto.lft(0,3,0, "\nodeSmall{$η_X$}") ; +\stopMPcode +\stopbuffer + +\startplacefigure [location={right,+1*hang},reference=fig:natural, + title={Drawn using \METAPOST\ interface}] + \getbuffer +\stopplacefigure + +Given the named path \type {nodepath}, we can now define and draw nodes as well +as connections between them (see \in{Figure} [fig:natural]): + +%\flushsidefloats + +\typebuffer [option=TEX] + +\startaside +In working with \METAPOST, it is good practice to reset or clear a variable using +the directive \type {save} for the \emph {suffix} (or variable name) \type +{nodepath} contained in the directive \type {clearnodepath} (defined as +\quotation {\type {save nodepath ; path nodepath}}). The macros used here rely on +the creation of certain internal variables and may not function correctly if the +variable structure is not cleared. Indeed, any node may contain a combination of +picture elements, added successively, so it is very important to \type {save} the +variable, making its use local, rather than global. This point is particularly +true with \CONTEXT, where a single MPlib instance is used and maintained over +multiple runs. + +The \CONTEXT\ directives \type {\startMPcode} … \type {\stopMPcode} include +grouping (\METAPOST\ \type {begingroup ;}… \type {endgroup ;}) and the use of +\type {save} (in \type {clearnodepath}) will make the suffix \type {nodepath} +local to this code block. In the code for \in{Figures} [fig:square] and \in +[fig:natural], the path \type {p} itself is not declared local (through the use +of a \type {save}); it therefore remains available for other \METAPOST\ code +blocks. We cannot do this with the default suffix name \type {nodepath} without +undesired consequences. + +The directive \type {clearnodepath} used in the example above, much like the +\METAPOST\ command \type {clearxy} clearing the \type {(x,y)} pair also known as +\type {z}, uses \type {save} to clear the default suffix \type {nodepath}. +\stopaside + +Note that one should not confuse the \METAPOST\ function \type {node()} with the +\CONTEXT\ command \type {\node{}}, defined as follows: + +\starttwo + \startTEX + \defineframed + [node] + [frame=off, + offset=1pt] + \stopTEX +\two + \startTEX + \defineframed + [nodeSmall] + [node] + [foregroundstyle=small] + \stopTEX +\stoptwo + +\type {\node{}} places the text within a \CONTEXT\ frame (with the frame border +turned|-|off), whereas the \METAPOST\ function \type {node(i,"…")} sets and +returns a picture element associated with a point on path \type {nodepath} +indexed by its first argument. The second argument here is a string that gets +typeset by \TEX. (The use of \type {\node{}} adds an \type {offset}). + +By default, the \METAPOST\ function \type {fromto()} returns a path segment going +between two points of the path \type {nodepath}. The first argument (\type {0} in +the example above) can be used as a displacement to skew the path away from a +straight line (by an amount in units of the straight path length). The last +argument is a string to be typeset and placed midpoint of the segment. The +{suffix} appended to the function name gives an offset around this halfway point. +This follows standard \METAPOST\ conventions. + +It is important to draw or declare the nodes \emph {before} drawing the +connections, using \type {fromto()}, in order to be able to avoid overlapping +symbols, as one notices that the arrows drawn in the example above begin and end +on the border of the frame (or bounding box) surrounding the node text. This +would of course not be possible if the arrow were to be drawn before this text +was known. + +As will be seen further on, one can actually specify the use of any defined path, +without restriction to the built|-|in name \type {nodepath} that is used by +default. Furthermore, a function \type {fromtopaths()} can be used to draw +segments connecting any two paths which may be distinct. This too will be +illustrated further on. + +The \CONTEXT\ syntax for the current example looks like this: + +\startbuffer + \startnodes [dx=3cm,dy=3cm] + \placenode [0,0] {\node{$G(X)$}} + \placenode [1,0] {\node{$G(Y)$}} + \placenode [1,1] {\node{$F(Y)$}} + \placenode [0,1] {\node{$F(X)$}} + \connectnodes [0,1] [alternative=arrow, + label={\nodeSmall{$G(f)$}},position=bottom] + \connectnodes [3,2] [alternative=arrow, + label={\nodeSmall{$F(f)$}},position=top] + \connectnodes [2,1] [alternative=arrow, + label={\nodeSmall{$η_Y$}}, position=right] + \connectnodes [3,0] [alternative=arrow, + label={\nodeSmall{$η_X$}}, position=left] + \stopnodes +\stopbuffer + +\startplacefigure [location=right, + title={Drawn using \CONTEXT\ interface}] + \getbuffer +\stopplacefigure + +\typebuffer [option=TEX] + +\startplacefigure [reference=fig:indices, + location=right, + title={Coordinates and indices.\footnote{For variety, a rectangular oblique + lattice is drawn in \in{Figure} [fig:indices].} + }] +\stopfootnote + \startframed [frame=off,width=.33\textwidth,align=flushright] + \startnodes [dx=3cm,dy=2cm,rotation=60] + \placenode [0,0] {\node{(0,0)}} + \placenode [1,0] {\node{(1,0)}} + \placenode [1,1] {\node{(1,1)}} + \placenode [0,1] {\node{(0,1)}} + \connectnodes [0,1] [alternative=arrow, + label={\nodeSmall{$0\rightarrow1$}},position=bottom] + \connectnodes [3,2] [alternative=arrow, + label={\nodeSmall{$3\rightarrow2$}},position=top] + \connectnodes [2,1] [alternative=arrow, + label={\nodeSmall{$~2\rightarrow1$}}, position=right] + \connectnodes [3,0] [alternative=arrow, + label={\nodeSmall{$3\rightarrow0$}}, position=upperleft] + \stopnodes + \stopframed +\stopplacefigure + +This follows the more classic (and limited) approach of placing nodes on the +coordinates of a regular lattice, here defined as a 3~cm square network. +\footnote {The lattice can be square (\type {dx} $=$ \type {dy}), rectangular +(\type {dx} $≠$ \type {dy}), or oblique (through \type {rotation} $≠$ 90).} The +arguments are then $(x,y)$ coordinates of this lattice and the nodes are indexed +0, 1, 2, … in the order that they are drawn. These are used as reference indices +in the commands \type {\connectnodes} (rather than requiring two \emph {pairs} of +coordinates); see \in {Figure} [fig:indices]. This might seem a bit confusing at +first view, but it simplifies things in the end, really! + +An identity map, as shown in \in {Figure} [fig:ID], earlier, and, below, in \in +{Figure} [fig:Me] is achieved by connecting a node to itself: + +\startbuffer +\startnodes [dx=2cm,dy=1cm] + \placenode [0,0] {\node{Me}} + \placenode [1,-1] {\node{You}} + \connectnodes [0,0] [alternative=arrow, + offset=.75cm,position=topright, + label=myself] + \connectnodes [1,1] [alternative=arrow, + offset=.75cm,position=bottomright, + label=yourself] +\stopnodes +\stopbuffer + +\startplacefigure [reference=fig:Me,title=Identity maps, + location=right] + \getbuffer +\stopplacefigure + +\typebuffer [option=TEX] + +The scale (diameter) of the circular loop|-|back is set by the keyword \type +{offset=} (normally used to curve or bow|-|away a path connecting nodes from the +straight|-|line segment between them), and the \type {position=} keyword sets its +orientation. + +\page [yes] + +\startbuffer +\startMPcode +clearnodepath ; +nodepath = fullsquare scaled 2cm ; +save A ; A = 3 ; draw node(A,"\node{A}") ; +save B ; B = 2 ; draw node(B,"\node{B}") ; +save C ; C = 0 ; draw node(C,"\node{C}") ; +save D ; D = 1 ; draw node(D,"\node{D}") ; + +drawarrow fromto(0,B,C) ; +drawarrow fromto(0,A,D) crossingunder fromto(0,B,C) ; +\stopMPcode +\stopbuffer + +\startplacefigure [reference=fig:crossingunder, + location={right,+3*hang}, + title=A$\rightarrow$D under B$\rightarrow$C] + \startframed [frame=off,width=5cm,align=middle] + \getbuffer + \stopframed +\stopplacefigure + +Let us now consider the following code which illustrates the \METAFUN\ operator +\type {crossingunder} +\startfootnote + The operator \type {crossingunder} is of such general use that it has been + added to the \METAFUN\ base. +\stopfootnote +(see \in {Figure}[fig:crossingunder]). The \type {nodepath} indices are put into +variables \type {A}, \type {B}, \type {C}, and \type {D}, thus simplifying the +code. + +\typebuffer [option=TEX] + +\startplacefigure [reference=fig:sincos, + location=right, + title={\type{crossingunder}}] + \startMPcode + save u ; u := 2cm ; + save p ; path p[] ; + n := 64 ; + p2 := for i=0 upto n : if i>0 : .. fi (3u*(i/n), u*sind(720*(i/n))) endfor ; + p3 := for i=0 upto n : if i>0 : .. fi (3u*(i/n), u*cosd(720*(i/n))) endfor ; + p4 := point 0 of p2 -- point (length p2) of p2 shifted (left*.01u) ; + + draw p2 withcolor red ; + begingroup ; + interim crossingscale := 20 ; + draw (p3 crossingunder p2) crossingunder p4 withcolor blue ; + endgroup ; + drawarrow (p4 crossingunder p2) ; + \stopMPcode +\stopplacefigure + +Another illustration of the \type {crossingunder} operator in use is shown in \in +{figure} [fig:sincos]. Because the diagrams are all defined and drawn in +\METAPOST, one can easily use the power of \METAPOST\ to extend a simple node +drawing with any kind of graphical decoration. + +This brings up an important point that has limited the development of a +full|-|featured \CONTEXT\ module up to now. A pure \METAPOST\ interface affords +much more flexibility than can be conveniently reduced to a set of \TeX\ macros; +the \CONTEXT\ interface has been written to maintain only basic functionality. +\startfootnote + One can use \type {\nodeMPcode{}} to inject arbitrary \METAPOST\ code within + a \type {\startnode} … \type {\stopnode} pair, although in this example one + is probably better off using the straight \METAPOST\ interface. +\stopfootnote + +\stopsubject + +\startsubject [title=Cyclic diagrams] + +For a somewhat more complicated example, let us consider the representation of a +catalytic process such as that given by \cite [author] [Krebs1946]. \cite +[Krebs1946] The input is shown coming into the cycle from the center of a circle; +the products of the cycle are spun|-|off from the outside of the circle. We start +by defining a circular path where each point corresponds to a step in the cyclic +process. Our example will use six steps (see \in {Figure} [fig:circles]). + +We also want to define a second circular path with the same number of points at +the interior of this first circle for the input, and a third circular path at the +exterior for the output. + +The code is as follows: + +\page [yes] + +\startbuffer +\startMPcode + save p ; path p[] ; + % define a fullcircle path with nodes at 60° (rather than 45°) + p1 := (for i=0 step 60 until 300: dir(90-i) .. endfor cycle) scaled 2.5cm ; + p0 := p1 scaled .5 ; + p2 := p1 scaled 1.5 ; + + for i=0 upto 2: + draw p[i] ; + label.bot("\bf p" & decimal i, point 0 of p[i]) ; + for j=1 upto length p[i]: + draw point j of p[i] withpen currentpen scaled 10 withcolor red ; + if i=1: + label.autoalign(angle point j of p[i]) (decimal j, point j of p[i]) + withcolor red ; + fi + endfor + endfor +\stopMPcode +\stopbuffer + +\typebuffer [option=TEX] + +\startplacefigure [reference=fig:circles, + location=right, + title={The paths that we will use for the anchoring of nodes.}] + \getbuffer +\stopplacefigure + +[\type {autoalign()} is a feature defined within \METAFUN.] + +Nodes will then be drawn on each of these three circles and arrows will be used +to connect these various nodes, either on the same path or else between paths. + +The \METAPOST\ function \type {fromto()} is used to give a path segment that +points from one node to another. It \emph {assumes} the path \type {nodepath}, +and in fact calls the function \type {fromtopaths} that explicitly takes path +names as arguments. That is, \type {fromto (d, i, j, …)} is equivalent to \type +{fromtopaths (d, nodepath, i, nodepath, j, …)}. + +As stated above, this segment can be a straight line or else a path that can be +bowed|-|away from this straight line by a transverse displacement given by the +function's first argument (given in units of the straight segment length). When +both nodes are located on a single, defined path, this segment can be made to lie +on or follow this path, such as one of the circular paths defined above. This +behavior is obtained by using any non|-|numeric value (such as \type {true}) in +place of the first argument. Of course, this cannot work if the two nodes are not +located on the same path. + +The circular arc segments labeled \emph {\darkgreen a–f} are drawn on \in +{figure} [fig:Bethe] using the following: + +\startTEX +drawarrow fromtopaths.urt (true,p1,0,p1,1,"\nodeGreen{a}") ; +\stopTEX + +for example, where \type {\nodeGreen} is a frame that inherits from \type +{\node}, changing style and color: + +\startTEX +\defineframed + [nodeGreen] + [node] + [foregroundcolor=darkgreen, + foregroundstyle=italic] +\stopTEX + +The bowed|-|arrows feeding into the cyclic process and leading out to the +products, thus between different paths, from the path \type {p0} to the path +\type {p1} and from the path \type {p1} to the path \type {p2}, respectively, are +drawn using the deviations \type {+3/10} and \type {-1/10} (to and from +half|-|integer indices, thus mid|-|step, on path \type {p1}): + +\startTEX +drawarrow fromtopaths( 3/10,p0,0,p1,0.5) withcolor .6white ; +drawarrow fromtopaths(-1/10,p1,0.5,p2,1) withcolor .6white ; +\stopTEX + +\startplacefigure [reference=fig:Bethe, + title={The \cite[author] [Bethe1939a] cycle for the energy production in stars + \cite[alternative=year,left=(,right=)] [Bethe1939a+Bethe1939b] in a + \cite[author] [Krebs1946] representation of a catalytic process + \cite[alternative=year,left=(,right=)] [Krebs1946].}] +\startMPcode + + % differs slightly from \reuseMPgraphic{nodes::krebs} + + % The Bethe cycle for energy production in stars (1939), following Krebs (1946) + + save p ; path p[] ; + p1 := (for i=0 step 60 until 300: dir(90-i).. endfor cycle) scaled 2.75cm ; + p0 := p1 scaled .5 ; + p2 := p1 scaled 1.5 ; + + bboxmargin := 0pt ; + + draw node(p1,0,"\node{\chemical{^{12}C}}") ; + draw node(p1,1,"\node{\chemical{^{13}N}}") ; + draw node(p1,2,"\node{\chemical{^{13}C}}") ; + draw node(p1,3,"\node{\chemical{^{14}N}}") ; + draw node(p1,4,"\node{\chemical{^{15}O}}") ; + draw node(p1,5,"\node{\chemical{^{15}N}}") ; + + drawarrow fromtopaths.urt (true,p1,0,p1,1,"\nodeGreen{a}") ; + drawarrow fromtopaths.rt (true,p1,1,p1,2,"\nodeGreen{b}") ; + drawarrow fromtopaths.lrt (true,p1,2,p1,3,"\nodeGreen{c}") ; + drawarrow fromtopaths.llft(true,p1,3,p1,4,"\nodeGreen{d}") ; + drawarrow fromtopaths.lft (true,p1,4,p1,5,"\nodeGreen{e}") ; + drawarrow fromtopaths.ulft(true,p1,5,p1,6,"\nodeGreen{f}") ; + + draw node(p0,0,"\node{\chemical{^1H}}") ; + draw node(p0,2,"\node{\chemical{^1H}}") ; + draw node(p0,3,"\node{\chemical{^1H}}") ; + draw node(p0,5,"\node{\chemical{^1H}}") ; + + drawarrow fromtopaths(3/10,p0,0,p1,0.5) withcolor .6white ; + drawarrow fromtopaths(3/10,p0,2,p1,2.5) withcolor .6white ; + drawarrow fromtopaths(3/10,p0,3,p1,3.5) withcolor .6white ; + drawarrow fromtopaths(3/10,p0,5,p1,5.5) withcolor .6white ; + + draw node (p2,0,"\node{\chemical{^4He}}") ; + draw node (p2,1,"\node{$γ$}") ; + draw node.lrt (p2,2,"\node{$\mathrm{e}^+ + ν_\mathrm{e}$}") ; + draw node (p2,3,"\node{$γ$}") ; + draw node (p2,4,"\node{$γ$}") ; + draw node.ulft(p2,5,"\node{$\mathrm{e}^+ + ν_\mathrm{e}$}") ; + + drawarrow fromtopaths(-1/10,p1,0.5,p2,1) withcolor .6white ; + drawarrow fromtopaths(-1/10,p1,1.5,p2,2) withcolor .6white ; + drawarrow fromtopaths(-1/10,p1,2.5,p2,3) withcolor .6white ; + drawarrow fromtopaths(-1/10,p1,3.5,p2,4) withcolor .6white ; + drawarrow fromtopaths(-1/10,p1,4.5,p2,5) withcolor .6white ; + drawarrow fromtopaths(-1/10,p1,5.5,p2,0) withcolor .6white ; + +\stopMPcode +\stopplacefigure + +\startsubsubject [title={A lesson in \METAPOST}] + +An \quote {array} of paths is declared through \type {path p[] ;} it is not a +formal array, but rather a syntactic definition of a collection of path variables +\type {p0}, \type {p1}, … each of whose name is prefixed with the tag \quotation +{p} followed by any number, not necessarily an integer (e.g., \type {p3.14} is a +valid path name). The syntax allows enclosing this \quotation {index} within +square brackets, as in \type {p[0]} or, more typically, \type {p[i]}, where \type +{i} would be a numeric variable or the index of a loop. Note that the use of +brackets is required when using a negative index, as in \type {p[-1]} (for \type +{p-1} is interpreted as three tokens, representing a subtraction). Furthermore, +the variable \type {p} itself, would here be a numeric (by default), so \type +{p[p]} would be a valid syntactic construction! One could, additionally, declare +a set of variables \type {path p[][] ;} and so forth, defining also \type +{p[0][0]} (equivalently, \type {p0 0}) for example as a valid path, coexisting +with yet different from the path \type {p0}. + +\METAPOST\ also admits variable names reminiscent of a structure: \type {picture +p.pic[] ;} for example is used internally in the \type {node} macros, but this +becomes \type {picture p[]pic[] ;} when using a path \quote {array} syntax. These +variable names are associated with the suffix \type {p} and become all undefined +by \type {save p ;}. + +\stopsubsubject + +\startsubsubject [title={Putting it together}] + +What follows is simple example of a natural transformation, discovered and +articulated in the course of a philosophical research project (by Idris Samawi +Hamid). \in {Figure} [fig:NT] represents what is called the Croce Topos [named +after the Italian philosopher Benedetto Croce (1866–1952)]: + +\startbuffer +\startMPcode + save nodepath ; + path nodepath ; + nodepath = ((0,0) -- (1,0) -- (3,0) -- + (3,1) -- (1,1) -- (0,1) -- + cycle) scaled 4cm ; + draw node(0,"\node{Practical}") ; + draw node(1,"\node{Economic}") ; + draw node(2,"\node{Moral}") ; + draw node(3,"\node{Conceptual}") ; + draw node(4,"\node{Aesthetic}") ; + draw node(5,"\node{Theoretical}") ; + + drawarrow fromto.rt (.1,5,0,"\node{$γ$}") ; + drawarrow fromto.lft(.1,0,5,"\node{$γ'$}") ; + drawarrow fromto.rt (.1,4,1,"\node{$Fγ$}") ; + drawarrow fromto.lft(.1,1,4,"\node{$Fγ'$}") ; + drawarrow fromto.rt (.1,3,2,"\node{$Gγ$}") ; + drawarrow fromto.lft(.1,2,3,"\node{$Gγ'$}") ; + + drawarrow fromto.top( 0,4,3,"\node{\it concretization$_1$}") ; + drawarrow fromto.bot(.1,3,4,"\node{\it abstraction$_1$}") + dashed evenly ; + drawarrow fromto.top( 0,1,2,"\node{\it concretization$_2$}") ; + drawarrow fromto.bot(.1,2,1,"\node{\it abstraction$_2$}") + dashed evenly ; +\stopMPcode +\stopbuffer + +% Let's forget that and rather use \startnodes... + +\startbuffer +\startnodes [dx=4cm,dy=4cm,alternative=arrow] + \placenode [0,0] {\node{Practical}} + \placenode [1,0] {\node{Economic}} + \placenode [3,0] {\node{Moral}} + \placenode [3,1] {\node{Conceptual}} + \placenode [1,1] {\node{Aesthetic}} + \placenode [0,1] {\node{Theoretical}} + + \connectnodes [5,0] [offset=.1,position=right, label={\node{$γ$}}] + \connectnodes [0,5] [offset=.1,position=left, label={\node{$γ'$}}] + \connectnodes [4,1] [offset=.1,position=right, label={\node{$Fγ$}}] + \connectnodes [1,4] [offset=.1,position=left, label={\node{$Fγ'$}}] + \connectnodes [3,2] [offset=.1,position=right, label={\node{$Gγ$}}] + \connectnodes [2,3] [offset=.1,position=left, label={\node{$Gγ'$}}] + + \connectnodes [4,3] [position=top, label={\node{\it concretization$_1$}}] + \connectnodes [3,4] [postition=bottom,offset=.1, option=dashed, + label={\node{\it abstraction$_1$}}] + \connectnodes [1,2] [position=top, label={\node{\it concretization$_2$}}] + \connectnodes [2,1] [position=bottom,offset=.1, option=dashed, + label={\node{\it abstraction$_2$}}] +\stopnodes +\stopbuffer + +\startplacefigure [reference=fig:NT, + title={A representation of the Croce Topos}] + \getbuffer +\stopplacefigure + +Here we use the \CONTEXT\ interface to the node package: + +\typebuffer [option=TEX] + +\stopsubsubject + +\stopsubject + +\startsubject [title=Tree diagrams] + +The tree diagram shown in \in {Figure} [fig:DNA] is drawn using four paths, each +one defining a row or generation in the branching. The definition of the spacing +of nodes was crafted by hand and is somewhat arbitrary: 3.8, 1.7, and 1 for the +first, second and third generations. This might not be the best approach, but +this is how I was thinking when I first created this figure. + +\startplacefigure [location=force,reference=fig:DNA] +\startMPcode + % third example: A tree diagram + + save u ; u := 2.25cm ; + save n ; n := 2 ; % n children per generation + + save p ; path p[] ; + p0 := origin ; + numeric d[] ; d1 := 3.8 ; d2 := 1.7 ; d3 := 1 ; + for g=1 upto 3: + p[g] := + for i=0 upto length(p[g-1]): + for c=0 upto n-1: + if (i+c)>0: -- fi + ((point i of p[g-1]) shifted (d[g]*(c/(n-1)-.5)*u,-u)) + endfor + endfor ; + endfor + + draw node(p0,0, "\node{DNA interactions with surfaces}") ; + draw node(p1,0, "\node{repulsive:}") ; + draw node(p1,1, "\node{attractive: adsorption}") ; + draw node(p2,0, "\node{confinement}") ; + draw node(p2,1, "\node[align=middle,location=high]{depletion,\\macromolecular\\crowding}") ; + draw node(p2,2, "\node{chemisorption}") ; + draw node(p2,3, "\node{physisorption}") ; + draw node(p3,5.5,"\node{immobilized}") ; + draw node(p3,7, "\node{mobile}") ; + + drawarrow fromtopaths(0,p0,0,p1,0) ; + drawarrow fromtopaths(0,p0,0,p1,1) ; + + drawarrow fromtopaths(0,p1,0,p2,0) ; + drawarrow fromtopaths(0,p1,0,p2,1) ; + drawarrow fromtopaths(0,p1,1,p2,2) ; + drawarrow fromtopaths(0,p1,1,p2,3) ; + + drawarrow fromtopaths(0,p2,2,p3,5.5) ; + drawarrow fromtopaths(0,p2,3,p3,5.5) ; + drawarrow fromtopaths(0,p2,3,p3,7) ; + +\stopMPcode +\stopplacefigure + +Ultimately, one can do better by allowing \METAPOST\ to solve the relevant +equations and to determine this spacing automatically. Because it is a somewhat +advanced procedure, this approach will be first illustrated through a very simple +example of a diagram where the nodes will be placed on a declared but undefined +path: + +\startTEX +save p ; % path p ; +\stopTEX + +The \type {save p ;} assures that the path is undefined. This path will later ḻṯ +defined based on the contents of the nodes and a desired relative placement. In +fact, it is not even necessary to declare that the suffix will be a path, as the +path will be declared and automatically built once the positions of all the nodes +are determined. To emphasize this point, the \type {path} declaration above is +commented|-|out. + +\startdescription {Warning:} +Solving equations in \METAPOST\ can be non|-|trivial for those who are less +mathematically inclined. One needs to establish a coupled set of equations that +is solvable: that is, fully but not over|-|determined. +\stopdescription + +A few helper functions have been defined: \type {makenode()} returns a suffix +(variable name) corresponding to the node's position. The first such node can be +placed at any finite point, for example the drawing's origin. The following nodes +can be placed in relation to this first node: + +% \startframed [frame=off,align=text,offset=overlay] % keep this together on one page. +\startTEX +save nodepath ; +save first, second, third, fourth ; +pair first, second, third, fourth ; +first.i = 0 ; first = makenode(first.i, "\node{first}") ; +second.i = 1 ; second = makenode(second.i,"\node{second}") ; +third.i = 2 ; third = makenode(third.i, "\node{third}") ; +fourth.i = 3 ; fourth = makenode(fourth.i,"\node{fourth}") ; + +first = origin ; +second = first + + betweennodes.urt(nodepath,first.i, nodepath,second.i,whatever) ; +third = second + + betweennodes.lft(nodepath,second.i,nodepath,third.i, whatever) ; +fourth = third + + betweennodes.bot(nodepath,fourth.i,nodepath,first.i,3ahlength) ; +\stopTEX +% \stopframed + +The helper function \type {betweennodes()} returns a vector pointing in a certain +direction, here following the standard \METAPOST\ suffixes: \type {urt}, \type +{lft}, and \type {bot}, that takes into account the bounding boxes of the +contents of each node, plus an (optional) additional distance (here given in +units of the arrow|-|head length, \type {ahlength}). Using the keyword \type +{whatever} tells \METAPOST\ to adjust this distance as necessary. The above set +of equations is incomplete as written, so a fifth and final relation needs to be +added; the fourth node is also to be located directly to the left of the very +first node: +\startfootnote + Equivalently, we could declare that the first node located to the right of + the fourth node: \type {first = fourth + betweennodes.rt (nodepath, first.i, + nodepath, fourth.i, 3ahlength) ;} +\stopfootnote + +\startTEX +fourth = first + + betweennodes.lft(nodepath,fourth.i,nodepath,first.i,3ahlength) ; +\stopTEX + +Note that the helper function \type {makenode()} can be used as many times as +needed; if given no content, only returning the node's position. Additional nodes +can be added to this diagram along with appropriate relational equations, keeping +in mind that the equations must, of course, be solvable. This last issue is the +one challenge that most users might face. The function \type {node()} that was +used previously and returning a picture element to be drawn itself calls the +function \type {makenode()}, used here. The nodes have not yet been drawn: + +\startplacefigure [location=right,reference=fig:relative] +\startMPcode + save nodepath ; + save first, second, third, fourth ; + pair first, second, third, fourth ; + first.i = 0 ; first = makenode(first.i, "\node{first}") ; + second.i = 1 ; second = makenode(second.i,"\node{second}") ; + third.i = 2 ; third = makenode(third.i, "\node{third}") ; + fourth.i = 3 ; fourth = makenode(fourth.i,"\node{fourth}") ; + + first = origin ; + second = first + betweennodes.urt(nodepath,first.i, nodepath,second.i,whatever) ; + third = second + betweennodes.lft(nodepath,second.i,nodepath,third.i, whatever) ; + fourth = third + betweennodes.bot(nodepath,fourth.i,nodepath,first.i,3ahlength) ; + fourth = first + betweennodes.lft(nodepath,fourth.i,nodepath,first.i,3ahlength) ; + + for i = first.i, second.i, third.i, fourth.i : + draw node(i) ; + drawarrow fromto(0,i,i+1) ; + endfor +\stopMPcode +\stopplacefigure + +\startTEX +for i = first.i, second.i, third.i, fourth.i : + draw node(i) ; + drawarrow fromto(0,i,i+1) ; +endfor +\stopTEX + +This results in \in {Figure} [fig:relative]. The path is now defined as one +running through the position of all of the defined nodes, and is cyclic. + +Using this approach, that of defining but not drawing the nodes until a complete +set of equations defining their relative positions has been constructed, imposes +several limitations. First, the nodes are expected to be numbered from $0$ up to +$n$, continuously and without any gaps for each defined path. This is just an +implicit, heuristic convention of the path construction. Second, when finally +defining all the nodes and their positions, the path needs to be constructed. A +function, \type {makenodepath(p) ;} accomplishes this; it gets implicitly called +(once) upon the drawing of any \type {node()} or connecting \type {fromto}. Of +course, \type {makenodepath()} can always be called explicitly once the set of +equations determining the node positions is completely defined. + +\startparagraph [style=bold] +We once again stress that the writing of a solvable yet not over|-|determined set +of equations can be a common source of error for many \METAPOST\ users. +\startfootnote + The generous use of descriptive variables as we try to illustrate in the + examples here can help tremendously in keeping track of multiple equations. +\stopfootnote +\stopparagraph + +Another such example is the construction of a simple tree of descendance or +family tree. There are many ways to draw such a tree; in \in {figure} +[fig:descendance] we will show only three generations. + +\startplacefigure [location=here,reference=fig:descendance, + title={A tree of descendance}] +\startMPcode + save p ; % path p[], p[][] ; get automagically defined + save spacing ; spacing = 5pt ; + save d ; d = 4ahlength ; + + save mother, father ; pair mother, father ; + + mother = makenode(p,0,"\node{mother}") ; + father = makenode(p,1,"\node{father}") ; + + mother = origin ; + father = mother + betweennodes.rt(p,0,p,1,spacing) ; + + % first generation + save child, spouse ; pair child[], spouse[] ; + child = 0 ; spouse = 1 ; + + child1 = makenode(p0,child, "\node{child1}") ; + spouse1 = makenode(p0,spouse,"\node{spouse}") ; + child2 = makenode(p1,child, "\node{child2}") ; + spouse2 = makenode(p1,spouse,"\node{spouse}") ; + + .5[child1,child2] = mother + d*down ; + spouse1 = child1 + betweennodes.rt(p0,child, p0,spouse,spacing) ; + child2 = spouse1 + betweennodes.rt(p0,spouse,p1,child, whatever) ; + spouse2 = child2 + betweennodes.rt(p1,child, p1,spouse,spacing) ; + + % second generation + save grandchild, grandspouse ; pair grandchild[], grandspouse[] ; + grandchild1 = makenode(p0 0,child, "\node{grandchild1}") ; + grandspouse1 = makenode(p0 0,spouse,"\node{spouse}") ; + grandchild2 = makenode(p0 1,child, "\node{grandchild2}") ; + grandspouse2 = makenode(p0 1,spouse,"\node{spouse}") ; + grandchild3 = makenode(p1 0,child, "\node{grandchild3}") ; + grandspouse3 = makenode(p1 0,spouse,"\node{spouse}") ; + grandchild4 = makenode(p1 1,child, "\node{grandchild4}") ; + grandspouse4 = makenode(p1 1,spouse,"\node{spouse}") ; + + .5[grandchild1,grandchild2] = child1 + d*down ; + .5[grandchild3,grandchild4] = child2 + d*down ; + grandchild2 = grandchild1 + betweennodes.rt(p0 0,child,p0 1,child,spacing) ; + grandchild3 = grandchild2 + betweennodes.rt(p0 1,child,p1 0,child,spacing) ; + grandchild4 = grandchild3 + betweennodes.rt(p1 0,child,p1 1,child,spacing) ; + grandspouse1 = grandchild1 + nodeboundingpoint.bot(p0 0,child) + + nodeboundingpoint.lrt(p0 0,spouse) ; + grandspouse2 = grandchild2 + nodeboundingpoint.bot(p0 1,child) + + nodeboundingpoint.lrt(p0 1,spouse) ; + grandspouse3 = grandchild3 + nodeboundingpoint.bot(p1 0,child) + + nodeboundingpoint.lrt(p1 0,spouse) ; + grandspouse4 = grandchild4 + nodeboundingpoint.bot(p1 1,child) + + nodeboundingpoint.lrt(p1 1,spouse) ; + + draw node(p,0) ; + draw node(p,1) withcolor blue ; + + for i=0,1 : + draw node(p[i],child) ; + drawarrow fromtopaths(0,p,0,p[i],child) ; + draw node(p[i],spouse) withcolor blue ; + for j=0,1 : + draw node(p[i][j],child) ; + draw node(p[i][j],spouse) withcolor blue ; + endfor + drawarrow fromtopaths(0,p[i],child,p[i][0],child) ; + drawarrow fromtopaths(0,p[i],child,p[i][1],child) ; + endfor +\stopMPcode +\stopplacefigure + +We leave it as an exercise to the reader to come|-|up with the equations used to +determine this tree (one can look at source of this document, if necessary). + +The requisite set of equations could be hidden from the user wishing to construct +simple, pre|-|defined types of diagrams. However, such cases would involve a loss +of generality and flexibility. Nevertheless, the \ConTeXt-Nodes module \emph +{could} be extended in the future to provide a few simple models. One might be a +branching tree structure, although even the above example (as drawn) does not +easily fit into a simple, general model. + +\blank + +A user on the \CONTEXT\ mailing list asked if it is possible to make structure +trees for English sentences with categorical grammar, an example of which is +shown in \in {Figure} [fig:grammar]. + +\startbuffer +\startMPcode + save p ; path p[] ; + save n ; n = 0 ; + % rather than parsing a string, we can use "suffixes": + forsuffixes $=People,from,the,country,can,become,quite,lonely : + p[n] = makenode(p[n],0,"\node{\it" & (str $) & "}") + = (n,0) ; % we work first with unit paths. + n := n + 1 ; + endfor + save u ; u := MakeupWidth/n ; %(columns) TextWidth/n ; + + % build upward tree + + vardef makeparentnode(text t) = + save i, xsum, xaverage, ymax ; + i = xsum = 0 ; + forsuffixes $ = t : + clearxy ; z = point infinity of $ ; + xsum := xsum + x ; + if unknown ymax : ymax = y ; elseif y > ymax : ymax := y ; fi + i := i + 1 ; + endfor + xaverage = xsum / i ; + ymax := ymax + 1 ; + forsuffixes $ = t : + clearxy ; + z = point infinity of $ ; + $ := $ & z -- (x,ymax) if i>1 : -- (xaverage,ymax) fi ; + endfor + enddef ; + + makeparentnode(p2,p3) ; + makeparentnode(p4,p5) ; + makeparentnode(p6,p7) ; + makeparentnode(p1,p2) ; + makeparentnode(p0,p1) ; + makeparentnode(p4,p6) ; + makeparentnode(p0,p4) ; + makeparentnode(p0) ; + + % the paths are all defined but need to be scaled. + + for i=0 upto n-1 : + p[i] := p[i] xyscaled (u,.8u) ; + draw node(p[i],0) ; + endfor + + save followpath ; boolean followpath ; followpath = true ; + + draw fromtopaths(followpath,p0,0,p0,1,"\node{H:N}") ; + draw fromtopaths(followpath,p1,0,p1,1,"\node{Rel:Prep}") ; + draw fromtopaths(followpath,p2,0,p2,1,"\node{Dr:Dv}") ; + draw fromtopaths(followpath,p3,0,p3,1,"\node{H:N}") ; + draw fromtopaths(followpath,p4,0,p4,1,"\node{M:Aux}") ; + draw fromtopaths(followpath,p5,0,p5,1,"\node{H:Mv}") ; + draw fromtopaths(followpath,p6,0,p6,1,"\node{M:Adv}") ; + draw fromtopaths(followpath,p7,0,p7,1,"\node{H:Adj}") ; + + draw fromtopaths(followpath,p1,1,p1,2) ; + draw fromtopaths(followpath,p2,3,p2,4) ; + draw fromtopaths(followpath,p1,2,p1,3,"\node{M:PP}") ; + draw fromtopaths(followpath,p2,1,p2,2) ; + draw fromtopaths(followpath,p3,1,p3,2) ; + draw fromtopaths(followpath,p2,2,p2,3,"\node{Ax:NP}") ; + draw fromtopaths(followpath,p4,1,p4,2) ; + draw fromtopaths(followpath,p5,1,p5,2) ; + draw fromtopaths(followpath,p4,2,p4,3,"\node{P:VP}") ; + draw fromtopaths(followpath,p6,1,p6,2) ; + draw fromtopaths(followpath,p7,1,p7,2) ; + draw fromtopaths(followpath,p6,2,p6,3,"\node{PCs:AdjP}") ; + draw fromtopaths(followpath,p0,1,p0,2) ; + draw fromtopaths(followpath,p1,3,p1,4) ; + draw fromtopaths(followpath,p0,2,p0,3,"\node{S:NP}") ; + draw fromtopaths(followpath,p4,3,p4,4) ; + draw fromtopaths(followpath,p6,3,p6,4) ; + draw fromtopaths(followpath,p4,4,p4,5,"\node{Pred:PredP}") ; + draw node(p0,4.5,"\node{Cl}") ; + draw fromtopaths(followpath,p0,3,p0,4.5) ; + draw fromtopaths(followpath,p4,5,p4,6) ; +\stopMPcode +\stopbuffer + +\startplacefigure [reference=fig:grammar, + title={A categorical grammer structure tree}] + \getbuffer +\stopplacefigure + +Here, I chose to define a series of parallel paths, one per word, with one path +terminating whenever it joins another path (or paths) at a common parent. +Naturally, labeling each branch of the tree structure requires a knowledge of the +tree structure. The code is not short, but hopefully it is mostly clear. + +\typebuffer [option=TEX] + +Note that diagrams such as those constructed here will each be significantly +different, making the writing of a general mechanism rather complex. For example, +one might need to construct a tree branching up rather than down, or to the right +(or left), or even following an arbitrary path, such as a random walk. These can +all be achieved individually in \METAPOST\ without too much difficulty. + +\stopsubject + +\startsubject [title=A 3D projection] + +Although \METAPOST\ is a 2D drawing language, it can be easily extended to work +in 3D. Several attempts have been made in the past ranging from simple to +complicated. Here, we will take a simple approach. + +The \METAPOST\ language includes a triplet variable type, used to handle \type +{rgb} colors (it also has a quadruplet type used for \type {cmyk} colors). We +will use this \type {triplet} type to hold 3D coordinates. There is a separate +\CONTEXT\ module, entitled \type {three}, which creates a new \METAPOST\ instance +(also named \type {three}), which loads a set of macros that can be used to +manipulate these triplet coordinates. + +\usemodule [three] + +\startTEX +\usemodule [three] + +\startMPcode{three} + % code here +\stopMPcode +\stopTEX + +For our purposes here, only one function is really necessary: \type +{projection()} that maps a 3D coordinate to a 2D projection on the page. This +will not be a perspective projection having a viewpoint and a focus point, but +rather a very simple oblique projection, useful for, e.g., pseudo|-|3D schematic +drawings. The \type {Z} coordinate is taken to be \type {up} and the \type {Y} +coordinate taken to be \type {right}, both in the page of the paper. The third +coordinate \type {X} is an oblique projection in a right|-|hand coordinate +system. + +\page [yes] + +\startbuffer +\startMPcode{three} + save nodepath ; + path nodepath ; + nodepath = (projection Origin -- + projection (1,0,0) -- + projection (1,1,0) -- + projection (0,1,0) -- + projection (0,1,1) -- + projection (1,1,1) -- + projection (1,0,1) -- + projection (0,0,1) -- + cycle) scaled 5cm ; + + draw node(0,"\node{${\cal C}_{i\cal P}^{\mathrm{nt}}$}") ; + draw node(1,"\node{${\cal C}_{i\cal G}^{\mathrm{nt}}$}") ; + draw node(2,"\node{${\cal C}_{j\cal P}^{\mathrm{nt}}$}") ; + draw node(3,"\node{${\cal C}_{j\cal G}^{\mathrm{nt}}$}") ; + draw node(4,"\node{${\cal C}_{j\cal G}$}") ; + draw node(5,"\node{${\cal C}_{j\cal P}$}") ; + draw node(6,"\node{${\cal C}_{i\cal G}$}") ; + draw node(7,"\node{${\cal C}_{i\cal P}$}") ; + + interim crossingscale := 30 ; + drawdoublearrows fromto(0,0,1) ; + drawdoublearrows fromto(0,1,2) ; + drawdoublearrows fromto(0,2,3) ; + drawdoublearrows fromto(0,3,0) crossingunder fromto(0,2,5) ; + + drawdoublearrows fromto(0,7,6) ; + drawdoublearrows fromto(0,6,5) ; + drawdoublearrows fromto.ulft(0,5,4,"\node{$τ_j$~}") ; + drawdoublearrows fromto.top (0,7,4,"\node{$σ$}") ; + + drawdoublearrows fromto.lrt(0,0,7,"\node{$Ψ^{\mathrm{nt}}$}") + crossingunder fromto(0,6,5) ; + drawdoublearrows fromto(0,1,6) ; + drawdoublearrows fromto(0,2,5) ; + drawdoublearrows fromto(0,3,4) ; +\stopMPcode +\stopbuffer + +\startplacefigure [location=right, + reference=fig:cube] + \getbuffer +\stopplacefigure + +Intended for schematic drawings, there is no automatic hidden|-|line removal nor +effects like shading, and line crossings need to be handled manually (using \type +{crossingunder} introduced previously). In \in{Figure} [fig:cube] we draw a +simple cubical commutative diagram, with a node at each corner. + +\typebuffer [option=TEX] + +Note the use of \type {drawdoublearrows}, a new \METAFUN\ command that is +introduced here. + +\stopsubject + +\startsubject [title=Two final examples] + +\startbuffer[mp:tikz-cd] +\startMPcode + save nodepath ; save l ; l = 5ahlength ; + save X, Y, Z, XxY, T ; + pair X, Y, Z, XxY, T ; + XxY.i = 0 ; XxY = makenode(XxY.i,"\node{$X\times_Z Y$}") ; + X.i = 1 ; X = makenode(X.i, "\node{$X$}") ; + Z.i = 2 ; Z = makenode(Z.i, "\node{$Z$}") ; + Y.i = 3 ; Y = makenode(Y.i, "\node{$Y$}") ; + T.i = 4 ; T = makenode(T.i, "\node{$T$}") ; + XxY = origin ; + X = XxY + betweennodes.rt (nodepath,XxY.i,nodepath,X.i) + (l,0) ; + Z = X + betweennodes.bot(nodepath,X.i, nodepath,Z.i) + (0,-.8l); + Y = XxY + betweennodes.bot(nodepath,XxY.i,nodepath,Y.i) + (0,-.8l) ; + T = XxY + nodeboundingpoint.ulft(XxY.i) + + nodeboundingpoint.lft (T.i) + l*dir(135) ; + for i = XxY.i, X.i, Z.i, Y.i, T.i: + draw node(i) ; + endfor + drawarrow fromto.top(0, XxY.i,X.i, "\nodeSmall{$p$}") ; + drawarrow fromto.rt (0, X.i,Z.i, "\nodeSmall{$f$}") ; + drawarrow fromto.top(0, Y.i,Z.i, "\nodeSmall{$g$}") ; + drawarrow fromto.rt (0, XxY.i,Y.i, "\nodeSmall{$q$}") ; + drawarrow fromto.top( .13,T.i,X.i, "\nodeSmall{$x$}") ; + drawarrow fromto.urt(-.13,T.i,Y.i, "\nodeSmall{$y$}") ; + drawarrow fromto (0, T.i,XxY.i,"\nodeSmall{$(x,y)$}") + dashed withdots scaled .5 + withpen currentpen scaled 2 ; +\stopMPcode +\stopbuffer + +% Rather, let's do it similarly to TikZ. + +\startbuffer[mp:tikz-cd] +\startnodes [dx=2.5cm,dy=2cm,alternative=arrow] + \placenode [0, 0] {\node{$X\times_Z Y$}} + \placenode [1, 0] {\node{$X$}} + \placenode [1,-1] {\node{$Z$}} + \placenode [0,-1] {\node{$Y$}} + \placenode [-1,1] {\node{$T$}} + + \connectnodes [0,1] [position=top, label={\nodeSmall{$p$}}] + \connectnodes [1,2] [position=right, label={\nodeSmall{$f$}}] + \connectnodes [0,3] [position=right, label={\nodeSmall{$q$}}] + \connectnodes [3,2] [position=top, label={\nodeSmall{$g$}}] + \connectnodes [4,0] [option=dotted,rulethickness=1pt, + label={\nodeSmall{$(x,y)$}}] + \connectnodes [4,1] [offset=+.13,position=top, + label={\nodeSmall{$x$}}] + \connectnodes [4,3] [offset=-.13,position=topright, + label={\nodeSmall{$y$}}] +\stopnodes +\stopbuffer + +\startplacefigure [reference=fig:tikz-cd, + location={right,+3*hang}] + \getbuffer[mp:tikz-cd] +\stopplacefigure + +We end this manual with two examples of more advanced commutative diagrams. The +following example, shown in \in {Figure} [fig:tikz-cd], illustrates what in +category theory is called a \emph {pullback}. It is inspired from an example +given in the TikZ CD (commutative diagrams) package. + +The arrow labeled \quotation {$(x,y)$} is drawn \type {dashed withdots} and +illustrates how the line gets broken, implicitly \type {crossingunder} its +centered label. + +\typebuffer[mp:tikz-cd] [option=TEX] + +The previous diagram was drawn using the \CONTEXT\ interface. Our final example, +shown in \in {Figure} [fig:tikz-cd2], gives another \quotation {real|-|life} +example of a categorical pullback, also inspired by TikZ-CD, but this time drawn +through the \METAPOST\ interface and solving for positions. + +\startbuffer[mp:tikz-cd2] +\startMPcode + save nodepath ; save l ; l = 5ahlength ; + save A, B, C, D, E ; + pair A, B, C, D, E ; + A.i = 0 ; A = makenode(A.i,"\node{$\pi_1(U_1\cap U_2)$}") ; + B.i = 1 ; B = makenode(B.i, + "\node{$\pi_1(U_1)\ast_{\pi_1(U_1\cap U_2)}\pi_1(U_2)$}") ; + C.i = 2 ; C = makenode(C.i,"\node{$\pi_1(X)$}") ; + D.i = 3 ; D = makenode(D.i,"\node{$\pi_1(U_2)$}") ; + E.i = 4 ; E = makenode(E.i,"\node{$\pi_1(U_1)$}") ; + A = origin ; + B = A + betweennodes.rt(nodepath,A.i,nodepath,B.i) + ( l,0) ; + C = B + betweennodes.rt(nodepath,B.i,nodepath,C.i) + (.7l,0) ; + D = .5[A,B] + (0,-.9l) ; + E = .5[A,B] + (0, .9l) ; + + for i = A.i, B.i, C.i, D.i, E.i : + draw node(i) ; + endfor + drawarrow fromto.llft( 0,A.i,D.i,"\smallnode{$i_2$}") ; + drawarrow fromto.ulft( 0,A.i,E.i,"\smallnode{$i_1$}") ; + drawarrow fromto ( 0,D.i,B.i) ; + drawarrow fromto ( 0,E.i,B.i) ; + drawarrow fromto.urt( .1,E.i,C.i,"\smallnode{$j_1$}") ; + drawarrow fromto.lrt(-.1,D.i,C.i,"\smallnode{$j_2$}") ; + drawarrow fromto.top( 0,B.i,C.i) dashed evenly ; + draw textext.top("{\tfxx\strut$\simeq$}") + shifted point .4 of fromto(0,B.i,C.i) ; +\stopMPcode +\stopbuffer + +\startplacefigure [location=here,reference=fig:tikz-cd2] + \getbuffer[mp:tikz-cd2] +\stopplacefigure + +\typebuffer[mp:tikz-cd2] [option=TEX] + +\stopsubject + +\startsubject [title=Conclusions] + +There was initial consensus at the 2017 \CONTEXT\ Meeting in Maibach, Germany, +where a version of this package was presented, that there was little use of +developing a purely \CONTEXT\ interface. Rather, the \METAPOST\ package should be +sufficiently accessible. Since then, however, we decided that the development of +a derivative \CONTEXT\ interface implementing some basic functionality could +indeed be useful for many users, although it will necessarily remain somewhat +limited. Users are recommended to turn to the pure \METAPOST\ interface when more +sophisticated functionality is needed. + +\stopsubject + +\startsubject [title=Acknowledgements] + +This module was inspired by a request made by Idris Samawi Hamid to draw a +natural transformation diagram (\in{Figure} [fig:natural]). The \METAPOST\ macros +that were developed then benefited from improvements suggested by Hans Hagen as +well as inspiration provided by Taco Hoekwater. + +The cover artwork one can recognize as coming under the hand of Hans Hagen that +he produced when I mentioned that I wanted to do something along these lines. It +fits very well into the style of manual covers that we distribute with \CONTEXT. +This manual therefore has been co|-|written by Hans and Alan. + +\stopsubject + +\startsubject [title=References] + + \placelistofpublications + +\stopsubject + +\stoptitle + +\stoptext |