mag-1104-mkiv.tex /size: 22 Kb    last modification: 2023-12-21 09:43
1% author    : Hans Hagen
2% copyright : ConTeXt Development Team
3% license   : Creative Commons Attribution ShareAlike 4.0 International
4% reference : pragma-ade.nl | contextgarden.net | texlive (related) distributions
5% origin    : the ConTeXt distribution
6%
7% comment   : Because this manual is distributed with TeX distributions it comes with a rather
8%             liberal license. We try to adapt these documents to upgrades in the (sub)systems
9%             that they describe. Using parts of the content otherwise can therefore conflict
10%             with existing functionality and we cannot be held responsible for that. Many of
11%             the manuals contain characteristic graphics and personal notes or examples that
12%             make no sense when used out-of-context.
13
14\usemodule[magazine-basic,abr-02]
15
16\usemodule[scite]
17
18\startbuffer[abstract]
19    As part of the \CONTEXT\ \LMTX\ project, we experiment with new ways to
20    interface subsystems and \METAPOST\ makes a good candidate. Here I wrap up some
21    experiments. It's not a manual or a recipe, just food for thought. All you see
22    here might change and|/|or evolve.
23\stopbuffer
24
25\setuplayout
26  [backspace=20mm,
27   topspace=10mm]
28
29\startdocument
30  [title={New interfacing in \METAFUN, a preview},
31   author={Hans Hagen & Alan Braslau},
32  %affiliation=PRAGMA ADE,
33   date=July 2019,
34   number=1104 LMTX]
35
36As we move to \CONTEXT\ \LMTX, some decisions need to be made. For instance, how
37shall we introduce new functionality while not affecting the \MKIV\ code base too
38much with engine related tests, messy and performance sapping. Of course we
39remain downward compatible but the \LUAMETATEX\ engine sometimes permits multiple
40solutions. As this is something new, for a while we can use experimental features
41that may change or later disappear depending on experience. It is not a big deal
42to adapt to these new possibilites and users shouldn't notice, unless of course
43they currently employ (yet undocumented) low|-|level features. Part of the
44solution is to have separate files for \MKIV\ and \LMTX, although that will
45mostly concern low level support modules; even then differences will be subtle
46and should not affect users. I must admit that some of those changes are mostly
47aesthetic and often don't improve performance, although better performance
48sometimes may be the case, in particular concerning \quote {extreme} usage.
49
50But, that said, there are areas where \LMTX\ will offer entirely new
51functionality. One of the areas where we are making interesting developments is
52in \METAFUN, which means \METAPOST. Now, it is not to be said that some of the
53core functionality needed for this will migrate from \LUAMETATEX\ (used by \LMTX)
54to \LUATEX\ (used by \MKIV). But, because (due to external pressure), the later
55engine is now considered stable and its functionality frozen, it is not likely to
56be quickly backported or at least only will happen when this has been throughly
57tested in \CONTEXT|/|\LMTX.
58
59Over the years there have been (small) improvements in the interface but while
60Alan Braslau and I experiment with new graphic abilities, we also are coming up
61with (graphic) interfaces that suit \CONTEXT\ much better. Below, I will show
62some examples. \footnote {These optional argument handlers themselves are
63\emphasize {not} part of \METAPOST\ but implemented in \CONTEXT\ using some
64experimental parsing related extensions to a version of \MPLIB\ used in
65\LUAMETATEX.}
66
67\startbuffer
68\startMPcode{doublefun}
69    draw lmt_grid [
70        nx =  20, ny =  10,
71        dx =   5, dy =   2,
72        tx =  10, ty =  10,
73    ] ysized 5cm withpen pencircle scaled 1mm withcolor "red" ;
74\stopMPcode
75\stopbuffer
76
77\typebuffer[option=TEX]
78
79\startlinecorrection
80\getbuffer
81\stoplinecorrection
82
83What we see here is an key|/|value driven interface that has been one of the
84unique core properties of \CONTEXT\ since it was created. \footnote {Note the use
85of the color string \type {"red"} rather then the \METAPOST\ color variable \type
86{red := (1,0,0)}. This is a small detail but here imports the color definition
87from \CONTEXT, which might be a bit special.} Of course parameters can be
88optional as demonstrated in:
89
90\startbuffer
91\startMPcode{doublefun}
92    draw lmt_grid [
93        nx =  10, ny =  10,
94        dx =   1, dy =   1
95    ] ysized 3cm
96        withpen pencircle scaled 1mm
97        withcolor "darkblue"  ;
98
99    draw lmt_grid [
100        nx = 10, ny = 10
101    ] ysized 3cm shifted (4cm,0)
102       withpen pencircle scaled .3mm
103       withcolor "darkgreen" ;
104\stopMPcode
105\stopbuffer
106
107\typebuffer[option=TEX]
108
109\startlinecorrection
110\getbuffer
111\stoplinecorrection
112
113This syntax means that we can also use the already used interface documentation
114system.
115
116We can actually go quite far in what we provide. It's not so much that these
117things were not possible before, but the more concise user interface is something
118new indeed. Let's start with drawing some simple axis:
119
120\startbuffer
121\startMPcode{doublefun}
122    draw lmt_axis [
123        nx =  20, ny =  10,
124        dx =   5, dy =   2,
125    ] ysized 4cm
126        withpen pencircle scaled 1mm
127        withcolor "darkcyan" ;
128\stopMPcode
129\stopbuffer
130
131\typebuffer[option=TEX]
132
133\startlinecorrection
134\getbuffer
135\stoplinecorrection
136
137This \quote {article} is not meant as tutorial but more as a teaser about what is
138possible and hopefully it triggers users in coming up with useful demands. As the
139previous axis example is not that interesting we move on to a more complex one:
140
141\startbuffer
142\startMPcode{doublefun}
143    draw lmt_axis [
144        sx =   5mm, sy =   5mm,
145        nx =  20,   ny =  10,
146        dx =   5,   dy =   2,
147        tx =  10,   ty =  10,
148    ] withpen pencircle scaled 1mm withcolor "darkblue" ;
149
150    draw lmt_connected (
151        for i = 1 step 2 until 20 :
152            -- (i, 1 randomized 8) * 5mm
153        endfor
154    )
155        withpen pencircle scaled 2mm withcolor "darkyellow" ;
156
157    draw lmt_connected (
158        for i = 1 step 2 until 20 :
159            lmt_connection (i, 1 randomized 8) * 5mm
160        endfor
161    )
162        withpen pencircle scaled 2mm withcolor "darkgreen" ;
163\stopMPcode
164\stopbuffer
165
166\typebuffer[option=TEX]
167
168\startlinecorrection
169\getbuffer
170\stoplinecorrection
171
172These examples are made as part of exploring how to best interface with
173\METAPOST, to be used by the upcoming luagraph module, a flexible and high
174performance set of macros aimed at drawing graphs and to visualize data. On the
175one hand, we want to free the user from dealing with details such as scales to
176get the graphics right, but on the other hand it should be possible to
177fine|-|tune when needed.
178
179Again we draw an axis. Using strings as color names, mentioned in the footnote
180earlier, is not new, but already present for a while. It will use the colors
181defined at the \TEX\ end and is more convenient and natural than using the older
182\type {\MPcolor}. The \type {lmt_connected} macro is sort of a gimmick: if you
183look closely you will see that it has to start with a point (coordinate) but that
184one is discarded silently. Again this is something we need to deal with.
185
186% This is obscure, and silly. I'm sure that we can do better. Sure, but so is the
187% HIDE related alternative trrickery. We probably need something getparameterpath.
188
189The next variant uses a list of samples. Watch the use of braces, this is
190something normally not part of \METAPOST\ syntax, and it signals a \LUA|-|like
191list. This is a choice of interfacing. There are subtle and somewhat complicated
192aspects involved here as \METAPOST\ parsing involves primaries, secondaries,
193tertiaries and expressions, symbols, strings, tags and other specialities.
194
195% Why does samples = {} require a second pair of brackets? Wouldn't a
196% comma-separated list be enough in Lua? Because it's \METAPOST\ which has its own
197% ideas about where expressions start and end.
198
199\startbuffer
200\startMPcode{doublefun}
201    draw lmt_axis [
202        sx     =  5mm, sy     =  5mm,
203        nx     = 20,   ny     = 10,
204        dx     =  5,   dy     =  2,
205        tx     =  5,   ty     =  2,
206        startx =  1,   starty =  0,
207
208        connect = true,
209        samples = {
210            {
211                4, 2, 4, 9, 3, 0, 8, 9, 10, 1,
212                5, 3, 0, 8, 5, 6, 10, 2, 3, 5
213            }
214        },
215        axiscolor    = "darkgreen",
216        textcolor    = "darkred",
217        samplecolors = {
218            "darkblue"
219        },
220    ] withpen pencircle scaled 1mm ;
221\stopMPcode
222\stopbuffer
223
224\typebuffer[option=TEX]
225
226\startlinecorrection
227\getbuffer
228\stoplinecorrection
229
230We can have multiple sample lists. But of course dealing with that is really up
231to the underlying code, which itself is not that much related to \METAPOST\ but
232has been delegated to \LUA.
233
234\startbuffer
235\definecolor[tdarkred]  [r=.6,a=1,t=.5]
236\definecolor[tdarkgreen][g=.6,a=1,t=.5]
237\definecolor[tdarkblue] [b=.6,a=1,t=.5]
238
239\startMPcode{doublefun}
240    save u ; let u = uniformdeviate ;
241    draw lmt_axis [
242        sx =  5mm, sy =  5mm,
243        nx = 20,   ny = 10,
244        dx =  5,   dy =  2,
245        tx = 10,   ty =  2,
246        samples = {
247            {
248                u10, u10, u10, u10, u10,
249                u10, u10, u10, u10, u10,
250                u10, u10, u10, u10, u10,
251                u10, u10, u10, u10, u10
252            },
253            {
254                u10, u10, u10, u10, u10,
255                u10, u10, u10, u10, u10,
256                u10, u10, u10, u10, u10,
257                u10, u10, u10, u10, u10
258            },
259            {
260                u10, u10, u10, u10, u10,
261                u10, u10, u10, u10, u10,
262                u10, u10, u10, u10, u10,
263                u10, u10, u10, u10, u10
264            }
265        },
266        startx       = 1,
267        starty       = 0,
268        connect      = true,
269        axiscolor    = "darkgray",
270        textcolor    = "darkyellow",
271        samplecolors = {
272            "tdarkred",
273            "tdarkgreen",
274            "tdarkblue"
275        },
276    ] withpen pencircle scaled 1mm ;
277\stopMPcode
278\stopbuffer
279
280\typebuffer[option=TEX]
281
282\startlinecorrection
283\getbuffer
284\stoplinecorrection
285
286Yet another interesting variant might be this:
287
288\startbuffer
289\startluacode
290    documentdata["lmx-sample-1"] = {
291        {
292            4, 2, 4, 9, 3, 0, 8, 9, 10, 1,
293            5, 3, 0, 8, 5, 6, 10, 2, 3, 5
294        }
295    }
296\stopluacode
297\stopbuffer
298
299\typebuffer[option=TEX] \getbuffer
300
301\startbuffer
302\startMPcode{doublefun}
303    draw lmt_axis [
304        sx     = 5mm, sy     = 5mm,
305        nx     = 20,  ny     = 10,
306        dx     = 5,   dy     = 2,
307        tx     = 5,   ty     = 2,
308        startx = 1,   starty = 0,
309
310        samples      = "lmx-sample-1",
311        axiscolor    = "darkgreen",
312        textcolor    = "darkred",
313        samplecolors = { "darkblue" },
314    ] withpen pencircle scaled 1mm ;
315\stopMPcode
316\stopbuffer
317
318\typebuffer[option=TEX]
319
320\startlinecorrection
321\getbuffer
322\stoplinecorrection
323
324% OOPS, doesn't work!
325
326Adding more tricks is not that complex, take, for example:
327
328\startbuffer
329\startMPcode{doublefun}
330draw lmt_axis [
331    sx =  5mm, sy =  5mm,
332    nx = 20,   ny = 10,
333    dx =  5,   dy =  2,
334    tx = 10,   ty = 10,
335
336    list = {
337        [
338            connect = true,
339            color   = "darkred",
340            close   = true,
341            points  = { (1, 1), (15, 8), (2, 10) },
342            texts   = { "segment 1", "segment 2", "segment 3" }
343        ],
344        [
345            connect = true,
346            color   = "darkgreen",
347            points  = { (2, 2), (4, 1), (10, 3), (16, 8), (19, 2) },
348            labels  = { "a", "b", "c", "d", "e" }
349        ],
350        [
351            connect = true,
352            color   = "darkblue",
353            close   = true,
354            points  = { (5, 3), (8, 8), (16, 1) },
355            labels  = { "1", "2", "3" }
356        ]
357    },
358
359] withpen pencircle scaled 1mm  ;
360\stopMPcode
361\stopbuffer
362
363\typebuffer[option=TEX]
364
365yielding
366
367\startlinecorrection
368\getbuffer
369\stoplinecorrection
370
371but this is experimentation, work in progress, not to be taken as settled.
372
373\blank
374
375A variant on this one is the following:
376
377\startbuffer
378\startMPcode{doublefun}
379draw lmt_function [
380
381    xmin =  0, xmax = 10, xstep = .05,
382    ymin = -2, ymax =  2,
383
384    xticks = "bottom", xsmall = 80, xlarge = 20,
385    yticks = "left",   ysmall = 40, ylarge =  4,
386
387    code = "1.5 * math.cosd(240 * math.sqrt(x))",
388
389    xlabels = "yes",
390    ylabels = "yes",
391
392    ycaption = "\strut\tfd \rotate[rotation=90]{vertical}",
393    xcaption = "\strut\tfd horizontal",
394
395    pointsymbol = "dot", pointsize = 4, pointcolor = "orange",
396
397    sx = 2mm, sy = 4mm, linewidth = .025mm, offset = .1mm,
398]
399    xsized 8cm
400;
401\stopMPcode
402\stopbuffer
403
404\typebuffer[option=TEX]
405
406A valid question is if this should be combined with the previous but having
407distinctive variants is less likely to complicate the settings, as these can
408depend on the application:
409
410\startlinecorrection
411\getbuffer
412\stoplinecorrection
413
414A more complex usage (still under exploration) is demonstrated next:
415
416\startbuffer
417\definecolor[MyColorR][r=.5,t=.5,a=1]
418\definecolor[MyColorG][g=.5,t=.5,a=1]
419\definecolor[MyColorB][b=.5,t=.5,a=1]
420\definecolor[MyColorY][r=.5,g=.5,t=.5,a=1]
421
422\startMPcode{doublefun}
423draw lmt_function [
424    sx = 1mm, sy = 4mm, linewidth = .025mm, offset = .1mm,
425
426    xmin =  0, xmax = 20, xstep     = .1,
427    ymin = -2, ymax =  2,
428
429    xticks = "bottom", xsmall = 80, xlarge = 20, xlabels = "nolimits",
430    yticks = "left",   ysmall = 40, ylarge =  4, ylabels = "yes",
431
432    code  = "1.5 * math.sind (50 * x - 150)",
433
434    frame = "sticks", % "ticks"
435
436    functions = {
437        [
438            xmin      =  1.0,
439            xmax      =  7.0,
440            close     = true,
441            fillcolor = "MyColorR"
442        ],
443        [
444            xmin      =  7.0,
445            xmax      = 12.0,
446            close     = true,
447            fillcolor = "MyColorG"
448        ],
449        [
450            xmin      = 12.0,
451            xmax      = 19.0,
452            close     = true,
453            fillcolor = "MyColorB"
454        ],
455        [
456            drawcolor = "darkyellow",
457            drawsize  = 2,
458        ],
459        [
460            xmin      =   4,
461            xmax      =  17,
462            xstep     = .25,
463            drawcolor = "darkmagenta",
464            shape     = "steps",
465            code      = "0.5 * math.random(-2,2)",
466        ],
467        [
468            xmin      =  5.0,
469            xmax      = 15.0,
470            close     = true,
471            fillcolor = "MyColorY"
472            code      = "1.75 * math.cosd (50 * x - 150)",
473        ]
474    },
475    ycaption  = "\rotate[rotation=90]{\tfd\strut a mix of drawings}",
476    xcaption  = "\framed[foregroundstyle=\tfd]{a mixture of $\sin(x), \cos(x), \sqrt{x}$ etc.}",
477]
478    xsized 8cm
479;
480\stopMPcode
481\stopbuffer
482
483\typebuffer[option=TEX]
484
485Of course calling the same command multiple times with different code snippets
486will also work.
487
488\startlinecorrection
489\getbuffer
490\stoplinecorrection
491
492The previous examples used new code but how about improving existing features?
493Let's look at outlines.
494
495\startbuffer
496\startMPcode{doublefun}
497    save h ; h = 12mm ;
498
499    draw lmt_outline [
500        text      = "hello"
501        kind      = "draw",
502        drawcolor = "darkblue",
503    ] ysized h ;
504
505    draw lmt_outline [
506        text          = "hello",
507        kind          = "fill",
508        fillcolor     = "darkred",
509    ] ysized h shifted (3.75h,0) ;
510
511    draw lmt_outline [
512        test          = "hello",
513        kind          = "both",
514        fillcolor     = "darkred",
515    ] ysized h shifted (7.5h,0mm) ;
516
517    draw lmt_outline [
518        text          = "hello",
519        kind          = "both",
520        fillcolor     = "darkred",
521        drawcolor     = "darkblue",
522        rulethickness = 1/5,
523    ] ysized h shifted (0,-1.25h) ;
524
525    draw lmt_outline [
526        text          = "hello",
527        kind          = "reverse",
528        fillcolor     = "darkred",
529        drawcolor     = "darkblue",
530        rulethickness = 1/2,
531    ] ysized h shifted (3.75h,-1.25h) ;
532
533    draw lmt_outline [
534        text          = "hello",
535        kind          = "fillup",
536        fillcolor     = "darkgreen",
537        rulethickness = 0,
538    ] ysized h shifted (7.5h,-1.25h) ;
539\stopMPcode
540\stopbuffer
541
542\typebuffer[option=TEX]
543
544\startlinecorrection
545\getbuffer
546\stoplinecorrection
547
548This interface is much nicer than the one where each variant (the parameter \type
549{kind} above) had its own macro due to the need to group properties of the
550outline and fill. Let's show some more:
551
552\startbuffer
553\startMPcode{doublefun}
554    draw lmt_outline [
555        text      = "\obeydiscretionaries\samplefile{tufte}",
556        align     = "normal",
557        kind      = "draw",
558        drawcolor = "darkblue",
559    ] xsized TextWidth ;
560\stopMPcode
561\stopbuffer
562
563\typebuffer[option=TEX]
564
565\startlinecorrection
566\getbuffer
567\stoplinecorrection
568
569\startbuffer
570\startMPcode{doublefun}
571    draw lmt_outline [
572        text      = "\obeydiscretionaries\samplefile{ward}",
573        align     = "normal,tolerant",
574        width     = 10cm,
575        kind      = "draw",
576        drawcolor = "darkblue",
577    ] xsized TextWidth ;
578\stopMPcode
579\stopbuffer
580
581\typebuffer[option=TEX]
582
583\startlinecorrection
584\getbuffer
585\stoplinecorrection
586
587\startbuffer
588\startMPcode{doublefun}
589    draw lmt_outline [
590        text          = "\obeydiscretionaries\samplefile{sapolsky}",
591        align         = "normal,tolerant",
592        style         = "bold",
593        width         = 10cm,
594        kind          = "draw",
595        rulethickness = 1/5,
596        drawcolor     = "darkred",
597    ] xsized TextWidth ;
598\stopMPcode
599\stopbuffer
600
601\typebuffer[option=TEX]
602
603\startlinecorrection
604\getbuffer
605\stoplinecorrection
606
607Another \METAFUN\ text related mechanism deals with following a specific path.
608That interface has evolved over time, also due to more advanced possibilities in
609\MKIV. But, it's again time for a upgrade, for example:
610
611\startbuffer
612\startMPcode{doublefun}
613    draw lmt_followtext [
614        text    = "How well does it work {\bf 1}! ",
615        path    = (fullcircle scaled 4cm),
616        trace   = true,
617        spread  = true,
618    ] ysized 5cm ;
619
620    draw lmt_followtext [
621        text    = "How well does it work {\bf 2}! ",
622        path    = fullcircle scaled 4cm,
623        trace   = true,
624        spread  = false,
625        reverse = true,
626    ] ysized 5cm shifted (0,-6cm) ;
627
628    draw lmt_followtext [
629        text        = "How well does it work {\bf 3}! ",
630        trace       = true,
631        autoscaleup = "yes"
632    ] ysized 5cm shifted (6cm,0) ;
633
634    draw lmt_followtext [
635        text        = "How well does it work {\bf 4}! ",
636        path        = fullcircle scaled 2cm,
637        trace       = true,
638        autoscaleup = "max"
639    ] ysized 5cm shifted (6cm,-6cm) ;
640\stopMPcode
641\stopbuffer
642
643\typebuffer[option=TEX]
644
645\startlinecorrection
646\getbuffer
647\stoplinecorrection
648
649Although \METAPOST\ can draw arrows a bit more code is involved than one would
650have expected. As a consequence, influencing the way an arrowhead is drawn as
651currently using variables is somewhat cumbersome. Here is an alternative:
652
653\startbuffer
654\startMPcode{doublefun}
655    draw lmt_arrow [
656        path = fullcircle
657            scaled  3cm
658            shifted (0,0cm),
659    ] withcolor "darkred" ;
660
661    draw lmt_arrow [
662        location = "both"
663        path     = fullcircle
664            scaled  3cm
665            rotated 90
666            shifted (0,-3.5cm),
667    ] withcolor "darkgreen" ;
668
669    draw lmt_arrow [
670        kind        = "draw",
671        location    = "middle",
672        alternative = "curved",
673        path        = fullcircle
674            scaled  3cm
675            shifted (3.5cm,0cm),
676    ] withcolor "darkblue" ;
677
678    for i = 0 step 5 until 100 :
679        draw lmt_arrow [
680            alternative = "dimpled",
681            location    = "percentage",
682            percentage  = i,
683            dimple      = (1/5 + i/200),
684            headonly    = (i = 0),
685            path        = fullcircle
686                scaled  3cm
687                shifted (3.5cm,-3.5cm),
688        ] withcolor "darkyellow" ;
689    endfor ;
690\stopMPcode
691\stopbuffer
692
693\typebuffer[option=TEX]
694
695\startlinecorrection
696\getbuffer
697\stoplinecorrection
698
699These new interfaces for outlines, following text and arrows certainly will make
700it in some form to be permanent \METAFUN\ extensions. Some will also be used in
701macros at the \TEX\ end, for instance, when you load the dummy library:
702
703\startbuffer
704\useMPlibrary[dum]
705\stopbuffer
706
707\typebuffer[option=TEX] \getbuffer
708
709You can do this:
710
711\startbuffer
712\startcombination
713    {\externalfigure[crap-001]} {one}
714    {\externalfigure[crap-004][alternative=triangle]} {two}
715\stopcombination
716\stopbuffer
717
718\typebuffer[option=TEX]
719
720and get:
721
722\startlinecorrection
723\getbuffer
724\stoplinecorrection
725
726This placeholder now also can be accessed directly:
727
728\startbuffer
729\useMPmacro
730  [minifun]
731  [placeholder]
732  [width=10cm,
733   height=3cm,
734   reduction=.2,
735   alternative=triangle,
736   color=orange]
737\stopbuffer
738
739\typebuffer[option=TEX]
740
741\startlinecorrection
742\getbuffer
743\stoplinecorrection
744
745The \type {\useMPmacro} is an entirely new interface to \METAFUN\ code. Although
746it is still experimental, we show an example. Of course, as needed, you can throw
747in some \LUA\ magic.
748
749\startbuffer
750\startMPcalculation
751    presetparameters "demo" [
752        n = 5,
753        s = 1cm,
754    ] ;
755
756    def lmt_demo = applyparameters "demo" "lmt_do_demo" enddef ;
757
758    vardef lmt_do_demo =
759        for i=1 upto getparameter "demo" "n" :
760            draw fullcircle scaled (i*getparameter "demo" "s");
761        endfor ;
762    enddef ;
763\stopMPcalculation
764\stopbuffer
765
766\typebuffer[option=TEX]
767
768The calculation wrapper makes this code be processed immediately, which is needed
769because we don't use a module.
770
771\getbuffer
772
773A the \TEX\ end we do this:
774
775\startbuffer
776\defineMPparameterset[demo][n=integer,s=dimension]
777\stopbuffer
778
779\typebuffer[option=TEX]
780
781\getbuffer
782
783We can now let the macro do its work:
784
785\startbuffer
786\startcombination[nx=4,location=middle]
787    {\useMPmacro[demo][n=8,s=2mm]}        {Demo 1}
788    {\useMPmacro[demo][n=4,s=4mm]}        {Demo 2}
789    {\useMPmacro[demo][n=4,s=5\exheight]} {Demo 3}
790    {\useMPmacro[demo]}                   {Demo 4}
791\stopcombination
792\stopbuffer
793
794\typebuffer[option=TEX]
795
796\startlinecorrection
797\getbuffer
798\stoplinecorrection
799
800You can also set the parameters separately. There is one catch: there is no
801grouping so in this case you need to reset the parameters afterwards.
802
803\starttyping
804\presetMPparameters[demo][n=8] \useMPmacro[demo]\blank
805\presetMPparameters[demo][n=4] \useMPmacro[demo]\blank
806\resetMPparameters [demo]      \useMPmacro[demo]\blank
807\stoptyping
808
809These examples demonstrate that we can make \METAPOST\ a bit friendlier for users
810who are not that fluent with the language. It remains to be seen to what extent
811additional modules will be written, but the possibilities are there.
812
813\stopdocument
814