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