1
2
3
4
5
6
7
8
9
10
11
12
13
14\usemodule[magazinebasic,abr02]
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. Its not a manual or a recipe, just food for thought. All you see
22 here might change andor 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
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 shouldnt notice, unless of course
43they currently employ (yet undocumented) lowlevel 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 dont 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 keyvalue 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. Its not so much that these
117things were not possible before, but the more concise user interface is something
118new indeed. Lets 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
177finetune 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 {lmtconnected} 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
187
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 \LUAlike
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
196
197
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
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",
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?
493Lets 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 = 15,
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 = 12,
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. Lets 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 = 15,
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, its 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 = (15 i200),
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[crap001]} {one}
714 {\externalfigure[crap004][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 (igetparameter "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 dont 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 |