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