meta-ini.mkxl /size: 45 Kb    last modification: 2023-12-21 09:44
1%D \module
2%D   [       file=meta-ini,
3%D        version=2008.03.25,
4%D          title=\METAPOST\ Graphics,
5%D       subtitle=Initialization,
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
14%D For real \METAFUN\ magic see \type {https://art-aleatoire.com/}.
15
16% initializations:
17%
18% - pass settings from tex to mp (delayed expansion)
19% - used by context core (and modules)
20% - cummulative definitions
21% - flushed each graphic
22% - can be disabled per instance
23% - managed at the tex end
24%
25% extensions:
26%
27% - add mp functionality (immediate expansion)
28% - cummulative
29% - all instances or subset of instances
30% - can be disabled per instance
31% - managed at the lua/mp end
32% - could be managed at the tex end but no real reason and also messy
33%
34% definitions:
35%
36% - add mp functionality (delayed expansion)
37% - cummulative
38% - per instance
39% - managed at the tex end
40%
41% inclusions:
42%
43% - add mp functionality (delayed expansion)
44% - cummulative only when [+]
45% - per instance
46% - managed at the tex end
47%
48% order of execution:
49%
50%   definitions
51%   extensions
52%   inclusions
53%   beginfig
54%     initializations
55%     graphic
56%   endfig
57
58% The instance will be implemented stepwise ... I should redo some code in order to
59% make the macros look better than they do now.
60
61\writestatus{loading}{MetaPost Graphics / Initializations}
62
63\registerctxluafile{meta-ini}{autosuffix}
64
65\unprotect
66
67\newtoks \everyMPgraphic          % mp % public or not ?
68
69\appendtoks
70    \setcatcodetable\ctxcatcodes
71    % then this is not needed:
72    \restoreendofline % see interferences-001.tex
73\to \everyMPgraphic
74
75\mutable  \def\MPruntimefile    {mprun}
76\mutable  \def\currentMPformat  {metafun}
77\immutable\def\defaultMPinstance{metafun}
78
79\installcorenamespace{mpinstance}
80\installcorenamespace{mpinclusions}
81\installcorenamespace{mpdefinitions}
82\installcorenamespace{mpgraphic}
83\installcorenamespace{mpstaticgraphic}
84\installcorenamespace{mpclip}
85\installcorenamespace{mpcategory}
86
87\newtoks \t_meta_initializations  % tex, each
88
89\permanent\def\t_meta_inclusions {\csname\??mpinclusions \currentMPinstance\endcsname} % token register
90\permanent\def\t_meta_definitions{\csname\??mpdefinitions\currentMPinstance\endcsname} % token register
91
92%D The next command is, of course, dedicated to Mojca, who needs it for gnuplot.
93%D Anyway, the whole multiple engine mechanism is to keep her gnuplot from
94%D interfering.
95
96\permanent\tolerant\protected\def\startMPdefinitions#=#:#2\stopMPdefinitions
97  {\let\m_meta_saved_instance\currentMPinstance
98   \cdef\currentMPinstance{#1}%
99   \ifempty\currentMPinstance
100     \let\currentMPinstance\defaultMPinstance
101   \fi
102   \gtoksapp\t_meta_definitions{#2}%
103   \let\currentMPinstance\m_meta_saved_instance}
104
105\permanent\protected\lettonothing\stopMPdefinitions
106
107\permanent\tolerant\protected\def\startMPextensions#=#:#2\stopMPextensions % we could use buffers instead
108  {\clf_setmpextensions{#1}{#2}}
109
110\permanent\protected\lettonothing\stopMPextensions
111
112\permanent\protected\def\startMPinitializations#1\stopMPinitializations % for all instances, when enabled
113  {\gtoksapp\t_meta_initializations{#1}}
114
115\permanent\protected\lettonothing\stopMPinitializations
116
117\permanent\tolerant\protected\def\startMPinclusions[#1]#*#=#:#3\stopMPinclusions
118  {\let\m_meta_saved_instance\currentMPinstance % \pushmacro
119   \cdef\currentMPinstance{#2}%
120   \ifempty\currentMPinstance
121     \let\currentMPinstance\defaultMPinstance
122   \fi
123   \iftok{#1}{+}\else
124     \global\t_meta_inclusions\emptytoks
125   \fi
126   \gtoksapp\t_meta_inclusions{#3}%
127   \let\currentMPinstance\m_meta_saved_instance} % \popmacro
128
129\permanent\protected\lettonothing\stopMPinclusions
130
131% The next was broken since we added instances so it will go away!
132
133\permanent\tolerant\protected\def\MPinclusions[#1]#:#*#=#:#*#=%
134  {\let\m_meta_saved_instance\currentMPinstance
135   \iftok{#1}{+}\else
136     \global\t_meta_inclusions\emptytoks
137   \fi
138   \ifparameter#3\or
139     \cdef\currentMPinstance{#2}%
140     \ifempty\currentMPinstance
141       \let\currentMPinstance\defaultMPinstance
142     \fi
143     \gtoksapp\t_meta_inclusions{#3}%
144   \else
145     \let\currentMPinstance\defaultMPinstance
146     \gtoksapp\t_meta_inclusions{#2}%
147   \fi
148   \let\currentMPinstance\m_meta_saved_instance}
149
150% so far
151
152\installcommandhandler \??mpinstance {MPinstance} \??mpinstance
153
154\setupMPinstance
155  [\s!format=metafun,
156   \s!extensions=\v!no,
157   \s!initializations=\v!no,
158   \c!method=\s!default,
159   \c!textstyle=,
160   \c!textcolor=]
161
162\appendtoks
163    \ifcsname\??mpdefinitions\currentMPinstance\endcsname \else
164      \expandafter\newtoks\csname\??mpdefinitions\currentMPinstance\endcsname
165    \fi
166    \ifcsname\??mpinclusions\currentMPinstance\endcsname \else
167      \expandafter\newtoks\csname\??mpinclusions\currentMPinstance\endcsname
168    \fi
169    \t_meta_definitions\emptytoks % in case we redefine
170    \t_meta_inclusions \emptytoks % in case we redefine
171\to \everydefineMPinstance
172
173% \permanent\protected\def\resetMPinstance[#1]%
174%   {\writestatus\m!metapost{reset will be implemented when needed}}
175
176\def\meta_analyze_graphicname[#1]%
177  {\normalexpanded{\meta_analyze_graphicname_indeed[#1::::]}}
178
179\def\meta_show_properties_indeed
180  {\writestatus{metapost}{name: \currentMPgraphicname, instance: \currentMPinstance, format: \currentMPformat}}
181
182\let\meta_show_properties\donothing
183
184\installtextracker
185  {metapost.properties}
186  {\let\meta_show_properties\meta_show_properties_indeed}
187  {\let\meta_show_properties\donothing}
188
189\protected\def\meta_analyze_graphicname_indeed[#1::#2::#3]% instance ::
190  {\cdef\currentMPgraphicname{#2}%
191   \ifempty\currentMPgraphicname
192     \cdef\currentMPgraphicname{#1}%
193     \let\currentMPinstance\defaultMPinstance
194   \orelse\ifcsname\??mpdefinitions#1\endcsname
195     \cdef\currentMPinstance{#1}%
196   \else
197     \let\currentMPinstance\defaultMPinstance
198   \fi
199   \cdef\currentMPformat{\MPinstanceparameter\s!format}%
200   \meta_show_properties}
201
202\mutable\def\currentMPgraphicname{\s!unknown}
203\mutable\def\currentMPinstance   {\defaultMPinstance}
204\mutable\def\currentMPformat     {\currentMPinstance}
205
206\defineMPinstance[metafun]    [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!double]
207\defineMPinstance[minifun]    [\s!format=minifun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!double]
208\defineMPinstance[extrafun]   [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!double]
209\defineMPinstance[lessfun]    [\s!format=metafun]
210\defineMPinstance[scaledfun]  [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!scaled]
211\defineMPinstance[doublefun]  [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!double]
212\defineMPinstance[binaryfun]  [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!binary]
213\defineMPinstance[decimalfun] [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!decimal]
214\defineMPinstance[positfun]   [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!posit]
215
216\defineMPinstance[mprun]      [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes]
217
218\defineMPinstance[metapost]   [\s!format=mpost]
219\defineMPinstance[nofun]      [\s!format=mpost]
220\defineMPinstance[scaledpost] [\s!format=mpost,\c!method=\s!scaled]
221\defineMPinstance[doublepost] [\s!format=mpost,\c!method=\s!double]
222\defineMPinstance[binarypost] [\s!format=mpost,\c!method=\s!binary]
223\defineMPinstance[decimalpost][\s!format=mpost,\c!method=\s!decimal]
224
225\defineMPinstance[simplefun]  [\s!format=metafun,\c!method=\s!double] % maybe use minifun
226
227%defineMPinstance[megapost]   [\s!format=mpost,\c!method=\s!decimal]
228
229\newconditional\c_meta_include_initializations
230
231\def\meta_begin_graphic_group#1%
232  {\begingroup
233   \meta_analyze_graphicname[#1]}
234
235\def\meta_end_graphic_group
236  {\endgroup}
237
238\mutable\def\MPaskedfigure{false}
239
240\def\meta_flush_current_initializations
241  {\ifconditional\c_meta_include_initializations
242     \the\t_meta_initializations
243   \fi}
244
245\def\meta_flush_current_inclusions
246  {\the\t_meta_inclusions}
247
248\def\meta_flush_current_definitions
249  {\the\t_meta_definitions}
250
251\def\meta_start_current_graphic
252  {\begingroup
253   \meta_enable_include
254   \expand\everyMPgraphic
255   \edef\p_initializations{\MPinstanceparameter\s!initializations}%
256   \ifx\p_initializations\v!yes
257     \c_meta_include_initializations\conditionaltrue
258   \else
259     \c_meta_include_initializations\conditionalfalse
260   \fi
261   \edef\p_setups{\MPinstanceparameter\c!setups}%
262   \ifempty\p_setups \else
263     \setups[\p_setups]%
264   \fi
265   \useMPinstancestyleparameter\c!textstyle}
266
267\def\meta_set_current_color
268  {\useMPinstancecolorparameter\c!textcolor}
269
270\def\meta_stop_current_graphic
271  {\global\t_meta_definitions\emptytoks
272   \global\t_meta_inclusions\emptytoks
273   \endgroup}
274
275\def\meta_process_graphic_start
276  {\pushMPboundingbox
277   \setbox\b_meta_graphic\hpack\bgroup}
278
279\let\meta_relocate_graphic\relax % experimental hook
280
281\def\meta_process_graphic_stop
282  {\egroup
283   \meta_place_graphic
284   \meta_relocate_graphic
285   \popMPboundingbox}
286
287\protected\def\meta_process_graphic_instance#1#2% used in startMPpage
288  {\cdef\currentMPinstance{#1}%
289   \ifempty\currentMPinstance
290     \let\currentMPinstance\defaultMPinstance
291   \fi
292   \setmpcategoryparameter\c!stacking{#2}%
293   \cdef\currentMPformat{\MPinstanceparameter\s!format}%
294   \meta_process_graphic}
295
296\protected\def\meta_process_graphic#1% todo: extensions and inclusions outside beginfig
297  {\meta_start_current_graphic
298   \forgetall
299   \meta_process_graphic_start
300     \normalexpanded{\noexpand\clf_mpgraphic
301         instance        {\currentMPinstance}%
302         format          {\currentMPformat}%
303         data            {#1;}%
304         initializations {\meta_flush_current_initializations}%
305    \ifcstok{\MPinstanceparameter\s!extensions}\v!yes
306         extensions      {\clf_getmpextensions{\currentMPinstance}}% goes through tex again, can be done better now
307    \fi
308         inclusions      {\meta_flush_current_inclusions}%
309         definitions     {\meta_flush_current_definitions}%
310         figure          {\MPaskedfigure}%
311         filtering       {\mpcategoryparameter\c!stacking}
312         method          {\MPinstanceparameter\c!method}%
313         namespace       {\??graphicvariable\currentmpcategory:}%
314    \relax}%
315   \meta_process_graphic_stop
316   \meta_stop_current_graphic}
317
318\let\meta_process_graphic_figure_start\relax
319\let\meta_process_graphic_figure_stop \relax
320
321\let\normal_meta_process_graphic_start\relax
322\let\normal_meta_process_graphic_stop \relax
323
324\permanent\protected\def\processMPfigurefile#1% special case: obeys beginfig .. endfig and makes pages
325  {\begingroup
326   \let\normal_meta_process_graphic_start\meta_process_graphic_start
327   \let\normal_meta_process_graphic_stop \meta_process_graphic_stop
328   \let\meta_process_graphic_start\relax
329   \let\meta_process_graphic_stop \relax
330   \def\meta_process_graphic_figure_start{\startTEXpage[\c!offset=\v!overlay,\c!align=]\normal_meta_process_graphic_start}%
331   \def\meta_process_graphic_figure_stop {\normal_meta_process_graphic_stop\stopTEXpage}
332   \def\MPaskedfigure{all}%
333   \meta_process_graphic{input "#1" ;}%
334   \endgroup}
335
336%D Calling up previously defined graphics.
337
338% \def\includeMPgraphic#1% gets expanded !
339%   {\ifcsname\??mpgraphic#1\endcsname
340%      \csname\??mpgraphic#1\endcsname ; % ; is safeguard
341%    \fi}
342%
343% \protected\def\meta_enable_include % public
344%   {\let\meta_handle_use_graphic     \thirdofthreearguments
345%    \let\meta_handle_reusable_graphic\thirdofthreearguments}
346%
347% but ... we want this too:
348%
349% \startuseMPgraphic{x}
350%     draw textext("\externalfigure[foo.pdf]") ;
351% \stopuseMPgraphic
352%
353% \useMPgraphic{x}
354%
355% so we cannot overload unless we let back to the original meanings each graphic
356% ... a better solution is:
357
358\permanent\def\includeMPgraphic#1% gets expanded !
359  {\ifcsname\??mpgraphic#1\endcsname
360     \doubleexpandafter\fourthoffourarguments\lastnamedcs ; % ; is safeguard
361   \fi}
362
363\let\meta_enable_include\relax
364
365%D Drawings (stepwise built):
366
367\newif\ifMPdrawingdone \MPdrawingdonefalse
368
369\permanent\protected\def\finalizeMPdrawing
370  {\MPdrawingdonetrue}
371
372\mutable\lettonothing\MPdrawingdata
373
374\permanent\protected\def\resetMPdrawing
375  {\glettonothing\MPdrawingdata
376   \global\MPdrawingdonefalse}
377
378\permanent\protected\def\pushMPdrawing
379  {\globalpushmacro\MPdrawingdata
380   \glettonothing\MPdrawingdata}
381
382\permanent\protected\def\popMPdrawing
383  {\globalpopmacro\MPdrawingdata}
384
385\permanent\protected\def\getMPdrawing
386  {\ifMPdrawingdone
387     \expandafter\meta_process_graphic\expandafter{\MPdrawingdata}% is this expansion still needed?
388   \fi}
389
390\permanent\tolerant\def\startMPdrawing[#1]% todo: use pickup #:
391  {\meta_start_drawing{#1}}
392
393\def\meta_start_drawing#1#2\stopMPdrawing
394  {\relax
395   \bgroup
396   \meta_enable_include
397   % can be a one liner:
398   \iftok{#1}{-}%
399     \xdef\MPdrawingdata{\MPdrawingdata\detokenize{#2}}%
400   \else
401     \xdef\MPdrawingdata{\MPdrawingdata#2}%
402   \fi
403   \egroup}
404
405\permanent\protected\lettonothing\stopMPdrawing
406
407\permanent\def\MPdrawing#1%
408  {\relax
409   \bgroup
410   \meta_enable_include
411   \xdef\MPdrawingdata{\MPdrawingdata#1}%
412   \egroup}
413
414\permanent\protected\def\startMPclip#1#2\stopMPclip % todo: store at the lua end or just store less
415  {\gdefcsname\??mpclip#1\endcsname{#2}}
416
417\permanent\protected\lettonothing\stopMPclip
418
419\mutable\def\width {0 } % left-over, obsolete
420\mutable\def\height{0 } % left-over, obsolete
421
422\mutable\lettonothing\currentMPclip
423
424\protected\def\meta_grab_clip_path#1#2#3%
425  {\begingroup
426   \d_overlay_width #2\relax
427   \d_overlay_height#3\relax
428   \edef\width {\the\d_overlay_width \space}% obsolete
429   \edef\height{\the\d_overlay_height\space}% obsolete
430   \cdef\currentMPclip{#1}%
431   \ifcsname\??mpclip\currentMPclip\endcsname
432     \meta_grab_clip_path_yes
433   \else
434     \meta_grab_clip_path_nop
435   \fi
436   \endgroup}
437
438\def\meta_grab_clip_path_yes
439  {\meta_start_current_graphic
440     \normalexpanded{\noexpand\clf_mpsetclippath
441       instance        {\currentMPinstance}%
442       format          {\currentMPformat}%
443       data            {\begincsname\??mpclip\currentMPclip\endcsname}%
444       initializations {\meta_flush_current_initializations}%
445       useextensions   {\MPinstanceparameter\s!extensions}%
446       inclusions      {\meta_flush_current_inclusions}%
447       method          {\MPinstanceparameter\c!method}%
448       width           \d_overlay_width
449       height          \d_overlay_height
450     \relax}%
451   \meta_stop_current_graphic}
452
453\def\meta_grab_clip_path_nop
454  {\clf_mpsetclippath
455     width  \d_overlay_width
456     height \d_overlay_height
457   \relax}
458
459%D Since we want labels to follow the document settings, we also set the font
460%D related variables.
461
462\permanent\protected\def\MPfontsizehskip#1%
463  {\dontleavehmode
464   \begingroup
465   \definedfont[#1]%
466   \hskip\clf_currentdesignsize\scaledpoint\relax
467   \endgroup}
468
469\definefontsynonym[MetafunDefault][Regular*default]
470
471\startMPinitializations % scale is not yet ok
472    defaultfont:="\truefontname{MetafunDefault}";
473  % defaultscale:=\the\bodyfontsize/10pt; % only when hard coded 10pt
474  % defaultscale:=1;
475\stopMPinitializations
476
477%D A signal that we're in combined \CONTEXT||\METAFUN mode:
478
479\startMPextensions
480    string contextversion;contextversion:="\contextversion"; % expanded
481\stopMPextensions
482
483%D \macros
484%D   {setupMPvariables}
485%D
486%D When we build collections of \METAPOST\ graphics, like background and buttons,
487%D the need for passing settings arises. By (mis|)|using the local prefix that
488%D belongs to \type {\framed}, we get a rather natural interface to backgrounds. To
489%D prevent conflicts, we will use the \type {-} in \METAPOST\ specific variables,
490%D like:
491%D
492%D \starttyping
493%D \setupMPvariables[meta:button][size=20pt]
494%D \stoptyping
495
496% \lineheight  2pt  2  \scratchcounter  red  0.4  .5\bodyfontsize
497%
498% see cont-loc for test code
499
500%D Currently the inheritance of backgrounds does not work and we might drop it
501%D anyway (too messy)
502
503\lettonothing\m_meta_current_variable
504
505\installbasicnativeautosetuphandler \??mpcategory {mpcategory}
506
507\permanent\tolerant\protected\def\useMPvariables[#1]#*[#2]{} % no longer needed
508
509%D The uppercase ones are the official ones:
510
511\aliased\let\setupMPvariables\setupmpcategory
512\aliased\let\setMPvariables  \setupmpcategory
513
514\def\meta_mpvar_default{\MPcolor{black}\space}
515%def\meta_mpvar_default{0 }
516
517\permanent\def\MPvar#1% todo: could be a framed chain
518  {\beginlocalcontrol
519   \edef\m_meta_current_variable{\mpcategoryparameter{#1}}%
520   \endlocalcontrol
521   \ifempty\m_meta_current_variable
522     \meta_mpvar_default
523   \orelse\ifchkdimension\m_meta_current_variable\or
524     \todimension\lastchkdimension\space\space
525 % \orelse\ifchknum\m_meta_current_variable\or % we need to catch 1>2
526   \orunless\ifempty{\ifchknum\m_meta_current_variable\or\tointeger\m_meta_current_variable\fi}%
527     \tointeger\m_meta_current_variable\space\space % maybe \lastchkinteger
528   \orelse\ifcsname\??colorattribute\currentcolorprefix\m_meta_current_variable\endcsname
529     \MPcolor\m_meta_current_variable\space
530   \orelse\ifcsname\??colorattribute\m_meta_current_variable\endcsname
531     \MPcolor\m_meta_current_variable\space
532   \else
533     \m_meta_current_variable
534   \fi}
535
536\permanent\def\MPrawvar#1#2% todo: could be a framed chain
537  {\beginlocalcontrol
538   \edef\m_meta_current_variable{\namedmpcategoryparameter{#1}{#2}}%
539   \endlocalcontrol
540   \ifempty\m_meta_current_variable
541     \meta_mpvar_default
542   \orelse\ifchkdim\m_meta_current_variable\or
543     \todimension\m_meta_current_variable\space\space
544 % \orelse\ifchknum\m_meta_current_variable\or % we need to catch 1>2
545   \orunless\ifempty{\ifchknum\m_meta_current_variable\or\tointeger\m_meta_current_variable\fi}%
546     \tointeger\m_meta_current_variable\space\space
547   \orelse\ifcsname\??colorattribute\currentcolorprefix\m_meta_current_variable\endcsname
548     \MPcolor\m_meta_current_variable\space
549   \orelse\ifcsname\??colorattribute\m_meta_current_variable\endcsname
550     \MPcolor\m_meta_current_variable\space
551   \else
552     \m_meta_current_variable
553   \fi}
554
555\aliased\let\MPvariable\MPvar
556
557%D \macros
558%D   {startuniqueMPgraphic, uniqueMPgraphic}
559%D
560%D This macros is probably of most use to myself, since I like to use graphics that
561%D adapt themselves. The next \METAPOST\ kind of graphic is both unique and reused
562%D when possible.
563%D
564%D \starttyping
565%D \defineoverlay[example][\uniqueMPgraphic{test}]
566%D
567%D \startuniqueMPgraphic {test}
568%D   draw OverlayBox ;
569%D \stopuniqueMPgraphic
570%D
571%D \startuniqueMPgraphic {test}
572%D   draw OverlayBox ;
573%D \stopuniqueMPgraphic
574%D \stoptyping
575
576% todo: frozen or not?
577
578\permanent\def\overlaystamp % watch the \MPcolor, since colors can be redefined
579  {\the\d_overlay_width    :%
580   \the\d_overlay_height   :%
581   \the\d_overlay_depth    :%
582   \the\d_overlay_offset   :%
583   \the\d_overlay_linewidth:%
584   \MPcolor\overlaycolor   :%  % todo, expand once \m_overlaycolor
585   \MPcolor\overlaylinecolor}  % todo, expand once \m_overlaylinecolor
586
587%D A better approach is to let additional variables play a role in determining the
588%D uniqueness. In the next macro, the second, optional, argument is used to
589%D guarantee the uniqueness, as well as prepare variables for passing them to
590%D \METAPOST.
591%D
592%D \starttyping
593%D \startuniqueMPgraphic{meta:hash}{gap,angle,...}
594%D \stoptyping
595%D
596%D The calling macro also accepts a second argument. For convenient use in overlay
597%D definitions, we use \type {{}} instead of \type {[]}.
598%D
599%D \starttyping
600%D \uniqueMPgraphic{meta:hash}{gap=10pt,angle=30}
601%D \stoptyping
602
603\newinteger\c_meta_object_counter
604\newbox    \b_meta_graphic
605
606% hm, isn't this already done elsewhere?
607
608\protected\def\meta_obey_box_depth
609  {\setbox\b_meta_graphic\hpack\bgroup
610     \raise\MPlly\box\b_meta_graphic
611   \egroup}
612
613\protected\def\meta_ignore_box_depth
614  {\normalexpanded
615     {\meta_obey_box_depth % hence the \protected
616      \wd\b_meta_graphic\the\wd\b_meta_graphic
617      \ht\b_meta_graphic\the\ht\b_meta_graphic
618      \dp\b_meta_graphic\the\dp\b_meta_graphic}}
619
620\protected\def\meta_obey_box_origin
621  {\setbox\b_meta_graphic\hpack\bgroup
622     \kern\MPllx\raise\MPlly\box\b_meta_graphic
623   \egroup}
624
625\permanent\protected\def\obeyMPboxdepth  {\let\meta_relocate_box\meta_obey_box_depth}
626\permanent\protected\def\ignoreMPboxdepth{\let\meta_relocate_box\meta_ignore_box_depth}
627\permanent\protected\def\obeyMPboxorigin {\let\meta_relocate_box\meta_obey_box_origin}
628\permanent\protected\def\normalMPboxdepth{\let\meta_relocate_box\relax}
629
630\let\meta_relocate_box\relax
631
632\protected\def\meta_place_graphic % the converter also displaces so in fact we revert
633  {\meta_relocate_box
634   \box\b_meta_graphic}
635
636% \protected\def\meta_reuse_box#1#2#3#4#5% space delimiting would save some tokens
637%   {\MPllx#2\MPlly#3\MPurx#4\MPury#5%
638%    \hpack container{\forcecolorhack\getobject{MP}{#1}}} % else no proper color intent
639
640\protected\def\meta_reuse_box#1#2#3#4#5% space delimiting would save some tokens
641  {\MPllx#2\MPlly#3\MPurx#4\MPury#5%
642   \hpack container{\getobject{MP}{#1}}}
643
644\protected\def\meta_use_box
645  {\setunreferencedobject{MP}}
646
647\def\meta_handle_unique_graphic#1#2#3% when there are too many, we can store data at the lua end, although,
648  {\begingroup                       % when there are that many they're probably not that unique anyway
649 % \currentmpcategory already set
650   \extendMPoverlaystamp{#2}% incl prepare (maybe move to lua)
651   \ifcsname\??mpgraphic\overlaystamp:#1\endcsname % todo: is now per instance !
652     \lastnamedcs
653   \else
654     \meta_enable_include % redundant
655     \global\advanceby\c_meta_object_counter\plusone
656     \meta_use_box{\the\c_meta_object_counter}\hpack{\meta_process_graphic{#3}}% was vbox, graphic must end up as hbox
657     \xdefcsname\??mpgraphic\overlaystamp:#1\endcsname{\meta_reuse_box{\the\c_meta_object_counter}{\the\MPllx}{\the\MPlly}{\the\MPurx}{\the\MPury}}%
658     \csname\??mpgraphic\overlaystamp:#1\endcsname\empty
659   \fi
660   \endgroup}
661
662% todo: we partially expand
663
664\permanent\protected\def\startuniqueMPgraphic
665  {\dodoublegroupempty\meta_start_unique_graphic}
666
667\permanent\protected\lettonothing\stopuniqueMPgraphic
668
669\def\meta_start_unique_graphic#1%
670  {\normalexpanded{\meta_start_unique_graphic_indeed{#1}}}
671
672\permanent\protected\def\meta_start_unique_graphic_indeed#1#2#3\stopuniqueMPgraphic
673  {\gdefcsname\??mpgraphic#1\endcsname{\meta_handle_unique_graphic{#1}{#2}{#3}}}
674
675% \permanent\tolerant\protected\def\uniqueMPgraphic#=#*#=%
676%   {\meta_begin_graphic_group{#1}%
677%    \checkmpcategoryparent
678%    \let\currentmpcategory\currentMPgraphicname
679%    \setupcurrentmpcategory[#2]%
680%    \begincsname\??mpgraphic#1\endcsname\empty
681%    \meta_end_graphic_group}
682
683\permanent\tolerant\protected\def\uniqueMPgraphic
684  {\futureexpandis[\meta_uniquempgraphic_yes\meta_uniquempgraphic_nop}
685
686\def\meta_uniquempgraphic_yes[#1]#*#=%
687  {% ugly code but we run on top of older code
688   \resetdummyparameter\c!instance
689   \getdummyparameters[#1]%
690   \cdef\currentMPinstance{\dummyparameter\c!instance}%
691   % here we feed the instance into the analyzer
692   \meta_begin_graphic_group{\ifempty\currentMPinstance\else\currentMPinstance::\fi#1}%
693   \checkmpcategoryparent
694   \let\currentmpcategory\currentMPgraphicname
695   \setupcurrentmpcategory[#1]%
696   \begincsname\??mpgraphic#2\endcsname\empty
697   \meta_end_graphic_group}
698
699\tolerant\def\meta_uniquempgraphic_nop#=#*#=%
700  {\meta_begin_graphic_group{#1}%
701   \checkmpcategoryparent
702   \let\currentmpcategory\currentMPgraphicname
703   \setupcurrentmpcategory[#2]%
704   \begincsname\??mpgraphic#1\endcsname\empty
705   \meta_end_graphic_group}
706
707\def\meta_handle_use_graphic#1#2#3%
708  {\begingroup
709 % \currentmpcategory already set
710   \meta_enable_include % redundant
711   \meta_process_graphic{#3}%
712   \endgroup}
713
714\permanent\protected\def\startuseMPgraphic
715  {\dodoublegroupempty\meta_start_use_graphic}
716
717\permanent\protected\lettonothing\stopuseMPgraphic
718
719\def\meta_start_use_graphic#1%
720  {\normalexpanded{\meta_start_use_graphic_indeed{#1}}}
721
722\protected\def\meta_start_use_graphic_indeed#1#2#3\stopuseMPgraphic
723  {\gdefcsname\??mpgraphic#1\endcsname{\meta_handle_use_graphic{#1}{#2}{#3}}}
724
725\permanent\protected\def\startusableMPgraphic
726  {\dodoublegroupempty\meta_start_usable_graphic}
727
728\permanent\protected\lettonothing\stopusableMPgraphic
729
730\def\meta_start_usable_graphic#1%
731  {\normalexpanded{\meta_start_usable_graphic_indeed{#1}}}
732
733\protected\def\meta_start_usable_graphic_indeed#1#2#3\stopusableMPgraphic
734  {\gdefcsname\??mpgraphic#1\endcsname{\meta_handle_use_graphic{#1}{#2}{#3}}}
735
736\def\meta_handle_reusable_graphic#1#2#3%
737  {\begingroup
738 % \currentmpcategory already set
739   \meta_enable_include % redundant
740   \global\advanceby\c_meta_object_counter\plusone
741   \meta_use_box{\the\c_meta_object_counter}\hpack{\meta_process_graphic{#3}}% was vbox, graphic must end up as hbox
742   \xdefcsname\??mpgraphic#1\endcsname{\meta_reuse_box{\the\c_meta_object_counter}{\the\MPllx}{\the\MPlly}{\the\MPurx}{\the\MPury}}%
743   \csname\??mpgraphic#1\endcsname\empty
744   \endgroup}
745
746\permanent\protected\def\startreusableMPgraphic
747  {\dodoublegroupempty\meta_start_reusable_graphic}
748
749\permanent\protected\lettonothing\stopreusableMPgraphic
750
751\def\meta_start_reusable_graphic#1%
752  {\normalexpanded{\meta_start_reusable_graphic_indeed{#1}}}
753
754\protected\def\meta_start_reusable_graphic_indeed#1#2#3\stopreusableMPgraphic
755  {\gdefcsname\??mpgraphic#1\endcsname{\meta_handle_reusable_graphic{#1}{#2}{#3}}}
756
757\permanent\tolerant\protected\def\useMPgraphic
758  {\futureexpandis[\meta_usempgraphic_yes\meta_usempgraphic_nop}
759
760\def\meta_usempgraphic_yes[#1]#*#=%
761  {% ugly code but we run on top of older code
762   \resetdummyparameter\c!instance
763   \getdummyparameters[#1]%
764   \cdef\currentMPinstance{\dummyparameter\c!instance}%
765   % here we feed the instance into the analyzer
766   \meta_begin_graphic_group{\ifempty\currentMPinstance\else\currentMPinstance::\fi#2}%
767   \ifcsname\??mpgraphic#2\endcsname
768     \cdef\currentmpcategory{#2}%
769   \orelse\ifcsname\??mpgraphic\currentMPgraphicname\endcsname
770     \let\currentmpcategory\currentMPgraphicname
771   \else
772     \lettonothing\currentmpcategory
773   \fi
774   \ifempty\currentmpcategory
775     % message
776   \else
777     \checkmpcategoryparent
778     \setupcurrentmpcategory[#1]%
779     \csname\??mpgraphic\currentmpcategory\endcsname
780   \fi
781   \meta_end_graphic_group}
782
783\tolerant\def\meta_usempgraphic_nop#=#*#=%
784  {\meta_begin_graphic_group{#1}%
785   \ifcsname\??mpgraphic#1\endcsname
786     \cdef\currentmpcategory{#1}%
787   \orelse\ifcsname\??mpgraphic\currentMPgraphicname\endcsname
788     \let\currentmpcategory\currentMPgraphicname
789   \else
790     \lettonothing\currentmpcategory
791   \fi
792   \ifempty\currentmpcategory
793     % message
794   \else
795     \checkmpcategoryparent
796     \ifempty{#2}\else
797       \setupcurrentmpcategory[#2]%
798     \fi
799     \csname\??mpgraphic\currentmpcategory\endcsname
800   \fi
801   \meta_end_graphic_group}
802
803\aliased\let\reuseMPgraphic   \useMPgraphic   % we can save a setup here if needed
804\aliased\let\reusableMPgraphic\reuseMPgraphic % we can save a setup here if needed
805
806%D Saves an overlaydefinition:
807
808\permanent\protected\def\startoverlayMPgraphic
809  {\dodoublegroupempty\meta_start_overlay_graphic}
810
811\permanent\protected\lettonothing\stopoverlayMPgraphic
812
813\def\meta_start_overlay_graphic#1%
814  {\normalexpanded{%
815     \pack_overlay_define{#1}{\useMPgraphic{#1}}%
816     \meta_start_overlay_graphic_indeed{#1}}%
817   }
818
819\protected\def\meta_start_overlay_graphic_indeed#1#2#3\stopoverlayMPgraphic
820  {\gdefcsname\??mpgraphic#1\endcsname{\meta_handle_overlay_graphic{#1}{#2}{#3}}}
821
822\def\meta_handle_overlay_graphic#1#2#3%
823  {\begingroup
824   \cdef\currentmpcategory{#1}%
825   \meta_process_graphic{#3;BoundToOverlayBox;}%
826   \endgroup}
827
828%D New in \LMTX:
829
830\newtoks\MPoverlaydata
831
832\permanent\protected\lettonothing\stopMPoverlaydata
833
834\permanent\protected\def\startMPoverlaydata
835  {\iftrialtypesetting
836     \expandafter\startMPoverlaydata_nop
837   \else
838     \expandafter\startMPoverlaydata_yes
839   \fi}
840
841\permanent\protected\def\startMPoverlaydata_nop#-\stopMPoverlaydata
842  {}
843
844\permanent\protected\def\startMPoverlaydata_yes#1\stopMPoverlaydata
845  {\xtoksapp\MPoverlaydata{#1;}}
846
847\def\includeMPoverlaydata % expandable
848  {\the\MPoverlaydata
849   \resetMPoverlaydata}
850
851\def\resetMPoverlaydata % expandable
852  {\localcontrolled{\global\MPoverlaydata\emptytoks}}
853
854
855%D \macros
856%D   {startuniqueMPpagegraphic,uniqueMPpagegraphic}
857%D
858%D Experimental.
859
860\def\m_meta_page_prefix{\doifelseoddpage oe}
861
862\permanent\def\overlaypagestamp
863  {\m_meta_page_prefix     :%
864   \the\d_overlay_width    :%
865   \the\d_overlay_height   :%
866   \the\d_overlay_depth    :%
867   \the\d_overlay_offset   :%
868   \the\d_overlay_linewidth:%
869   \MPcolor\overlaycolor   :%
870   \MPcolor\overlaylinecolor}
871
872\permanent\tolerant\protected\def\startuniqueMPpagegraphic % todo the modern way
873  {\dodoublegroupempty\meta_start_unique_page_graphic}
874
875\permanent\protected\lettonothing\stopuniqueMPpagegraphic
876
877\def\meta_start_unique_page_graphic#1%
878  {\normalexpanded{\meta_start_unique_page_graphic_indeed{#1}}}
879
880\protected\def\meta_start_unique_page_graphic_indeed#1#2#3\stopuniqueMPpagegraphic    % inefficient, double storage
881  {\gdefcsname\??mpgraphic o:#1\endcsname{\meta_handle_unique_graphic{o:#1}{#2}{#3}}% % but these also keep the state
882   \gdefcsname\??mpgraphic e:#1\endcsname{\meta_handle_unique_graphic{e:#1}{#2}{#3}}} % and meaning will be redefined
883
884\permanent\tolerant\protected\def\uniqueMPpagegraphic#=#=%
885  {\meta_begin_graphic_group{#1}%
886   \enforced\let\overlaystamp\overlaypagestamp
887   \setupmpcategory[\m_meta_page_prefix:#1][#2]% prefix is new here
888   \csname\??mpgraphic\m_meta_page_prefix:#1\endcsname\empty
889   \meta_end_graphic_group}
890
891\permanent\protected\def\extendMPoverlaystamp#1%
892  {\processcommalist[#1]\meta_extend_overlay_stamp}
893
894\def\meta_extend_overlay_stamp#1%
895  {\enforced\permanent\edef\overlaystamp{\overlaystamp:\MPvariable{#1}}}
896
897% \getMPdata % define at the lua end
898% \rawMPdata % define at the lua end
899
900%D We need this trick because we need to make sure that the tex scanner sees
901%D newlines and does not quit. Also, we do need to flush the buffer under a normal
902%D catcode regime in order to expand embedded tex macros. As usual with buffers,
903%D \type {#1} can be a list.
904
905\permanent\tolerant\protected\def\processMPbuffer[#1]%
906  {\meta_begin_graphic_group{#1}%
907   \meta_process_graphic{\clf_feedback{\currentMPgraphicname}}%
908   \meta_end_graphic_group}
909
910\permanent\tolerant\protected\def\runMPbuffer[#1]%
911  {\startnointerference\processMPbuffer[#1]\stopnointerference}
912
913%D \macros
914%D   {startMPenvironment, resetMPenvironment}
915%D
916%D In order to synchronize the main \TEX\ run and the runs local to \METAPOST,
917%D environments can be passed.
918
919\permanent\protected\def\startMPenvironment
920  {\begingroup
921   \catcode\endoflineasciicode\ignorecatcode
922   \meta_start_environment}
923
924\tolerant\def\meta_start_environment[#1]#:#2\stopMPenvironment
925  {\endgroup
926   \edef\m_meta_option{#1}
927   \ifx\m_meta_option\s!reset
928     \resetMPenvironment % reset mp toks
929   \orelse\ifx\m_meta_option\v!global
930     #2%                 % use in main doc too
931   \orelse\ifx\m_meta_option\!!plustoken
932     #2%                 % use in main doc too
933   \fi
934   \clf_mptexset{\detokenize{#2}}}
935
936\permanent\protected\lettonothing\stopMPenvironment
937
938\permanent\protected\def\resetMPenvironment
939  {\clf_mptexreset}
940
941\permanent\protected\def\useMPenvironmentbuffer[#1]%
942  {\clf_mptexsetfrombuffer{#1}}
943
944%D This command takes \type {[reset]} as optional argument.
945%D
946%D \starttyping
947%D \startMPenvironment
948%D   \setupbodyfont[pos,14.4pt]
949%D \stopMPenvironment
950%D
951%D \startMPcode
952%D   draw btex \sl Hans Hagen etex scaled 5 ;
953%D \stopMPcode
954%D \stoptyping
955%D
956%D The most simple case:
957
958% \permanent\tolerant\protected\def\startMPcode#=#:#2\stopMPcode
959%   {\begingroup
960%    \cdef\currentMPinstance{#1}%
961%    \ifempty\currentMPinstance
962%      \let\currentMPinstance\defaultMPinstance
963%    \fi
964%    \lettonothing\currentMPgraphicname
965%    \cdef\currentMPformat{\MPinstanceparameter\s!format}%
966%    \meta_enable_include
967%    \meta_process_graphic{#2}%
968%    \endgroup}
969
970\permanent\tolerant\protected\def\startMPcode
971  {\futureexpandis[\meta_start_mpcode_yes\meta_start_mpcode_nop}
972
973\tolerant\def\meta_start_mpcode_nop#:#=#:#2\stopMPcode
974  {\begingroup
975   \cdef\currentMPinstance{#1}%
976   \ifempty\currentMPinstance
977     \let\currentMPinstance\defaultMPinstance
978   \fi
979   \lettonothing\currentMPgraphicname
980   \cdef\currentMPformat{\MPinstanceparameter\s!format}%
981   \meta_enable_include
982   \meta_process_graphic{#2}%
983   \endgroup}
984
985\def\meta_start_mpcode_yes[#1]#2\stopMPcode
986  {\begingroup
987   \resetdummyparameter\c!instance
988   \resetdummyparameter\c!stacking
989   \getdummyparameters[#1]%
990   \cdef\currentMPinstance{\dummyparameter\c!instance}%
991   \setmpcategoryparameter\c!stacking{\dummyparameter\c!stacking}%
992   \ifempty\currentMPinstance
993     \let\currentMPinstance\defaultMPinstance
994   \fi
995   \lettonothing\currentMPgraphicname
996   \cdef\currentMPformat{\MPinstanceparameter\s!format}%
997   \meta_enable_include
998   \meta_process_graphic{#2}%
999   \endgroup}
1000
1001\permanent\protected\lettonothing\stopMPcode
1002
1003%D This one is not optimized because it's only used for small snippets, if it
1004%D is used at all.
1005%D
1006%D \starttyping
1007%D test \MPcode {draw unitcircle scaled 1.5ExHeight} test test \MPcode [doublefun]
1008%D {draw unitcircle scaled 3mm shifted (0,-1mm)} test
1009%D \stoptyping
1010
1011\permanent\tolerant\protected\def\MPcode[#1]#:#2%
1012  {\dontleavehmode
1013   \begingroup
1014   \obeyMPboxdepth
1015   \ifparameter#1\or
1016     \meta_begin_graphic_group{#1}%
1017     \meta_enable_include
1018     \meta_process_graphic{#2}%
1019     \meta_end_graphic_group
1020   \else
1021     \let\currentMPinstance\defaultMPinstance
1022     \meta_enable_include
1023     \meta_process_graphic{#2}%
1024   \fi
1025   \endgroup}
1026
1027% a bit nasty (also needed for compatibility:
1028
1029% \startMPrun input mp-www.mp ; \stopMPrun
1030% \externalfigure[mprun.3][width=10cm,height=8cm]
1031
1032% \startMPrun{mprun} input mp-www.mp ; \stopMPrun % instance
1033% \externalfigure[mprun.4][width=10cm,height=8cm]
1034
1035\mutable\let\MPruninstance\defaultMPinstance
1036
1037\permanent\protected\def\useMPrun#1#2% name n
1038  {\begingroup
1039   \def\MPaskedfigure{#2}%
1040   \normalexpanded{\useMPgraphic{\ifempty{#1}mprun\else#1\fi}}%
1041   \endgroup}
1042
1043\permanent\tolerant\protected\def\startMPrun#=#:#2\stopMPrun
1044  {\normalexpanded{\startuseMPgraphic{\ifempty{#1}mprun\else#1\fi}}#2\stopuseMPgraphic}
1045
1046\permanent\protected\lettonothing\stopMPrun
1047
1048%D The \type {\resetMPenvironment} is a quick way to erase the token list. You
1049%D should be aware of independencies. For instance, if you use a font in a graphic
1050%D that is not used in the main document, you need to load the typescript at the
1051%D outer level (either directly or by using the global option).
1052%D
1053%D \starttyping
1054%D \usetypescript[palatino][texnansi]
1055%D
1056%D \startMPenvironment
1057%D     \usetypescript[palatino][texnansi]
1058%D     \enableregime[utf]
1059%D     \setupbodyfont[palatino]
1060%D \stopMPenvironment
1061%D
1062%D \startMPpage
1063%D     draw btex aap‒noot coördinatie – één etex ;
1064%D \stopMPpage
1065%D \stoptyping
1066
1067%D Loading specific \METAPOST\ related definitions is accomplished by:
1068
1069\permanent\protected\def\useMPlibrary[#1]{\clf_useMPlibrary{#1}}
1070
1071%D \macros
1072%D   {setMPtext, MPtext, MPstring, MPbetex}
1073%D
1074%D To be documented:
1075%D
1076%D \starttyping
1077%D \setMPtext{identifier}{text}
1078%D
1079%D \MPtext  {identifier}
1080%D \MPstring{identifier}
1081%D \MPbetex {identifier}
1082%D \stoptyping
1083
1084\installcorenamespace{mptext}
1085
1086\permanent\protected\def\setMPtext#1#2{\edefcsname\??mptext#1\endcsname{\detokenize{#2}}} % \global will work here
1087\permanent          \def\MPtext     #1{\begincsname\??mptext#1\endcsname\empty}
1088\permanent          \def\MPstring   #1{"\begincsname\??mptext#1\endcsname\empty"}
1089\permanent          \def\MPbetex    #1{btex \begincsname\??mptext#1\endcsname\space etex}
1090
1091%D In order to communicate conveniently with the \TEX\ engine, we introduce some
1092%D typesetting variables.
1093
1094% \setupcolors[state=stop,conversion=never] % quite tricky ... type mismatch
1095
1096% \startMPinitializations
1097%     CurrentLayout:="\currentlayout";
1098% \stopMPinitializations
1099
1100%D A dirty trick, ** in colo-ini.lua (mpcolor). We cannot use a vardef, because
1101%D that fails with spot colors.
1102
1103% \startMPinitializations
1104%     def OverlayLineColor=\ifempty\overlaylinecolor black \else\MPcolor{\overlaylinecolor} \fi enddef;
1105%     def OverlayColor    =\ifempty\overlaycolor     black \else\MPcolor{\overlaycolor}     \fi enddef;
1106% \stopMPinitializations
1107
1108\appendtoks
1109    \disablediscretionaries
1110   %\disablecompoundcharacters
1111    %
1112    \baselineskip1\baselineskip
1113    \lineheight  1\lineheight
1114    \topskip     1\topskip
1115    %
1116    \enforced\let\#\letterhash
1117    \enforced\let\_\letterunderscore
1118    \enforced\let\&\letterampersand
1119    \enforced\let\{\letteropenbrace
1120    \enforced\let\}\letterclosebrace
1121\to \everyMPgraphic
1122
1123\newtoks\everyinsertMPfile
1124
1125\startMPextensions
1126    def initialize_form_numbers =
1127        do_initialize_numbers;
1128    enddef;
1129\stopMPextensions
1130
1131\startMPextensions
1132    vardef ForegroundBox =
1133        unitsquare xysized(HSize,VSize)
1134    enddef ;
1135\stopMPextensions
1136
1137\startMPdefinitions {metapost}
1138    if unknown context_bare : input mp-bare.mpiv ; fi ;
1139\stopMPdefinitions
1140\startMPdefinitions {binarypost}
1141    if unknown context_bare : input mp-bare.mpiv ; fi ;
1142\stopMPdefinitions
1143\startMPdefinitions {decimalpost}
1144    if unknown context_bare : input mp-bare.mpiv ; fi ;
1145\stopMPdefinitions
1146\startMPdefinitions {doublepost}
1147    if unknown context_bare : input mp-bare.mpiv ; fi ;
1148\stopMPdefinitions
1149
1150% \startMPdefinitions {nofun}
1151%     if unknown context_bare : input mp-bare.mpiv ; fi ;
1152% \stopMPdefinitions
1153
1154%D And some more. These are not really needed since we don't use the normal figure
1155%D inclusion macros any longer.
1156
1157\appendtoks
1158    \externalfigurepostprocessors\emptytoks % safeguard
1159\to \everyinsertMPfile
1160
1161%D We also take care of disabling fancy figure features, that can terribly interfere
1162%D when dealing with symbols, background graphics and running (postponed) graphics.
1163%D You won't believe me if I tell you what funny side effects can occur. One took me
1164%D over a day to uncover when processing the screen version of the \METAFUN\ manual.
1165
1166\permanent\def\doifelseMPgraphic#1%
1167  {\ifcsname\??mpgraphic   #1\endcsname\expandafter\firstoftwoarguments \orelse
1168   \ifcsname\??mpgraphic o:#1\endcsname\expandafter\firstoftwoarguments \orelse
1169   \ifcsname\??mpgraphic e:#1\endcsname\expandafter\firstoftwoarguments \else
1170                                       \expandafter\secondoftwoarguments\fi}
1171
1172\aliased\let\doifMPgraphicelse\doifelseMPgraphic
1173
1174%D New:
1175
1176\definelayerpreset % no dx,dy - else nasty non-mp placement
1177  [mp]
1178  [\c!y=-\MPury,
1179   \c!x=\MPllx,
1180   \c!method=\v!fit]
1181
1182\definelayer
1183  [mp]
1184  [\c!preset=mp]
1185
1186%D Usage:
1187%D
1188%D \starttyping
1189%D \defineviewerlayer[one][state=start]
1190%D \defineviewerlayer[two][state=stop]
1191%D
1192%D \startuseMPgraphic{step-1}
1193%D   fill fullcircle scaled 10cm withcolor red ;
1194%D \stopuseMPgraphic
1195%D
1196%D \startuseMPgraphic{step-2}
1197%D   fill fullcircle scaled 5cm withcolor green ;
1198%D \stopuseMPgraphic
1199%D
1200%D \setlayer[mp]{\viewerlayer[one]{\useMPgraphic{step-1}}}
1201%D \setlayer[mp]{\viewerlayer[two]{\useMPgraphic{step-2}}}
1202%D
1203%D \ruledhbox{\flushlayer[mp]}
1204%D \stoptyping
1205%D
1206%D Reusing graphics is also possible (now):
1207%D
1208%D \starttyping
1209%D \startreusableMPgraphic{axis}
1210%D   tickstep := 1cm ; ticklength := 2mm ;
1211%D   drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ;
1212%D   tickstep := tickstep/2 ; ticklength := ticklength/2 ;
1213%D   drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ;
1214%D \stopreusableMPgraphic
1215%D
1216%D \startuseMPgraphic{demo}
1217%D   drawpoint "1cm,1.5cm" ;
1218%D \stopuseMPgraphic
1219%D
1220%D \definelayer[mp][preset=mp]
1221%D \setlayer[mp]{\reuseMPgraphic{axis}}
1222%D \setlayer[mp]{\useMPgraphic{demo}}
1223%D \ruledhbox{\flushlayer[mp]}
1224%D \stoptyping
1225
1226%D \macros
1227%D   {startstaticMPfigure,useMPstaticfigure}
1228%D
1229%D Static figures are processed only when there has been something changed. Here is
1230%D Aditya Mahajan's testcase:
1231%D
1232%D \startbuffer
1233%D \startstaticMPfigure{circle}
1234%D   fill fullcircle scaled 1cm withcolor blue;
1235%D \stopstaticMPfigure
1236%D
1237%D \startstaticMPfigure{axis}
1238%D   drawarrow (0,0)--(2cm,0) ;
1239%D   drawarrow (0,0)--(0,2cm) ;
1240%D   label.llft(textext("(0,0)") ,origin) ;
1241%D \stopstaticMPfigure
1242%D \stopbuffer
1243%D
1244%D \typebuffer \getbuffer
1245
1246\permanent\protected\def\startstaticMPfigure#1#2\stopstaticMPfigure
1247  {\startreusableMPgraphic{\??mpstaticgraphic#1}#2\stopreusableMPgraphic}
1248
1249\permanent\tolerant\protected\def\startstaticMPgraphic#=#:#=#:#3\stopstaticMPgraphic
1250  {\startreusableMPgraphic{\??mpstaticgraphic#1}{#2}#3\stopreusableMPgraphic}
1251
1252\permanent\protected\lettonothing\stopstaticMPfigure
1253\permanent\protected\lettonothing\stopstaticMPgraphic
1254
1255\permanent\tolerant\protected\def\usestaticMPfigure[#1]#*[#2]%
1256  {\ifarguments\or
1257     \reuseMPgraphic{\??mpstaticgraphic#1}%
1258   \else
1259     \scale[#2]{\reuseMPgraphic{\??mpstaticgraphic#1}}%
1260   \fi}
1261
1262%D Goody for preventing overflows:
1263
1264%   frozen\def\MPdivten[#1]{\toscaled\dimexpr#1pt/10\relax}
1265\permanent\def\MPdivten[#1]{\toscaled\dimexpr#1pt/10\relax}
1266
1267%D There is no way to distinguish the black color that you get when you issue a
1268%D \type {draw} without color specification from a color that has an explicit black
1269%D specification unless you set the variable \type {defaultcolormodel} to 1.
1270%D Hoewever, in that case you cannot distinguish that draw from one with a \type
1271%D {withoutcolor} specification. This means that we have to provide multiple
1272%D variants of inheritance.
1273%D
1274%D In any case we need to tell the converter what the inherited color is to start
1275%D with. Case~3 is kind of unpredictable as it closely relates to the order in which
1276%D paths are flushed. If you want to inherit automatically from the surrounding, you
1277%D can best stick to variant 1. Variant 0 (an isolated graphic) is the default.
1278%D
1279%D \startbuffer
1280%D \startuseMPgraphic{test}
1281%D     drawoptions(withpen pencircle scaled 1pt) ;
1282%D     def shift_cp = currentpicture := currentpicture shifted (-15pt,0) ; enddef ;
1283%D     draw fullcircle scaled 10pt withoutcolor  ; shift_cp ;
1284%D     fill fullcircle scaled 10pt               ; shift_cp ;
1285%D     draw fullcircle scaled 10pt withoutcolor  ; shift_cp ;
1286%D     fill fullcircle scaled 10pt withcolor red ; shift_cp ;
1287%D     draw fullcircle scaled 10pt withoutcolor  ; shift_cp ;
1288%D     fill fullcircle scaled 10pt               ; shift_cp ;
1289%D \stopuseMPgraphic
1290%D
1291%D \starttabulate
1292%D \NC 0\quad \NC \MPcolormethod0 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR
1293%D \NC 1\quad \NC \MPcolormethod1 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR
1294%D \NC 2\quad \NC \MPcolormethod2 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR
1295%D \NC 3\quad \NC \MPcolormethod3 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR
1296%D \stoptabulate
1297%D \stopbuffer
1298%D
1299%D \typebuffer \getbuffer
1300
1301\newconstant\MPcolormethod
1302
1303\appendtoks
1304    \clf_mpsetoutercolor
1305        \MPcolormethod\space
1306        \c_attr_colormodel\space
1307        \c_attr_color\space
1308        \dogetattribute{transparency}\relax
1309\to \everyMPgraphic
1310
1311% \startMPinitializations
1312%     defaultcolormodel := \ifcase\MPcolormethod1\or1\or3\else3\fi;
1313% \stopMPinitializations
1314
1315%D macros
1316%D  {mprunvar,mpruntab,mprunset}
1317%D
1318%D \starttyping
1319%D \startMPcode
1320%D     passvariable("version","1.0") ;
1321%D     passvariable("number",123) ;
1322%D     passvariable("string","whatever") ;
1323%D     passvariable("point",(1.5,2.8)) ;
1324%D     passvariable("triplet",(1/1,1/2,1/3)) ;
1325%D     passvariable("quad",(1.1,2.2,3.3,4.4)) ;
1326%D     passvariable("boolean",false) ;
1327%D     passvariable("path",fullcircle scaled 1cm) ;
1328%D     draw fullcircle scaled 20pt ;
1329%D \stopMPcode
1330%D
1331%D \ctxlua{inspect(metapost.variables)}
1332%D
1333%D \MPrunvar{version} \MPruntab{quad}{3} (\MPrunset{triplet}{,})
1334%D
1335%D $(x,y) = (\MPruntab{point}{1},\MPruntab{point}{2})$
1336%D $(x,y) = (\MPrunset{point}{,})$
1337%D \stoptyping
1338
1339\permanent\def\MPrunvar  #1{\clf_mprunvar{#1}}         \aliased\let\mprunvar\MPrunvar
1340\permanent\def\MPruntab#1#2{\clf_mpruntab{#1}#2\relax} \aliased\let\mpruntab\MPruntab % #2 is number
1341\permanent\def\MPrunset#1#2{\clf_mprunset{#1}{#2}}     \aliased\let\mprunset\MPrunset
1342
1343% \prependtoks \clf_mppushvariables \to \everybeforepagebody
1344% \appendtoks  \clf_mppopvariables  \to \everyafterpagebody
1345
1346\tokspre\everybeforepagebody{\clf_mppushvariables}
1347\toksapp\everyafterpagebody {\clf_mppopvariables }
1348
1349\aliased\let\MPpushvariables\clf_mppushvariables
1350\aliased\let\MPpopvariables \clf_mppopvariables
1351
1352%D We also provide an outputless run:
1353
1354\permanent\tolerant\protected\def\startMPcalculation#=#:#2\stopMPcalculation
1355  {\begingroup
1356   \setbox\nextbox\hpack\bgroup
1357   \cdef\currentMPinstance{#1}%
1358   \ifempty\currentMPinstance
1359     \let\currentMPinstance\defaultMPinstance
1360   \fi
1361   \lettonothing\currentMPgraphicname
1362   \cdef\currentMPformat{\MPinstanceparameter\s!format}%
1363   \meta_enable_include
1364   \meta_process_graphic{#2;draw origin}%
1365   \egroup
1366   \endgroup}
1367
1368\permanent\protected\lettonothing\stopMPcalculation
1369
1370%D \macros
1371%D   {setupMPgraphics}
1372%D
1373%D Here is a generic setup command:
1374
1375\installcorenamespace{MPgraphics}
1376
1377\installsetuponlycommandhandler \??MPgraphics {MPgraphics}
1378
1379%D Here we hook in the outer color. When \type {color} is set to \type {global} we
1380%D get the outer color automatically. If you change this setting, you should do it
1381%D grouped in order not to make other graphics behave in unexpected ways.
1382
1383\appendtoks
1384    \MPcolormethod\ifcstok{\directMPgraphicsparameter\c!color}\v!global\plusone\else\zerocount\fi
1385\to \everysetupMPgraphics
1386
1387\setupMPgraphics
1388  [\c!color=\v!local]
1389
1390%D Some more helpers (see \type {meta-grd.mkiv} for an example of usage):
1391
1392\permanent\def\MPdpar#1#2{\the\dimexpr#1#2\relax\empty} % why \empty here
1393\permanent\def\MPnpar#1#2{\the\numexpr#1#2\relax\empty} % why \empty here
1394\permanent\def\MPspar#1#2{"#1#2"}
1395
1396%D Done.
1397
1398\protect \endinput
1399