mp-luas.mpxl /size: 21 Kb    last modification: 2023-12-21 09:43
1%D \module
2%D   [       file=mp-luas.mpiv,
3%D        version=2014.04.14,
4%D          title=\CONTEXT\ \METAPOST\ graphics,
5%D       subtitle=\LUA,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14if known metafun_loaded_luas : endinput ; fi ;
15
16% When I prototyped the runscript primitive I was just thinking of a usage like
17% the original \directlua primitive in luatex: genererate something and pipe
18% that back to metapost, and have access to some internals. Instead of compiling
19% the code a the metapost end here we delegate that to the lua end. Only strings
20% get passed. Of course in the end the real usage got a bit beyong the intended
21% usage. So, in addition to some definitions here there are and will be use in
22% other metafun modules too. Of course in retrospect I should have done this five
23% years earlier.
24
25newinternal boolean metafun_loaded_luas ; metafun_loaded_luas := true ; immutable metafun_loaded_luas ;
26
27def newscriptindex suffix t = newinternal t ; immutable t ; enddef ;
28
29newscriptindex mfid_scriptindex ; mfid_scriptindex := runscript("mp.mf_script_index('scriptindex')") ;
30
31def scriptindex = runscript mfid_scriptindex enddef ;
32
33string mfun_lua_bs ; mfun_lua_bs := "[===[" ;
34string mfun_lua_es ; mfun_lua_es := "]===]" ;
35
36vardef mlib_luas_luacall(text t) =
37    runscript("" for s = t :
38        if string s :
39            & s
40          % & mfun_lua_bs & s & mfun_lua_es
41        elseif numeric s :
42            & decimal s
43        elseif boolean s :
44            & if s : "true" else : "false" fi
45        elseif pair s :
46            & mfun_pair_to_table(s)
47        elseif path s :
48            & mfun_path_to_table(s)
49        elseif rgbcolor s :
50            & mfun_rgb_to_table(s)
51        elseif cmykcolor s :
52            & mfun_cmyk_to_table(s)
53        else :
54            & ditto & tostring(s) & ditto
55        fi endfor
56    )
57enddef ;
58
59newinternal mfun_luas_b ;
60
61def mlib_luas_luadone =
62    exitif numeric begingroup mfun_luas_b := 1 ; endgroup ;
63enddef ;
64
65vardef mlib_luas_lualist(expr c)(text t) = % we could use mlib_luas_s instead of c
66    interim mfun_luas_b := 0 ;
67    runscript(c & for s = t :
68        if mfun_luas_b = 0 :
69            "("
70          % hide(mfun_luas_b := 1)
71            mlib_luas_luadone
72        else :
73            ","
74        fi
75        &
76        if string s :
77            mfun_lua_bs & s & mfun_lua_es
78        elseif numeric s :
79            decimal s
80        elseif boolean s :
81            if s : "true" else : "false" fi
82        elseif pair s :
83            mfun_pair_to_table(s)
84        elseif path s :
85            mfun_path_to_table(s)
86        elseif rgbcolor s :
87            mfun_rgb_to_table(s)
88        elseif cmykcolor s :
89            mfun_cmyk_to_table(s)
90        else :
91            ditto & tostring(s) & ditto
92        fi & endfor if mfun_luas_b = 0 : "()" else : ")" fi
93    )
94enddef ;
95
96def luacall = mlib_luas_luacall enddef ; % why no let
97
98vardef lualist@#(text t) = mlib_luas_lualist(str @#)(t) enddef ;
99
100string mlib_luas_s ; % saves save/restore
101
102vardef lua@#(text t) =
103    mlib_luas_s := str @# ;
104    if length(mlib_luas_s) > 0 :
105        mlib_luas_lualist(mlib_luas_s,t)
106    else :
107        mlib_luas_luacall(t)
108    fi
109enddef ;
110
111vardef MP@#(text t) =
112    mlib_luas_lualist("MP." & str @#,t)
113enddef ;
114
115% todo: runner
116
117newscriptindex mfun_message ; mfun_message := scriptindex("message") ;
118
119def message text t =
120    runscript mfun_message tostring(t) ; % todo: scananything
121enddef ;
122
123permanent newscriptindex, scriptindex, luacall, lua, lualist, mp, MP  ;
124
125% Color:
126
127% We do a low level runscript:
128%
129% lua.mp.namedcolor(s)       % conflicts with macro namedcolor
130% lua.mp.mf_named_color(s)   % okay but, can also be
131% lua.mp("mf_named_color",s) % which gives expansion mess
132
133newscriptindex mfid_resolvedcolor ; mfid_resolvedcolor := scriptindex "namedcolor" ;
134
135def resolvedcolor = runscript mfid_resolvedcolor enddef ;
136
137permanent resolvedcolor ;
138
139% Modes:
140
141newscriptindex mfid_mode       ; mfid_mode       := scriptindex "mode" ;
142newscriptindex mfid_systemmode ; mfid_systemmode := scriptindex "systemmode" ;
143
144vardef texmode    (expr s) = runscript mfid_mode       s enddef ;
145vardef systemmode (expr s) = runscript mfid_systemmode s enddef ;
146
147% let processingmode = systemmode ;
148
149permanent texmode, systemmode ;
150
151% A few helpers
152
153newscriptindex mfid_isarray   ; mfid_isarray   := scriptindex "isarray"   ;
154newscriptindex mfid_prefix    ; mfid_prefix    := scriptindex "prefix"    ;
155newscriptindex mfid_dimension ; mfid_dimension := scriptindex "dimension" ;
156newscriptindex mfid_isobject  ; mfid_isobject  := scriptindex "isobject"  ;
157
158vardef isarray   suffix a = runscript mfid_isarray  (str a) enddef ;
159vardef prefix    suffix a = runscript mfid_prefix   (str a) enddef ;
160vardef dimension suffix a = runscript mfid_dimension(str a) enddef ;
161
162vardef isobject  expr p = if picture p : runscript mfid_isobject prescriptpart p else : false fi enddef ;
163
164permanent isarray, prefix, dimension, isobject ;
165
166% More access
167
168newscriptindex mfid_getmacro ; mfid_getmacro := scriptindex "getmacro" ; def getmacro = runscript mfid_getmacro enddef ;
169newscriptindex mfid_getdimen ; mfid_getdimen := scriptindex "getdimen" ; def getdimen = runscript mfid_getdimen enddef ;
170newscriptindex mfid_getcount ; mfid_getcount := scriptindex "getcount" ; def getcount = runscript mfid_getcount enddef ;
171newscriptindex mfid_gettoks  ; mfid_gettoks  := scriptindex "gettoks"  ; def gettoks  = runscript mfid_gettoks  enddef ;
172
173% todo: figure out a mixed interface: setdimen "foo" 123pt ; setdimen("foo", 123pt) ;
174
175newscriptindex mfid_setmacro ; mfid_setmacro := scriptindex "setmacro" ; def setmacro(expr k, v) = runscript mfid_setmacro k v ; enddef ;
176newscriptindex mfid_setdimen ; mfid_setdimen := scriptindex "setdimen" ; def setdimen(expr k, v) = runscript mfid_setdimen k v ; enddef ;
177newscriptindex mfid_setcount ; mfid_setcount := scriptindex "setcount" ; def setcount(expr k, v) = runscript mfid_setcount k v ; enddef ;
178newscriptindex mfid_settoks  ; mfid_settoks  := scriptindex "settoks"  ; def settoks (expr k, v) = runscript mfid_settoks  k v ; enddef ;
179
180newscriptindex mfid_setglobalmacro ; mfid_setglobalmacro := scriptindex "setglobalmacro" ; def setglobalmacro(expr k, v) = runscript mfid_setglobalmacro k v ; enddef ;
181newscriptindex mfid_setglobaldimen ; mfid_setglobaldimen := scriptindex "setglobaldimen" ; def setglobaldimen(expr k, v) = runscript mfid_setglobaldimen k v ; enddef ;
182newscriptindex mfid_setglobalcount ; mfid_setglobalcount := scriptindex "setglobalcount" ; def setglobalcount(expr k, v) = runscript mfid_setglobalcount k v ; enddef ;
183newscriptindex mfid_setglobaltoks  ; mfid_setglobaltoks  := scriptindex "setglobaltoks"  ; def setglobaltoks (expr k, v) = runscript mfid_setglobaltoks  k v ; enddef ;
184
185permanent
186    getmacro, getdimen, getcount, gettoks,
187    setmacro, setdimen, setcount, settoks,
188    setglobalmacro, setglobaldimen, setglobalcount, setglobaltoks ;
189
190newscriptindex mfid_positionpath        ; mfid_positionpath        := scriptindex("positionpath") ;
191newscriptindex mfid_positioncurve       ; mfid_positioncurve       := scriptindex("positioncurve") ;
192newscriptindex mfid_positionxy          ; mfid_positionxy          := scriptindex("positionxy") ;
193newscriptindex mfid_positionx           ; mfid_positionx           := scriptindex("positionx") ;
194newscriptindex mfid_positiony           ; mfid_positiony           := scriptindex("positiony") ;
195newscriptindex mfid_positionposition    ; mfid_positionparagraph   := scriptindex("positionparagraph") ;
196newscriptindex mfid_positionwhd         ; mfid_positionwhd         := scriptindex("positionwhd") ;
197newscriptindex mfid_positionpage        ; mfid_positionpage        := scriptindex("positionpage") ;
198newscriptindex mfid_positioncolumn      ; mfid_positioncolumn      := scriptindex("positioncolumn") ;
199newscriptindex mfid_positionregion      ; mfid_positionregion      := scriptindex("positionregion") ;
200newscriptindex mfid_positionbox         ; mfid_positionbox         := scriptindex("positionbox") ;
201newscriptindex mfid_positionanchor      ; mfid_positionanchor      := scriptindex("positionanchor") ;
202newscriptindex mfid_positioncolumnfromx ; mfid_positioncolumnfromx := scriptindex("positioncolumnfromx") ;
203newscriptindex mfid_positioncolumnbox   ; mfid_positioncolumnbox   := scriptindex("positioncolumnbox") ;
204newscriptindex mfid_overlaycolumnbox    ; mfid_overlaycolumnbox    := scriptindex("overlaycolumnbox") ;
205
206vardef positionpath     (expr name)   = runscript mfid_positionpath     (name)   enddef ;
207vardef positioncurve    (expr name)   = runscript mfid_positioncurve    (name)   enddef ;
208vardef positionxy       (expr name)   = runscript mfid_positionxy       (name)   enddef ;
209vardef positionx        (expr name)   = runscript mfid_positionx        (name)   enddef ;
210vardef positiony        (expr name)   = runscript mfid_positiony        (name)   enddef ;
211vardef positionwhd      (expr name)   = runscript mfid_positionwhd      (name)   enddef ;
212vardef positionpage     (expr name)   = runscript mfid_positionpage     (name)   enddef ;
213vardef positioncolumn   (expr name)   = runscript mfid_positioncolumn   (name)   enddef ;
214vardef positionparagraph(expr name)   = runscript mfid_positionparagraph(name)   enddef ;
215vardef positionpar      (expr name)   = runscript mfid_positionparagraph(name)   enddef ;
216vardef positionregion   (expr name)   = runscript mfid_positionregion   (name)   enddef ;
217vardef positionbox      (expr name)   = runscript mfid_positionbox      (name)   enddef ;
218vardef positionanchor                 = runscript mfid_positionanchor            enddef ;
219vardef positioncolumnatx(expr name)   = runscript mfid_positioncolumnatx(name)   enddef ;
220vardef positioncolumnbox(expr column) = runscript mfid_positioncolumnbox(column) enddef ;
221vardef overlaycolumnbox (expr column) = runscript mfid_overlaycolumnbox (column) enddef ;
222
223vardef positioninregion =
224    currentpicture := currentpicture shifted - positionxy(positionanchor) ;
225enddef ;
226
227vardef positionatanchor(expr name) =
228    currentpicture := currentpicture shifted - positionxy(name) ;
229enddef ;
230
231permanent positionpath, positioncurve, positionxy, positionwhd,
232    positionpage, positionregion, positioncolumn, positionparagraph,
233    positionbox, positionanchor, positioninregion, positionatanchor,
234    positioncolumnatx, positioncolumnbox, overlaycolumnbox ;
235
236let wdpart = redpart ;
237let htpart = greenpart ;
238let dppart = bluepart ;
239
240permanent wdpart, htpart, dppart;
241
242newscriptindex mfid_sortedpath ; mfid_sortedpath := scriptindex "sortedpath" ;
243newscriptindex mfid_uniquepath ; mfid_uniquepath := scriptindex "uniquepath" ;
244
245def sortedpath = runscript mfid_sortedpath enddef ;
246def uniquepath = runscript mfid_uniquepath enddef ;
247
248permanent sortpath, uniquepath ;
249
250newscriptindex mfid_texvar ; mfid_texvar := scriptindex "texvar" ; vardef texvar(expr s) = runscript mfid_texvar s enddef ;
251newscriptindex mfid_texstr ; mfid_texstr := scriptindex "texstr" ; vardef texstr(expr s) = runscript mfid_texstr s enddef ;
252
253newscriptindex mfid_path_lengthof ; mfid_path_lengthof := scriptindex "pathlengthof" ;
254newscriptindex mfid_path_pointof  ; mfid_path_pointof  := scriptindex "pathpointof" ;
255newscriptindex mfid_path_leftof   ; mfid_path_leftof   := scriptindex "pathleftof" ;
256newscriptindex mfid_path_rightof  ; mfid_path_rightof  := scriptindex "pathrightof" ;
257newscriptindex mfid_path_reset    ; mfid_path_reset    := scriptindex "pathreset" ;
258
259% 25 pct gain
260
261   def inpath            = = 1 step 1 until runscript mfid_path_lengthof   enddef ;
262vardef pointof primary i =                  runscript mfid_path_pointof  i enddef ;
263vardef leftof  primary i =                  runscript mfid_path_leftof   i enddef ;
264vardef rightof primary i =                  runscript mfid_path_rightof  i enddef ;
265
266permanent inpath, pointof, leftof, rightof ;
267
268% another 10 pct gain
269
270% def inpath   = = 1 step 1 until runscript mfid_path_lengthof enddef ;
271% def pointof  =                  runscript mfid_path_pointof  enddef ;
272% def leftof   =                  runscript mfid_path_leftof   enddef ;
273% def rightof  =                  runscript mfid_path_rightof  enddef ;
274
275extra_endfig := extra_endfig & " runscript mfid_path_reset ; " ;
276
277newscriptindex mfid_utfnum ; mfid_utfnum := scriptindex "utfnum" ;
278newscriptindex mfid_utflen ; mfid_utflen := scriptindex "utflen" ;
279newscriptindex mfid_utfsub ; mfid_utfsub := scriptindex "utfsub" ;
280
281% def utfnum = runscript mfid_utfnum enddef ;
282% def utflen = runscript mfid_utflen enddef ;
283% def utfsub = runscript mfid_utfsub enddef ;
284
285vardef utfnum(expr s) = runscript mfid_utfnum s enddef ; % str
286vardef utflen(expr s) = runscript mfid_utflen s enddef ; % str
287vardef utfsub(text t) = runscript mfid_utfsub t enddef ; % str, first, (optional) last
288
289permanent utfnum, utflen, utfsub ;
290
291newscriptindex mfid_getparameters        ; mfid_getparameters        := scriptindex "getparameters" ;
292newscriptindex mfid_presetparameters     ; mfid_presetparameters     := scriptindex "presetparameters" ;
293newscriptindex mfid_hasparameter         ; mfid_hasparameter         := scriptindex "hasparameter" ;
294newscriptindex mfid_hasoption            ; mfid_hasoption            := scriptindex "hasoption" ;
295newscriptindex mfid_getparameter         ; mfid_getparameter         := scriptindex "getparameter" ;
296newscriptindex mfid_getparameterdefault  ; mfid_getparameterdefault  := scriptindex "getparameterdefault" ;
297newscriptindex mfid_getparametercount    ; mfid_getparametercount    := scriptindex "getparametercount" ;
298newscriptindex mfid_getmaxparametercount ; mfid_getmaxparametercount := scriptindex "getmaxparametercount" ;
299newscriptindex mfid_getparameterpath     ; mfid_getparameterpath     := scriptindex "getparameterpath" ;
300newscriptindex mfid_getparameterpen      ; mfid_getparameterpen      := scriptindex "getparameterpen" ;
301newscriptindex mfid_getparametertext     ; mfid_getparametertext     := scriptindex "getparametertext" ;
302%              mfid_getparameteroption   ; mfid_getparameteroption   := scriptindex "getparameteroption" ;
303newscriptindex mfid_applyparameters      ; mfid_applyparameters      := scriptindex "applyparameters" ;
304newscriptindex mfid_mergeparameters      ; mfid_mergeparameters      := scriptindex "mergeparameters" ;
305newscriptindex mfid_pushparameters       ; mfid_pushparameters       := scriptindex "pushparameters" ;
306newscriptindex mfid_popparameters        ; mfid_popparameters        := scriptindex "popparameters" ;
307newscriptindex mfid_setluaparameter      ; mfid_setluaparameter      := scriptindex "setluaparameter" ;
308
309def getparameters        = runscript mfid_getparameters        enddef ;
310def presetparameters     = runscript mfid_presetparameters     enddef ;
311def hasparameter         = runscript mfid_hasparameter         enddef ;
312def hasoption            = runscript mfid_hasoption            enddef ;
313def getparameter         = runscript mfid_getparameter         enddef ;
314def getparameterdefault  = runscript mfid_getparameterdefault  enddef ;
315def getparametercount    = runscript mfid_getparametercount    enddef ;
316def getmaxparametercount = runscript mfid_getmaxparametercount enddef ;
317def getparameterpath     = runscript mfid_getparameterpath     enddef ;
318def getparameterpen      = runscript mfid_getparameterpen      enddef ;
319def getparametertext     = runscript mfid_getparametertext     enddef ;
320%   getparameteroption   = runscript mfid_getparameteroption   enddef ;
321def applyparameters      = runscript mfid_applyparameters      enddef ;
322def mergeparameters      = runscript mfid_mergeparameters      enddef ;
323def pushparameters       = runscript mfid_pushparameters       enddef ;
324def popparameters        = runscript mfid_popparameters        enddef ;
325def setluaparameter      = runscript mfid_setluaparameter      enddef ;
326
327permanent getparameters, presetparameters, hasparameter, hasoption, getparameter, getparameterdefault,
328    getparametercount, getmaxparametercount, getparameterpath, getparameterpen, getparametertext, % getparameteroption,
329    applyparameters, mergeparameters, pushparameters, popparameters, setluaparameter ;
330
331newscriptindex mfun_newrecord ; mfun_newrecord := scriptindex "newrecord" ;
332newscriptindex mfun_setrecord ; mfun_setrecord := scriptindex "setrecord" ;
333newscriptindex mfun_getrecord ; mfun_getrecord := scriptindex "getrecord" ;
334newscriptindex mfun_cntrecord ; mfun_cntrecord := scriptindex "cntrecord" ;
335
336% let record = runscript ; % We need to use "let" because we don't expand!
337
338def record    = newinternal numeric runscript enddef ;
339
340def newrecord = runscript mfun_newrecord ; enddef ; % semicolon prevents lookahead
341def setrecord = runscript mfun_setrecord ; enddef ;
342def getrecord = runscript mfun_getrecord   enddef ;
343def cntrecord = runscript mfun_cntrecord   enddef ;
344
345permanent
346    record, newrecord, setrecord, getrecord, cntrecord ;
347
348% No vardef's because we need to scan for an assignment too and we'll see
349% an endgroup otherwise.
350
351newscriptindex mfid_year   ; mfid_year   := scriptindex "year"   ; def year   = runscript mfid_year   enddef ;
352newscriptindex mfid_month  ; mfid_month  := scriptindex "month"  ; def month  = runscript mfid_month  enddef ;
353newscriptindex mfid_day    ; mfid_day    := scriptindex "day"    ; def day    = runscript mfid_day    enddef ;
354newscriptindex mfid_hour   ; mfid_hour   := scriptindex "hour"   ; def hour   = runscript mfid_hour   enddef ;
355newscriptindex mfid_minute ; mfid_minute := scriptindex "minute" ; def minute = runscript mfid_minute enddef ;
356newscriptindex mfid_second ; mfid_second := scriptindex "second" ; def second = runscript mfid_second enddef ;
357
358permanent year, month, day, hour, minute, second ; % overloaded
359
360% You cannot overload a local color bu using a prefix works ok:
361%
362% \definecolor [ name = "mp:myred", r = .9 ] ;
363
364newscriptindex mfid_definecolor ; mfid_definecolor := scriptindex "definecolor" ;
365
366def definecolor = runscript mfid_definecolor ; enddef ; % the semicolon prevents lookahead
367
368permanent definecolor ;
369
370% showproperty  fullcircle ;
371% showhashentry "fullcircle" ;
372
373newscriptindex mfid_showproperty  ; mfid_showproperty  := scriptindex("showproperty") ;
374newscriptindex mfid_showhashentry ; mfid_showhashentry := scriptindex("showhashentry") ;
375
376def showproperty  = runscript mfid_showproperty  enddef ;
377def showhashentry = runscript mfid_showhashentry enddef ;
378
379permanent showproperty, showhashentry ;
380
381newscriptindex mfid_textextanchor ; mfid_textextanchor := scriptindex("textextanchor") ;
382
383% def textextanchor = runscript mfid_textextanchor enddef ;
384
385vardef textextanchor(expr p) =
386    runscript mfid_textextanchor (prescriptpart p)
387enddef ;
388
389permanent textextanchor ;
390
391newscriptindex mfid_anchorxy   ; mfid_anchorxy   := scriptindex "anchorxy"   ;
392newscriptindex mfid_anchorx    ; mfid_anchorx    := scriptindex "anchorx"    ;
393newscriptindex mfid_anchory    ; mfid_anchory    := scriptindex "anchory"    ;
394newscriptindex mfid_anchorht   ; mfid_anchorht   := scriptindex "anchorht"   ;
395newscriptindex mfid_anchordp   ; mfid_anchordp   := scriptindex "anchordp"   ;
396newscriptindex mfid_anchorul   ; mfid_anchorul   := scriptindex "anchorul"   ;
397newscriptindex mfid_anchorll   ; mfid_anchorll   := scriptindex "anchorll"   ;
398newscriptindex mfid_anchorlr   ; mfid_anchorlr   := scriptindex "anchorlr"   ;
399newscriptindex mfid_anchorur   ; mfid_anchorur   := scriptindex "anchorur"   ;
400newscriptindex mfid_anchorbox  ; mfid_anchorbox  := scriptindex "anchorbox"  ;
401newscriptindex mfid_anchorspan ; mfid_anchorspan := scriptindex "anchorspan" ;
402
403def anchorxy (expr name, x, y) = runscript mfid_anchorxy  name x y enddef ;
404def anchorx  (expr name, x, y) = runscript mfid_anchorx   name x y enddef ;
405def anchory  (expr name, x, y) = runscript mfid_anchory   name x y enddef ;
406def anchorht (expr name, x, y) = runscript mfid_anchorht  name x y enddef ;
407def anchordp (expr name, x, y) = runscript mfid_anchordp  name x y enddef ;
408def anchorul (expr name, x, y) = runscript mfid_anchorul  name x y enddef ;
409def anchorll (expr name, x, y) = runscript mfid_anchorll  name x y enddef ;
410def anchorlr (expr name, x, y) = runscript mfid_anchorlr  name x y enddef ;
411def anchorur (expr name, x, y) = runscript mfid_anchorur  name x y enddef ;
412
413% todo: matrix =
414
415string mfun_local_anchor_tag ; mfun_local_anchor_tag := "matrix" ; % todo: push pop
416
417
418vardef localanchorbox (expr lname, fx, fy, rname, tx, ty) = (runscript mfid_anchorbox  lname fx fy rname tx ty) enddef ;
419vardef localanchorspan(expr lname, fx, fy, rname, tx, ty) = (runscript mfid_anchorspan lname fx fy rname tx ty) enddef ;
420vardef localanchorcell(expr  name,  x,  y               ) = (runscript mfid_anchorspan  name  x  y  name  x  y) enddef ;
421
422vardef anchorbox (expr fx, fy, tx, ty) = (runscript mfid_anchorbox  mfun_local_anchor_tag fx fy mfun_local_anchor_tag tx ty) enddef ;
423vardef anchorspan(expr fx, fy, tx, ty) = (runscript mfid_anchorspan mfun_local_anchor_tag fx fy mfun_local_anchor_tag tx ty) enddef ;
424vardef anchorcell(expr  x,  y        ) = (runscript mfid_anchorspan mfun_local_anchor_tag  x  y mfun_local_anchor_tag  x  y) enddef ;
425
426vardef matrixbox (expr fx, fy, tx, ty) = (runscript mfid_anchorbox  mfun_local_anchor_tag fx fy mfun_local_anchor_tag (tx+1) ty) enddef ;
427vardef matrixspan(expr fx, fy, tx, ty) = (runscript mfid_anchorspan mfun_local_anchor_tag fx fy mfun_local_anchor_tag (tx+1) ty) enddef ;
428vardef matrixcell(expr  x,  y        ) = (runscript mfid_anchorbox  mfun_local_anchor_tag  x  y mfun_local_anchor_tag ( x+1)  y) enddef ;
429
430permanent
431    anchorxy, anchorx, anchory,
432    anchorht, anchordp,
433    anchorul, anchorll, anchorlr, anchorur, anchorbox,
434    anchorspan ;
435
436permanent
437    matrixbox, matrixspan, matrixcell
438
439