1if not modules then modules = { } end modules [ ' mlib-ctx ' ] = {
2 version = 1 . 001 ,
3 comment = " companion to mlib-ctx.mkiv " ,
4 author = " Hans Hagen, PRAGMA-ADE, Hasselt NL " ,
5 copyright = " PRAGMA ADE / ConTeXt Development Team " ,
6 license = " see context related readme files " ,
7}
8
9local type , tostring = type , tostring
10local format , concat = string . format , table . concat
11local settings_to_hash = utilities . parsers . settings_to_hash
12local formatters = string . formatters
13
14local report_metapost = logs . reporter ( " metapost " )
15local status_metapost = logs . messenger ( " metapost " )
16
17local starttiming = statistics . starttiming
18local stoptiming = statistics . stoptiming
19
20local trace_graphic = false
21
22trackers . register ( " metapost.graphics " ,
23 function ( v ) trace_graphic = v end
24) ;
25
26local mplib = mplib
27
28metapost = metapost or { }
29local metapost = metapost
30local context = context
31
32local setters = tokens . setters
33local setmacro = setters . macro
34local implement = interfaces . implement
35
36local v_no = interfaces . variables . no
37
38local extensiondata = metapost . extensiondata or storage . allocate { }
39metapost . extensiondata = extensiondata
40
41storage . register ( " metapost/extensiondata " , extensiondata , " metapost.extensiondata " )
42
43function metapost . setextensions ( instances , data )
44 if data and data ~ = " " then
45 extensiondata [ # extensiondata + 1 ] = {
46 usedinall = not instances or instances = = " " ,
47 instances = settings_to_hash ( instances or " " ) ,
48 extensions = data ,
49 }
50 end
51end
52
53function metapost . getextensions ( instance , state )
54 if state and state = = v_no then
55 return " "
56 else
57 local t = { }
58 for i = 1 , # extensiondata do
59 local e = extensiondata [ i ]
60 local status = e . instances [ instance ]
61 if ( status ~ = true ) and ( e . usedinall or status ) then
62 t [ # t + 1 ] = e . extensions
63 e . instances [ instance ] = true
64 end
65 end
66 return concat ( t , " " )
67 end
68end
69
70implement {
71 name = " setmpextensions " ,
72 actions = metapost . setextensions ,
73 arguments = " 2 strings " ,
74}
75
76implement {
77 name = " getmpextensions " ,
78 actions = { metapost . getextensions , context } ,
79 arguments = " string "
80}
81
82local patterns = {
83 CONTEXTLMTXMODE > 0 and " meta-imp-%s.mkxl " or " " ,
84 " meta-imp-%s.mkiv " ,
85 " meta-imp-%s.tex " ,
86
87 " meta-%s.mkiv " ,
88 " meta-%s.tex "
89}
90
91local function action ( name , foundname )
92 commands . loadlibrary ( name , foundname , false )
93 status_metapost ( " library %a is loaded " , name )
94end
95
96local function failure ( name )
97 report_metapost ( " library %a is unknown or invalid " , name )
98end
99
100implement {
101 name = " useMPlibrary " ,
102 arguments = " string " ,
103 actions = function ( name )
104 resolvers . uselibrary {
105 name = name ,
106 patterns = patterns ,
107 action = action ,
108 failure = failure ,
109 onlyonce = true ,
110 }
111 end
112}
113
114
115
116implement {
117 name = " mprunvar " ,
118 arguments = " string " ,
119 actions = function ( name )
120 local value = metapost . variables [ name ]
121 if value ~ = nil then
122 local tvalue = type ( value )
123 if tvalue = = " table " then
124 context ( concat ( value , " " ) )
125 elseif tvalue = = " number " or tvalue = = " boolean " then
126 context ( tostring ( value ) )
127 elseif tvalue = = " string " then
128 context ( value )
129 end
130 end
131 end
132}
133
134implement {
135 name = " mpruntab " ,
136 arguments = { " string " , " integer " } ,
137 actions = function ( name , n )
138 local value = metapost . variables [ name ]
139 if value ~ = nil then
140 local tvalue = type ( value )
141 if tvalue = = " table " then
142 context ( value [ n ] )
143 elseif tvalue = = " number " or tvalue = = " boolean " then
144 context ( tostring ( value ) )
145 elseif tvalue = = " string " then
146 context ( value )
147 end
148 end
149 end
150}
151
152implement {
153 name = " mprunset " ,
154 arguments = " 2 strings " ,
155 actions = function ( name , connector )
156 local value = metapost . variables [ name ]
157 if value ~ = nil then
158 local tvalue = type ( value )
159 if tvalue = = " table " then
160 context ( concat ( value , connector ) )
161 elseif tvalue = = " number " or tvalue = = " boolean " then
162 context ( tostring ( value ) )
163 elseif tvalue = = " string " then
164 context ( value )
165 end
166 end
167 end
168}
169
170
171
172
173function metapost . graphic ( specification )
174 metapost . pushformat ( specification )
175 metapost . graphic_base_pass ( specification )
176 metapost . popformat ( )
177end
178
179function metapost . startgraphic ( t )
180 if not t then
181 t = { }
182 end
183 if not t . instance then
184 t . instance = metapost . defaultinstance
185 end
186 if not t . format then
187 t . format = metapost . defaultformat
188 end
189 if not t . method then
190 t . method = metapost . defaultmethod
191 end
192 t . data = { }
193 return t
194end
195
196function metapost . stopgraphic ( t )
197 if t then
198 t . data = concat ( t . data or { } , " \n " )
199 if trace_graphic then
200 report_metapost ( " \n " . . t . data . . " \n " )
201 end
202 metapost . graphic ( t )
203 end
204end
205
206function metapost . tographic ( t , f , s , ... )
207 local d = t . data
208 d [ # d + 1 ] = s and formatters [ f ] ( s , ... ) or f
209end
210
211implement {
212 name = " mpgraphic " ,
213 actions = metapost . graphic ,
214 arguments = {
215 {
216 { " instance " } ,
217 { " format " } ,
218 { " data " } ,
219 { " initializations " } ,
220 { " extensions " } ,
221 { " inclusions " } ,
222 { " definitions " } ,
223 { " figure " } ,
224 { " method " } ,
225 { " namespace " } ,
226 }
227 }
228}
229
230implement {
231 name = " mpsetoutercolor " ,
232 actions = function ( ... ) metapost . setoutercolor ( ... ) end ,
233 arguments = { " integer " , " integer " , " integer " , " integer " }
234}
235
236implement {
237 name = " mpflushreset " ,
238 actions = function ( ) metapost . flushreset ( ) end
239}
240
241implement {
242 name = " mpflushliteral " ,
243 actions = function ( str ) metapost . flushliteral ( str ) end ,
244 arguments = " string " ,
245}
246
247
248
249function metapost . getclippath ( specification )
250 local mpx = metapost . pushformat ( specification )
251 local data = specification . data or " "
252 if mpx and data ~ = " " then
253 starttiming ( metapost )
254 starttiming ( metapost . exectime )
255 local result = mpx : execute ( format ( " %s;%s;beginfig(1);%s;%s;endfig; " ,
256 specification . extensions or " " ,
257 specification . inclusions or " " ,
258 specification . initializations or " " ,
259 data
260 ) )
261 stoptiming ( metapost . exectime )
262 if result . status > 0 then
263 report_metapost ( " %s: %s " , result . status , result . error or result . term or result . log )
264 result = nil
265 else
266 result = metapost . filterclippath ( result )
267 end
268 stoptiming ( metapost )
269 metapost . popformat ( )
270 return result
271 else
272 metapost . popformat ( )
273 end
274end
275
276function metapost . filterclippath ( result )
277 if result then
278 local figures = result . fig
279 if figures and # figures > 0 then
280 local figure = figures [ 1 ]
281 local objects = figure : objects ( )
282 if objects then
283 local lastclippath
284 for o = 1 , # objects do
285 local object = objects [ o ]
286 if object . type = = " start_clip " then
287 lastclippath = object . path
288 end
289 end
290 return lastclippath
291 end
292 end
293 end
294end
295
296function metapost . theclippath ( ... )
297 local result = metapost . getclippath ( ... )
298 if result then
299 return concat ( metapost . flushnormalpath ( result ) , " " )
300 else
301 return " "
302 end
303end
304
305implement {
306 name = " mpsetclippath " ,
307 actions = function ( specification )
308 local p = specification . data and metapost . theclippath ( specification )
309 if not p or p = = " " then
310 local b = number . dimenfactors . bp
311 local w = b * ( specification . width or 0 )
312 local h = b * ( specification . height or 0 )
313 p = formatters [ " 0 0 m %.6N 0 l %.6N %.6N l 0 %.6N l " ] ( w , w , h , h )
314 end
315 setmacro ( " MPclippath " , p , " global " )
316 end ,
317 arguments = {
318 {
319 { " instance " } ,
320 { " format " } ,
321 { " data " } ,
322 { " initializations " } ,
323 { " useextensions " } ,
324 { " inclusions " } ,
325 { " method " } ,
326 { " namespace " } ,
327 { " width " , " dimension " } ,
328 { " height " , " dimension " } ,
329 } ,
330 }
331}
332
333statistics . register ( " metapost " , function ( )
334 local n = metapost . nofruns
335 if n and n > 0 then
336 local elapsedtime = statistics . elapsedtime
337 local elapsed = statistics . elapsed
338 local runs , stats = metapost . nofscriptruns ( )
339 local instances ,
340 memory = metapost . getstatistics ( true )
341 return format ( " %s seconds, loading: %s, execution: %s, n: %s, average: %s, instances: %i, luacalls: %s, memory: %0.3f M " ,
342 elapsedtime ( metapost ) , elapsedtime ( mplib ) , elapsedtime ( metapost . exectime ) , n ,
343 elapsedtime ( ( elapsed ( metapost ) + elapsed ( mplib ) + elapsed ( metapost . exectime ) ) / n ) ,
344 instances , stats and stats or runs , memory / ( 1024 * 1024 ) )
345 else
346 return nil
347 end
348end )
349
350
351
352metapost . tex = metapost . tex or { }
353local mptex = metapost . tex
354
355local environments = { }
356
357function mptex . set ( str )
358 environments [ # environments + 1 ] = str
359end
360
361function mptex . setfrombuffer ( name )
362 environments [ # environments + 1 ] = buffers . getcontent ( name )
363end
364
365function mptex . get ( )
366 return concat ( environments , " \n " )
367end
368
369function mptex . reset ( )
370 environments = { }
371end
372
373implement {
374 name = " mppushvariables " ,
375 actions = metapost . pushvariables ,
376}
377
378implement {
379 name = " mppopvariables " ,
380 actions = metapost . popvariables ,
381}
382
383implement {
384 name = " mptexset " ,
385 arguments = " string " ,
386 actions = mptex . set
387}
388
389implement {
390 name = " mptexsetfrombuffer " ,
391 arguments = " string " ,
392 actions = mptex . setfrombuffer
393}
394
395implement {
396 name = " mptexget " ,
397 actions = { mptex . get , context }
398}
399
400implement {
401 name = " mptexreset " ,
402 actions = mptex . reset
403}
404
405
406
407mp = mp or {
408 set = { } ,
409 get = { } ,
410 aux = { } ,
411 scan = { } ,
412 skip = { } ,
413 inject = { } ,
414}
415
416MP = MP or { }
417
418
419
420
421
422
423
424
425
426
427
428
429
430table . setmetatablecall ( mp , function ( t , k , ... ) return t [ k ] ( ... ) end )
431table . setmetatablecall ( MP , function ( t , k , ... ) return t [ k ] ( ... ) end )
432 |