%D \module %D [ file=mp-node.mpiv, %D version=1998.02.15, %D title=\CONTEXT\ \METAPOST\ graphics, %D subtitle=Node Based Graphics, %D author=Alan Braslau, %D date=\currentdate, %D copyright={Alan Braslau & \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. %D Ths crossing macros were written as part of this module but as they %D can be of use elsewhere they are defined in mp-tool. if known context_node : endinput ; fi ; boolean context_node ; context_node := true ; % returns a pair suffix if the path is unknown vardef makenode@#(suffix p)(text t) = save i, b ; numeric i ; string b ; for a = t : if unknown i : % first argument is the index i = a ; if isarray p : % % note that one needs to declare "path p[] ; picture p[]pic[] ;" % before calling node() if one is to use a pseudo-array for p % because "picture p1.pic[] ;" is not a valid syntax! % % The following works, but is a bit awkward... % b := prefix p ; if not picture p.pic[i] : scantokens("picture " & b & "[]pic[] ;") ; fi if not pair p.pos[i] : scantokens("pair " & b & "[]pos[] ;") ; fi else : if not picture p.pic[i] : picture p.pic[] ; fi if not pair p.pos[i] : pair p.pos[] ; fi fi else : if known p.pic[i] : addto p.pic[i] also else : p.pic[i] := fi if picture a : a elseif string a : textext@#(a) elseif numeric a : textext@#(decimal a) elseif ((boolean a) and a) : image(draw origin) else : nullpicture fi ; fi endfor p.pos[i] if known p : := point i of p ; fi enddef ; % returns a picture vardef node@#(suffix p)(text t) = if pair makenode@#(p)(t) : % nop: gobble the function return. fi for a = t : if (unknown p) and (known p.pos[a]) : makenodepath(p) ; fi if known p.pic[a] : p.pic[a] if known p : shifted point a of p fi else : nullpicture fi exitif true ; endfor enddef ; % returns a path vardef fromto@#(expr d)(suffix p)(expr f)(suffix q)(text s) = save r, t, l ; path r[] ; numeric t ; picture l ; for a = s : if unknown t : t = a ; if (unknown p) and (known p.pos[f]) : makenodepath(p) ; fi if (unknown q) and (known q.pos[t]) : makenodepath(q) ; fi r0 = if ((not numeric d) and (point f of p = point f of q) and (point t of p = point t of q)) : subpath (f,t) of p else : point f of p -- point t of q fi ; save deviation ; numeric deviation ; deviation := if numeric d: d else: 0 fi ; r1 = if deviation=0 : r0 else : point 0 of r0 .. unitvector direction .5length r0 of r0 rotated 90 scaled deviation * arclength r0 shifted point .5length r0 of r0 .. point length r0 of r0 fi ; else : if known l : addto l also else : l := fi if picture a : a elseif string a : textext@#(a) elseif numeric a : textext@#(decimal a) elseif ((boolean a) and a) : image(draw origin withpen currentpen scaled 4) else : nullpicture fi ; fi endfor r2 = r1 if known p.pic[f if cycle p: mod length p fi] : cutbefore boundingbox (p.pic[f if cycle p: mod length p fi] shifted point f of p) fi if known q.pic[t if cycle q: mod length q fi] : cutafter boundingbox (q.pic[t if cycle q: mod length q fi] shifted point t of q) fi ; if known l : l := l shifted point .5length r2 of r2 ; draw l ; (r2 if str @# = "" : crossingunder l fi) else : r2 fi enddef ; % returns pair: bounding point of the node picture vardef nodeboundingpoint@#(suffix p)(expr i) = if known p.pic[i] : boundingpoint@#(p.pic[i]) else : origin fi enddef ; % returns pair: scaled laboff direction vardef relative@#(expr s) = (mfun_laboff@# scaled s) enddef ; % returns pair: vector between nodes (+ optional scale) vardef betweennodes@#(suffix p)(expr f)(suffix q)(text s) = save t ; numeric t ; for a = s : if unknown t : t = a ; nodeboundingpoint@#(q,t) + nodeboundingpoint@#(p,f) else : + relative@#(a) fi endfor enddef ; % build a path from the node positions. % Must be continuous in index starting at 0. vardef makenodepath(suffix p) = if unknown p : save i ; i = -1 ; p = forever : exitif unknown p.pos[incr i] ; p.pos[i] -- endfor cycle ; fi enddef ;