mp-luas.mpxl /size: 21 Kb    last modification: 2025-02-21 11:03
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, positionpar,
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 sortedpath, 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_utfchr ; mfid_utfchr := scriptindex "utfchr" ;
278newscriptindex mfid_utfnum ; mfid_utfnum := scriptindex "utfnum" ;
279newscriptindex mfid_utflen ; mfid_utflen := scriptindex "utflen" ;
280newscriptindex mfid_utfsub ; mfid_utfsub := scriptindex "utfsub" ;
281
282% def utfnum = runscript mfid_utfnum enddef ;
283% def utflen = runscript mfid_utflen enddef ;
284% def utfsub = runscript mfid_utfsub enddef ;
285
286vardef utfchr(expr s) = runscript mfid_utfchr s enddef ; % number
287vardef utfnum(expr s) = runscript mfid_utfnum s enddef ; % str
288vardef utflen(expr s) = runscript mfid_utflen s enddef ; % str
289vardef utfsub(text t) = runscript mfid_utfsub t enddef ; % str, first, (optional) last
290
291permanent utfchr, utfnum, utflen, utfsub ;
292
293newscriptindex mfid_getparameters        ; mfid_getparameters        := scriptindex "getparameters" ;
294newscriptindex mfid_presetparameters     ; mfid_presetparameters     := scriptindex "presetparameters" ;
295newscriptindex mfid_hasparameter         ; mfid_hasparameter         := scriptindex "hasparameter" ;
296newscriptindex mfid_hasoption            ; mfid_hasoption            := scriptindex "hasoption" ;
297newscriptindex mfid_getparameter         ; mfid_getparameter         := scriptindex "getparameter" ;
298newscriptindex mfid_getparameterdefault  ; mfid_getparameterdefault  := scriptindex "getparameterdefault" ;
299newscriptindex mfid_getparametercount    ; mfid_getparametercount    := scriptindex "getparametercount" ;
300newscriptindex mfid_getmaxparametercount ; mfid_getmaxparametercount := scriptindex "getmaxparametercount" ;
301newscriptindex mfid_getparameterpath     ; mfid_getparameterpath     := scriptindex "getparameterpath" ;
302newscriptindex mfid_getparameterpen      ; mfid_getparameterpen      := scriptindex "getparameterpen" ;
303newscriptindex mfid_getparametertext     ; mfid_getparametertext     := scriptindex "getparametertext" ;
304%              mfid_getparameteroption   ; mfid_getparameteroption   := scriptindex "getparameteroption" ;
305newscriptindex mfid_applyparameters      ; mfid_applyparameters      := scriptindex "applyparameters" ;
306newscriptindex mfid_mergeparameters      ; mfid_mergeparameters      := scriptindex "mergeparameters" ;
307newscriptindex mfid_pushparameters       ; mfid_pushparameters       := scriptindex "pushparameters" ;
308newscriptindex mfid_popparameters        ; mfid_popparameters        := scriptindex "popparameters" ;
309newscriptindex mfid_setluaparameter      ; mfid_setluaparameter      := scriptindex "setluaparameter" ;
310
311def getparameters        = runscript mfid_getparameters        enddef ;
312def presetparameters     = runscript mfid_presetparameters     enddef ;
313def hasparameter         = runscript mfid_hasparameter         enddef ;
314def hasoption            = runscript mfid_hasoption            enddef ;
315def getparameter         = runscript mfid_getparameter         enddef ;
316def getparameterdefault  = runscript mfid_getparameterdefault  enddef ;
317def getparametercount    = runscript mfid_getparametercount    enddef ;
318def getmaxparametercount = runscript mfid_getmaxparametercount enddef ;
319def getparameterpath     = runscript mfid_getparameterpath     enddef ;
320def getparameterpen      = runscript mfid_getparameterpen      enddef ;
321def getparametertext     = runscript mfid_getparametertext     enddef ;
322%   getparameteroption   = runscript mfid_getparameteroption   enddef ;
323def applyparameters      = runscript mfid_applyparameters      enddef ;
324def mergeparameters      = runscript mfid_mergeparameters      enddef ;
325def pushparameters       = runscript mfid_pushparameters       enddef ;
326def popparameters        = runscript mfid_popparameters        enddef ;
327def setluaparameter      = runscript mfid_setluaparameter      enddef ;
328
329permanent getparameters, presetparameters, hasparameter, hasoption, getparameter, getparameterdefault,
330    getparametercount, getmaxparametercount, getparameterpath, getparameterpen, getparametertext, % getparameteroption,
331    applyparameters, mergeparameters, pushparameters, popparameters, setluaparameter ;
332
333newscriptindex mfun_newrecord ; mfun_newrecord := scriptindex "newrecord" ;
334newscriptindex mfun_setrecord ; mfun_setrecord := scriptindex "setrecord" ;
335newscriptindex mfun_getrecord ; mfun_getrecord := scriptindex "getrecord" ;
336newscriptindex mfun_cntrecord ; mfun_cntrecord := scriptindex "cntrecord" ;
337
338% let record = runscript ; % We need to use "let" because we don't expand!
339
340def record    = newinternal numeric runscript enddef ;
341
342def newrecord = runscript mfun_newrecord ; enddef ; % semicolon prevents lookahead
343def setrecord = runscript mfun_setrecord ; enddef ;
344def getrecord = runscript mfun_getrecord   enddef ;
345def cntrecord = runscript mfun_cntrecord   enddef ;
346
347permanent
348    record, newrecord, setrecord, getrecord, cntrecord ;
349
350% No vardef's because we need to scan for an assignment too and we'll see
351% an endgroup otherwise.
352
353newscriptindex mfid_year   ; mfid_year   := scriptindex "year"   ; def year   = runscript mfid_year   enddef ;
354newscriptindex mfid_month  ; mfid_month  := scriptindex "month"  ; def month  = runscript mfid_month  enddef ;
355newscriptindex mfid_day    ; mfid_day    := scriptindex "day"    ; def day    = runscript mfid_day    enddef ;
356newscriptindex mfid_hour   ; mfid_hour   := scriptindex "hour"   ; def hour   = runscript mfid_hour   enddef ;
357newscriptindex mfid_minute ; mfid_minute := scriptindex "minute" ; def minute = runscript mfid_minute enddef ;
358newscriptindex mfid_second ; mfid_second := scriptindex "second" ; def second = runscript mfid_second enddef ;
359
360permanent year, month, day, hour, minute, second ; % overloaded
361
362% You cannot overload a local color bu using a prefix works ok:
363%
364% \definecolor [ name = "mp:myred", r = .9 ] ;
365
366newscriptindex mfid_definecolor ; mfid_definecolor := scriptindex "definecolor" ;
367
368def definecolor = runscript mfid_definecolor ; enddef ; % the semicolon prevents lookahead
369
370permanent definecolor ;
371
372% showproperty  fullcircle ;
373% showhashentry "fullcircle" ;
374
375newscriptindex mfid_showproperty  ; mfid_showproperty  := scriptindex("showproperty") ;
376newscriptindex mfid_showhashentry ; mfid_showhashentry := scriptindex("showhashentry") ;
377
378def showproperty  = runscript mfid_showproperty  enddef ;
379def showhashentry = runscript mfid_showhashentry enddef ;
380
381permanent showproperty, showhashentry ;
382
383newscriptindex mfid_textextanchor ; mfid_textextanchor := scriptindex("textextanchor") ;
384
385% def textextanchor = runscript mfid_textextanchor enddef ;
386
387vardef textextanchor(expr p) =
388    runscript mfid_textextanchor (prescriptpart p)
389enddef ;
390
391permanent textextanchor ;
392
393newscriptindex mfid_anchorxy   ; mfid_anchorxy   := scriptindex "anchorxy"   ;
394newscriptindex mfid_anchorx    ; mfid_anchorx    := scriptindex "anchorx"    ;
395newscriptindex mfid_anchory    ; mfid_anchory    := scriptindex "anchory"    ;
396newscriptindex mfid_anchorht   ; mfid_anchorht   := scriptindex "anchorht"   ;
397newscriptindex mfid_anchordp   ; mfid_anchordp   := scriptindex "anchordp"   ;
398newscriptindex mfid_anchorul   ; mfid_anchorul   := scriptindex "anchorul"   ;
399newscriptindex mfid_anchorll   ; mfid_anchorll   := scriptindex "anchorll"   ;
400newscriptindex mfid_anchorlr   ; mfid_anchorlr   := scriptindex "anchorlr"   ;
401newscriptindex mfid_anchorur   ; mfid_anchorur   := scriptindex "anchorur"   ;
402newscriptindex mfid_anchorbox  ; mfid_anchorbox  := scriptindex "anchorbox"  ;
403newscriptindex mfid_anchorspan ; mfid_anchorspan := scriptindex "anchorspan" ;
404
405def anchorxy (expr name, x, y) = runscript mfid_anchorxy  name x y enddef ;
406def anchorx  (expr name, x, y) = runscript mfid_anchorx   name x y enddef ;
407def anchory  (expr name, x, y) = runscript mfid_anchory   name x y enddef ;
408def anchorht (expr name, x, y) = runscript mfid_anchorht  name x y enddef ;
409def anchordp (expr name, x, y) = runscript mfid_anchordp  name x y enddef ;
410def anchorul (expr name, x, y) = runscript mfid_anchorul  name x y enddef ;
411def anchorll (expr name, x, y) = runscript mfid_anchorll  name x y enddef ;
412def anchorlr (expr name, x, y) = runscript mfid_anchorlr  name x y enddef ;
413def anchorur (expr name, x, y) = runscript mfid_anchorur  name x y enddef ;
414
415% todo: matrix =
416
417string mfun_local_anchor_tag ; mfun_local_anchor_tag := "matrix" ; % todo: push pop
418
419
420vardef localanchorbox (expr lname, fx, fy, rname, tx, ty) = (runscript mfid_anchorbox  lname fx fy rname tx ty) enddef ;
421vardef localanchorspan(expr lname, fx, fy, rname, tx, ty) = (runscript mfid_anchorspan lname fx fy rname tx ty) enddef ;
422vardef localanchorcell(expr  name,  x,  y               ) = (runscript mfid_anchorspan  name  x  y  name  x  y) enddef ;
423
424vardef anchorbox (expr fx, fy, tx, ty) = (runscript mfid_anchorbox  mfun_local_anchor_tag fx fy mfun_local_anchor_tag tx ty) enddef ;
425vardef anchorspan(expr fx, fy, tx, ty) = (runscript mfid_anchorspan mfun_local_anchor_tag fx fy mfun_local_anchor_tag tx ty) enddef ;
426vardef anchorcell(expr  x,  y        ) = (runscript mfid_anchorspan mfun_local_anchor_tag  x  y mfun_local_anchor_tag  x  y) enddef ;
427
428vardef matrixbox (expr fx, fy, tx, ty) = (runscript mfid_anchorbox  mfun_local_anchor_tag fx fy mfun_local_anchor_tag (tx+1) ty) enddef ;
429vardef matrixspan(expr fx, fy, tx, ty) = (runscript mfid_anchorspan mfun_local_anchor_tag fx fy mfun_local_anchor_tag (tx+1) ty) enddef ;
430vardef matrixcell(expr  x,  y        ) = (runscript mfid_anchorbox  mfun_local_anchor_tag  x  y mfun_local_anchor_tag ( x+1)  y) enddef ;
431
432permanent
433    anchorxy, anchorx, anchory,
434    anchorht, anchordp,
435    anchorul, anchorll, anchorlr, anchorur, anchorbox,
436    anchorspan ;
437
438permanent
439    matrixbox, matrixspan, matrixcell
440
441