1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16if known metafun_loaded_xbox : endinput ; fi ;
17
18boolean metafun_loaded_xbox ; metafun_loaded_xbox := true ;
19
20
21
22
23
24vardef boxes_str_prefix (expr s) (text cond) =
25 save i_, c; string c; i_ = 0;
26 forever:
27 c := substring (i_, i_ 1) of s;
28 exitunless cond;
29 exitif incr i_ = length s;
30 endfor
31 i_
32enddef;
33
34
35
36
37vardef generisize (expr ss) =
38 save r, s, l; string r, s;
39 r = "";
40 s = ss;
41 forever:
42 exitif s = "";
43 l := boxes_str_prefix(s, (c<>"[") and ((c<"0") or (c>"9")));
44 r := r & substring (0,l) of s;
45 s := substring (l, infinity) of s;
46 if s <> "" :
47 if (s >= "[") and (length s > 1) :
48 if (substring (1,2) of s) = "[" :
49 l := 2;
50 r := r & "[[";
51 else :
52 l := 1 boxes_str_prefix(s, c <> "]");
53 r := r & "[]";
54 fi
55 else :
56 r := r & "[]";
57 l := boxes_str_prefix(s, (c = ".") or ("0" <= c) and (c <= "9"));
58 fi
59 s := substring(l, infinity) of s;
60 fi
61 endfor
62 r
63enddef;
64
65
66
67string boxes_n, boxes_n_cur, boxes_n_gen; boxes_n_cur := "]";
68
69vardef boxes_set_n_gen =
70 if boxes_n <> boxes_n_cur:
71 boxes_n_cur := boxes_n;
72 boxes_n_gen := generisize(boxes_n);
73 fi
74enddef;
75
76
77
78
79
80
81
82vardef boxes_declare(text t) text vars =
83 boxes_set_n_gen;
84 forsuffixes v_ = vars :
85 if forsuffixes _n = scantokens boxes_n : not t v_ endfor :
86 def boxes_gdmac text _n = t v_ enddef;
87 expandafter boxes_gdmac scantokens boxes_n_gen;
88 fi
89 endfor
90enddef;
91
92
93
94
95vardef boxes_redeclare(text t) text vars =
96 boxes_set_n_gen;
97 def boxes_gdmac text _n = t vars enddef;
98 expandafter boxes_gdmac scantokens boxes_n_gen;
99enddef;
100
101
102
103
104
105
106def boxes_begin (expr pp, sp) (suffix $) (text t) =
107 boxes_n := str $;
108 boxes_declare (pair) _n.off, _n.c;
109 boxes_declare (string) boxes_pproc._n, boxes_sproc._n;
110 boxes_declare (picture) boxes_pic._n;
111 boxes_pproc$ := pp;
112 boxes_sproc$ := sp;
113 boxes_pic$ := nullpicture;
114 for _p_ = t :
115
116 boxes_pic$ := if picture _p_: _p_ else: textext(_p_) fi;
117 endfor
118 $c = $off .5[llcorner boxes_pic$, urcorner boxes_pic$]
119enddef;
120
121
122
123
124def boxes_end(suffix cl, $) =
125 if known boxes_pic.boxes_prevbox:
126 boxes_dojoin(boxes_prevbox,$);
127 fi
128 def boxes_prevbox = $ enddef;
129 expandafter def expandafter boxes_clear_all expandafter =
130 boxes_clear_all cl($);
131 enddef
132enddef;
133
134
135
136def boxes_boxjoin(text t) =
137 def boxes_prevbox = _ enddef;
138 def boxes_dojoin(suffix a,b) = t enddef;
139enddef ;
140
141def boxes_clear_all = enddef;
142
143
144
145
146vardef boxes_fixsize(text t) =
147 forsuffixes $ = t : scantokens boxes_sproc$($); endfor
148enddef;
149
150
151
152vardef boxes_fixpos(text t) =
153 forsuffixes $=t:
154 if unknown xpart $.off : xpart $.off = 0; fi
155 if unknown ypart $.off : ypart $.off = 0; fi
156 endfor
157enddef;
158
159
160
161vardef bpath suffix $ =
162 boxes_fixsize($);
163 boxes_fixpos($);
164 scantokens boxes_pproc$($)
165enddef;
166
167
168
169
170vardef boxes_pic_mac suffix $ =
171 boxes_fixsize($);
172 boxes_fixpos($);
173 boxes_pic$ shifted $off
174enddef;
175
176vardef pic suffix $ = boxes_pic_mac $ enddef;
177
178
179
180def drawboxed(text t) =
181 boxes_fixsize(t);
182 boxes_fixpos(t);
183 forsuffixes s = t: draw boxes_pic_mac.s; draw bpath.s; endfor
184enddef;
185
186
187
188def drawunboxed(text t) =
189 boxes_fixsize(t);
190 boxes_fixpos(t);
191 forsuffixes s = t :
192 draw boxes_pic_mac.s;
193 endfor
194enddef;
195
196
197
198def drawboxes(text t) =
199 forsuffixes s = t :
200 draw bpath.s;
201 endfor
202enddef;
203
204
205
206newinternal defaultdx, defaultdy; defaultdx := defaultdy := 3bp;
207
208vardef boxit@#(text tt) =
209 boxes_begin("boxes_path","boxes_size",@#,tt);
210 boxes_declare (pair) _n.sw, _n.s, _n.se, _n.e, _n.ne, _n.n, _n.nw, _n.w;
211 0 = xpart(@#nw @#sw) = ypart(@#se @#sw);
212 0 = xpart(@#ne @#se) = ypart(@#ne @#nw);
213 @#w = .5[@#nw,@#sw];
214 @#s = .5[@#sw,@#se];
215 @#e = .5[@#ne,@#se];
216 @#n = .5[@#ne,@#nw];
217 @#ne @#c = @#c @#sw = (@#dx,@#dy) .5(urcorner boxes_pic@# llcorner boxes_pic@#);
218 boxes_end(boxes_clear,@#);
219enddef;
220
221def boxes_path(suffix $) =
222 $.sw -- $.se -- $.ne -- $.nw -- cycle
223enddef;
224
225def boxes_size(suffix $) =
226 if unknown $.dx : $.dx = defaultdx; fi
227 if unknown $.dy : $.dy = defaultdy; fi
228enddef;
229
230vardef boxes_clear(suffix $) =
231 boxes_n := str $;
232 boxes_redeclare(numeric) _n.sw, _n.s, _n.se, _n.e, _n.ne, _n.n, _n.nw, _n.w, _n.c, _n.off, _n.dx, _n.dy;
233enddef;
234
235
236
237newinternal circmargin; circmargin := 2bp;
238
239vardef circleit@#(text tt) =
240 boxes_begin("boxes_the_circle","boxes_size_circle",@#,tt);
241 boxes_generic_declare(pair) _n.n, _n.s, _n.e, _n.w;
242 @#e @#c = @#c @#w = (@#dx,0) .5(lrcorner boxes_pic@# llcorner boxes_pic@#);
243 @#n @#c = @#c @#s = (0,@#dy) .5(ulcorner boxes_pic@# llcorner boxes_pic@#);
244 boxes_end(boxes_clear_circle,@#);
245enddef;
246
247def boxes_the_circle (suffix $) =
248 $.e{up} ... $.n{left} ... $.w{down} ... $.s{right} ... cycle
249enddef;
250
251vardef boxes_clear_circle (suffix $) =
252 boxes_n := str $;
253 boxes_redeclare(numeric) _n.n, _n.s, _n.e, _n.w, _n.c, _n.off, _n.dx, _n.dy;
254enddef;
255
256vardef boxes_size_circle (suffix $) =
257 save a_, b_;
258 (a_,b_) = .5(urcorner boxes_pic$ llcorner boxes_pic$);
259 if unknown $dx :
260 if unknown $dy :
261 if unknown($dy$dx) :
262 a_ $dx = b_ $dy;
263 fi
264 if a_ $dx = b_ $dy :
265 a_ $dx = a_ b_ circmargin;
266 else :
267 $dx = boxes_select(max(a_,b_ $dx $dy), (a_ d_,0){up} ... (0,b_ d_ $dy $dx){left});
268 fi
269 else :
270 $dx = boxes_select(a_, (a_ d_,0){up}...(0,b_ $dy){left});
271 fi
272 elseif unknown $dy :
273 $dy = boxes_select(b_, (a_ $dx,0){up}...(0,b_ d_){left});
274 fi
275enddef;
276
277vardef boxes_select(expr dhi)(text tt) =
278 save f_, p_; path p_;
279 p_ = origin .. (a_,b_) circmargin unitvector(a_,b_);
280 vardef f_ (expr d_) =
281 xpart((tt) intersectiontimes p_) >= 0
282 enddef;
283 solve f_(0, dhi 1.5circmargin)
284enddef;
285
286def boxes_init_all =
287 boxes_boxjoin();
288 save boxes_pic, boxes_sproc, boxes_pproc;
289 def boxes_clear_all = enddef;
290enddef ;
291
292def boxjoin(text t) =
293 def boxes_prevbox = _ enddef;
294 def boxes_dojoin(suffix a,b) = t enddef;
295enddef;
296
297extra_beginfig := extra_beginfig & "boxes_init_all;";
298extra_endfig := "boxes_clear_all;" & extra_endfig;
299
300if makingfigure :
301 boxes_init_all;
302fi ;
303
304
305
306newinternal rbox_radius ; rbox_radius := 8bp ;
307
308vardef rboxit@#(text tt) =
309 boxes_begin("boxes_the_rounded","boxes_size",@#,tt) ;
310 boxes_generic_declare (pair) _n.sw, _n.s, _n.se, _n.e, _n.ne, _n.n, _n.nw, _n.w ;
311 0 = xpart(@#nw @#sw) = ypart(@#se @#sw) ;
312 0 = xpart(@#ne @#se) = ypart(@#ne @#nw) ;
313 @#w = .5[@#nw,@#sw] ;
314 @#s = .5[@#sw,@#se] ;
315 @#e = .5[@#ne,@#se] ;
316 @#n = .5[@#ne,@#nw] ;
317 @#ne @#c = @#c @#sw = (@#dx,@#dy) .5(urcorner boxes_pic@# llcorner boxes_pic@#) ;
318 boxes_end(boxes_clear,@#) ;
319enddef;
320
321def boxes_the_rounded(suffix $) =
322 save _r ; _r = min(rbox_radius, .5ypart($.n$.s), .5xpart($.e$.w));
323 $.sw (_r,0) {right} .. {right} $.se (_r,0) ..
324 $.se (0,_r) {up} .. {up} $.ne (0,_r) ..
325 $.ne (_r,0) {left} .. {left} $.nw (_r,0) ..
326 $.nw (0,_r) {down} .. {down} $.sw (0,_r) ..
327 cycle
328enddef;
329
330 |