summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/manuals/metafun
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2018-01-12 08:12:50 +0100
committerContext Git Mirror Bot <phg42.2a@gmail.com>2018-01-12 08:12:50 +0100
commitd0edf3e90e8922d9c672f24ecdc5d44fe2716f31 (patch)
tree5b618b87aa5078a8c744c94bbf058d69cd7111b2 /doc/context/sources/general/manuals/metafun
parent409a95f63883bd3b91699d39645e39a8a761457c (diff)
downloadcontext-d0edf3e90e8922d9c672f24ecdc5d44fe2716f31.tar.gz
2018-01-08 23:11:00
Diffstat (limited to 'doc/context/sources/general/manuals/metafun')
-rw-r--r--doc/context/sources/general/manuals/metafun/cow-fun.mps154
-rw-r--r--doc/context/sources/general/manuals/metafun/hacker.pngbin0 -> 60848 bytes
-rw-r--r--doc/context/sources/general/manuals/metafun/m-1.pngbin0 -> 27420 bytes
-rw-r--r--doc/context/sources/general/manuals/metafun/m-2.pngbin0 -> 1002 bytes
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-backgrounds.tex878
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-backpage.tex53
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-basics.tex3587
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-colofon-paper.tex19
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-colofon-screen.tex21
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-colofon.tex56
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-contents.tex17
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-conventions.tex117
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-debugging.tex383
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-document.tex118
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-effects.tex2596
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-embedding.tex1208
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-environment-layout.tex151
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-environment-samples.tex321
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-environment-screen.tex139
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-environment.tex595
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-examples.tex3269
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-functions.tex611
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-gadgets.tex548
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-graphics.tex21
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-index.tex25
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-introduction.tex101
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-layout.tex990
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-lua.tex1060
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-macros.tex91
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-positioning.tex1013
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-reference.tex659
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-sneaky.tex60
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-styles.tex445
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-syntax.tex1130
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-text.tex1784
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-titlepage-paper.tex23
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-titlepage-screen.tex30
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-welcome.tex3502
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun.tex108
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-700.tex17
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-771.tex9
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-772.tex9
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-773.tex9
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-774.tex103
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-775.tex9
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-776.tex9
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-800.tex27
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-900.tex48
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-901.tex11
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-902.tex11
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-mrun-demo.mp212
-rw-r--r--doc/context/sources/general/manuals/metafun/mycow.mp299
-rw-r--r--doc/context/sources/general/manuals/metafun/mycow.pdfbin0 -> 4301 bytes
-rw-r--r--doc/context/sources/general/manuals/metafun/somecow.pdfbin0 -> 3592 bytes
54 files changed, 26656 insertions, 0 deletions
diff --git a/doc/context/sources/general/manuals/metafun/cow-fun.mps b/doc/context/sources/general/manuals/metafun/cow-fun.mps
new file mode 100644
index 000000000..4235985ba
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/cow-fun.mps
@@ -0,0 +1,154 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%BoundingBox: 52 425 327 625
+%%Comment: originally a CorelDraw cow
+%%Creator: MetaPost
+%%Pages: 1
+%%EndProlog
+%%Page: 1 1
+0 2 dtransform truncate idtransform setlinewidth pop
+.625 0 0 setrgbcolor
+newpath 245.45 600.34 moveto
+242.78 599.40 239.62 596.02 237.67 594.07 curveto
+236.74 584.42 244.58 583.63 250.20 577.44 curveto
+258.77 573.70 251.21 567.72 256.18 557.42 curveto
+257.04 550.94 257.90 543.89 255.31 539.78 curveto
+249.48 538.92 247.97 540.22 246.89 531.43 curveto
+246.31 526.97 231.77 529.06 229.03 538.27 curveto
+227.09 544.97 221.33 546.70 217.80 543.17 curveto
+213.77 538.06 215.78 531.22 217.80 527.47 curveto
+224.93 517.32 212.04 511.42 205.13 516.74 curveto
+199.73 508.68 211.39 500.04 207.43 494.50 curveto
+205.78 493.99 204.77 489.17 185.47 500.54 curveto
+180.36 504.14 167.83 500.76 168.77 520.63 curveto
+168.77 525.82 165.60 543.53 162.14 555.91 curveto
+159.41 561.24 156.74 559.08 156.89 553.90 curveto
+157.18 547.85 162.94 531.22 155.52 540.22 curveto
+153.58 539.21 156.89 523.58 156.89 521.64 curveto
+162.00 517.03 157.39 513.58 154.73 512.28 curveto
+151.27 518.33 149.62 518.04 147.17 514.44 curveto
+141.70 514.08 144.58 528.19 140.26 528.62 curveto
+137.02 527.76 139.18 520.06 138.24 518.76 curveto
+132.98 524.74 130.90 529.27 127.01 521.64 curveto
+126.14 521.64 122.11 519.19 120.96 526.54 curveto
+117.65 552.74 107.06 558.36 93.82 565.13 curveto
+92.02 565.63 84.24 566.71 79.34 568.15 curveto
+73.51 560.88 58.32 565.63 56.23 570.31 curveto
+54.79 572.69 54.65 575.21 54.79 576.50 curveto
+52.34 580.10 55.87 582.70 59.62 583.06 curveto
+62.86 587.16 68.54 594.94 71.28 601.56 curveto
+72.29 603.07 74.95 609.34 78.19 609.55 curveto
+74.95 612.94 74.30 622.51 82.66 617.33 curveto
+87.12 624.02 92.09 624.31 95.76 615.82 curveto
+102.89 615.38 102.31 608.69 115.78 605.52 curveto
+122.76 602.86 132.77 604.58 140.26 603.72 curveto
+136.22 596.88 127.44 566.86 132.98 559.80 curveto
+140.76 564.70 141.84 605.38 157.03 595.66 curveto
+160.56 593.93 159.91 590.04 164.09 590.18 curveto
+170.42 587.45 169.13 600.77 172.51 600.77 curveto
+176.47 599.76 183.02 599.04 186.98 599.54 curveto
+197.71 600.77 206.93 604.08 223.92 602.50 curveto
+231.12 601.78 238.25 601.06 245.45 600.34 curveto
+closepath fill
+newpath 305.28 560.95 moveto
+304.63 560.95 299.95 561.24 299.38 561.24 curveto
+302.40 550.44 303.98 536.47 304.20 525.31 curveto
+303.70 521.35 299.81 517.46 299.38 525.67 curveto
+295.85 530.86 296.42 540.07 293.40 540.29 curveto
+287.35 539.64 285.34 513.22 280.01 509.33 curveto
+276.26 512.28 280.73 524.02 275.54 524.74 curveto
+270.50 524.02 264.31 526.68 266.69 534.46 curveto
+270.29 543.02 268.34 554.76 266.54 561.60 curveto
+262.37 578.59 264.02 587.09 271.58 596.09 curveto
+267.48 604.51 lineto
+275.40 608.26 285.62 604.58 290.02 602.21 curveto
+294.62 600.26 300.24 595.94 301.10 587.38 curveto
+303.34 578.88 304.42 569.74 305.28 560.95 curveto
+closepath fill
+.625 .625 0 setrgbcolor
+newpath 84.38 618.55 moveto
+88.34 624.38 92.59 622.94 96.34 615.67 curveto
+101.23 615.60 102.46 612.43 104.98 610.78 curveto
+122.62 598.39 147.46 607.18 167.90 601.92 curveto
+180.94 598.54 190.87 599.76 200.09 602.06 curveto
+220.32 607.25 246.10 596.16 263.74 603.86 curveto
+274.75 608.62 284.76 605.66 292.97 600.91 curveto
+297.58 597.96 299.59 596.09 300.96 591.26 curveto
+306.29 572.54 306.29 551.02 309.53 530.57 curveto
+309.53 528.84 312.19 526.10 312.48 522.07 curveto
+315.79 511.34 316.08 510.12 317.16 502.20 curveto
+317.16 501.34 326.52 488.45 325.01 479.02 curveto
+323.93 481.25 323.86 482.83 321.62 481.68 curveto
+320.33 479.30 320.90 473.90 322.56 471.74 curveto
+320.83 470.81 318.46 473.47 317.52 475.20 curveto
+318.17 473.04 317.81 470.81 316.73 469.30 curveto
+315.86 472.25 316.58 473.18 315.36 473.90 curveto
+313.99 472.90 314.21 469.30 314.28 466.20 curveto
+313.49 468.07 311.47 472.46 312.55 476.42 curveto
+312.48 484.20 308.81 489.10 310.32 499.10 curveto
+310.10 504.43 307.30 521.06 304.56 524.30 curveto
+303.12 526.25 306.36 510.77 306.36 506.16 curveto
+306.65 500.90 307.08 468.72 306.43 463.10 curveto
+306.43 459.22 306.22 453.96 307.08 452.16 curveto
+308.74 450.79 309.38 450.50 309.60 447.98 curveto
+309.24 446.62 308.74 446.04 307.73 445.54 curveto
+306.07 444.60 307.37 441.79 306.07 439.85 curveto
+304.49 438.77 304.13 441.86 303.34 441.86 curveto
+302.69 441.00 303.05 437.98 302.47 436.18 curveto
+299.66 433.80 292.18 432.50 289.15 434.66 curveto
+289.73 440.64 291.74 441.58 295.63 446.62 curveto
+298.66 452.59 297.00 460.94 296.93 468.14 curveto
+295.49 480.38 289.22 487.30 289.44 496.44 curveto
+287.86 495.72 286.42 494.57 284.26 494.86 curveto
+283.39 489.46 286.42 484.56 284.83 480.82 curveto
+281.95 471.96 277.06 446.62 279.00 437.76 curveto
+280.01 434.74 278.21 433.15 277.06 433.94 curveto
+276.77 433.94 276.55 433.94 276.41 433.94 curveto
+276.41 433.94 276.55 431.42 275.69 430.92 curveto
+274.10 430.34 273.67 431.71 272.66 432.14 curveto
+271.22 430.85 272.52 429.48 271.15 428.04 curveto
+267.19 428.04 261.36 425.38 257.98 428.26 curveto
+257.33 434.16 263.30 436.68 266.47 440.71 curveto
+268.63 446.62 271.08 462.89 267.77 474.62 curveto
+267.77 475.56 264.38 485.28 261.43 488.66 curveto
+258.70 487.66 257.33 485.50 253.22 486.29 curveto
+252.58 484.34 253.30 482.33 252.22 480.10 curveto
+251.86 479.52 249.34 478.58 249.19 481.39 curveto
+248.98 483.05 248.90 486.36 248.26 486.72 curveto
+243.65 486.72 233.71 487.08 231.77 493.92 curveto
+219.89 492.34 215.93 491.26 206.57 493.42 curveto
+196.63 489.67 183.24 506.16 174.53 502.20 curveto
+172.51 496.15 173.09 485.64 171.65 481.39 curveto
+169.34 474.77 171.14 467.14 171.14 456.41 curveto
+170.57 455.40 169.85 454.46 168.48 454.46 curveto
+168.48 453.10 169.34 450.86 168.62 449.42 curveto
+167.18 447.62 165.89 451.80 165.02 444.60 curveto
+163.15 443.74 157.75 442.22 155.59 445.18 curveto
+155.88 448.99 158.33 451.30 160.13 453.38 curveto
+161.42 456.91 160.99 458.28 160.70 461.81 curveto
+160.99 464.98 161.71 468.58 161.86 470.09 curveto
+161.86 473.04 162.50 479.30 161.14 481.18 curveto
+159.41 482.69 lineto
+157.18 487.22 158.33 494.64 157.61 500.26 curveto
+155.81 500.69 155.81 500.98 154.01 498.31 curveto
+154.01 494.42 153.50 486.36 152.35 483.84 curveto
+149.69 479.81 150.84 459.65 151.42 448.56 curveto
+151.78 446.47 149.69 447.70 149.76 444.74 curveto
+150.05 442.80 147.89 443.59 146.09 444.60 curveto
+145.15 445.18 146.59 439.78 145.37 439.56 curveto
+142.34 438.84 136.87 438.19 135.22 440.71 curveto
+134.57 444.60 137.88 448.06 140.62 451.01 curveto
+143.14 455.83 140.90 465.70 140.47 476.28 curveto
+138.89 478.22 lineto
+134.86 483.19 139.61 496.94 136.51 506.23 curveto
+120.02 514.87 122.11 519.19 118.73 537.62 curveto
+115.13 557.64 93.38 567.65 79.06 567.65 curveto
+73.44 563.04 66.24 563.62 58.54 567.65 curveto
+55.66 569.23 54.43 573.19 54.50 576.50 curveto
+52.63 580.75 55.22 582.19 59.62 583.49 curveto
+62.71 587.81 68.62 594.65 69.19 597.74 curveto
+70.34 601.92 75.53 608.11 77.76 609.77 curveto
+75.82 613.01 74.81 615.17 77.11 618.55 curveto
+79.56 620.14 81.79 616.61 84.38 618.55 curveto
+closepath stroke
+showpage
+%%EOF
diff --git a/doc/context/sources/general/manuals/metafun/hacker.png b/doc/context/sources/general/manuals/metafun/hacker.png
new file mode 100644
index 000000000..3a54696ee
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/hacker.png
Binary files differ
diff --git a/doc/context/sources/general/manuals/metafun/m-1.png b/doc/context/sources/general/manuals/metafun/m-1.png
new file mode 100644
index 000000000..ab020de9f
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/m-1.png
Binary files differ
diff --git a/doc/context/sources/general/manuals/metafun/m-2.png b/doc/context/sources/general/manuals/metafun/m-2.png
new file mode 100644
index 000000000..512d3eda0
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/m-2.png
Binary files differ
diff --git a/doc/context/sources/general/manuals/metafun/metafun-backgrounds.tex b/doc/context/sources/general/manuals/metafun/metafun-backgrounds.tex
new file mode 100644
index 000000000..200620cae
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-backgrounds.tex
@@ -0,0 +1,878 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-backgrounds
+
+\environment metafun-environment
+
+\startchapter[reference=sec:page,title={Page backgrounds}]
+
+\startintro
+
+Especially in interactive documents, adding backgrounds to the page and text
+areas not only enhances readability, but also makes it more convenient to
+identify header, footers and navigational areas. In this chapter we will
+demonstrate that with \METAPOST\ we can go beyond the \TEX\ based features
+present in \CONTEXT. One section is dedicated to graphics and printing,
+especially bleeding.
+
+\stopintro
+
+\startsection[title={The basic layout}]
+
+\index {layout}
+
+In the \CONTEXT\ manual you can find many details on the composition of the page.
+When \TEX\ typesets text, crossing the page boundary triggers \TEX's output
+routine. This routine is responsible for pasting the body text that goes onto a
+page in the correct area. A simple representation of such a page is:
+
+\startbuffer[a]
+\startuseMPgraphic{layout 1}
+ pickup pencircle scaled 1mm ;
+ fill unitsquare xyscaled (7cm,8cm)
+ withcolor .85white ;
+ fill unitsquare xyscaled (5cm,5cm) shifted (1cm,1.5cm)
+ withcolor .625yellow ;
+ fill unitsquare xyscaled (5cm,1cm) shifted (1cm,.5cm)
+ withcolor .625red ;
+ fill unitsquare xyscaled (5cm,1cm) shifted (1cm,6.5cm)
+ withcolor .625red ;
+ draw unitsquare xyscaled (5cm,7cm) shifted (1cm,.5cm)
+ withcolor .25white ;
+ drawarrow (2cm,8cm) -- top (2cm,7.5cm) ;
+ drawarrow (0cm,7cm) -- lft (1cm,7cm) ;
+ clip currentpicture to unitsquare xyscaled (7cm,8cm) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[b]
+\startuseMPgraphic{layout 2}
+ \includeMPgraphic{layout 1}
+ clip currentpicture to unitsquare scaled 3cm shifted (0,5cm) ;
+ currentpicture := currentpicture scaled 2 shifted (0,-8cm) ;
+ setbounds currentpicture to unitsquare xyscaled (6cm,8cm) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer[a,b]
+
+\startbuffer[c]
+\startlinecorrection[blank]
+\hbox
+ {\useMPgraphic{layout 1}\hskip1cm
+ \useMPgraphic{layout 2}}
+\stoplinecorrection
+\stopbuffer
+
+\getbuffer[c]
+
+The red areas are the header and footer, while the yellow areas contains the text
+flow. We can turn headers on and off and|/|or hide them. For this reason, the
+header, text and footer areas together make up the height of the text.
+
+A close look at the left picture will reveal that the two arrows point to the
+center of the lines. This is achieved by the \type {top} and \type {lft}
+directives. If we would not have clipped the picture, the arrow would have stuck
+half a line width outside the gray area that represents the page. When
+constructing such pictures, one should really pay attention to such details,
+since it pays off in the overall look and feel of the document.
+
+The vertical arrow represents the top space, while the horizontal arrow denotes
+the distance to the back of the cover (back space). By changing their values, you
+can shift the main body text on the page. In a double sided layout scheme, the
+back space is automatically mirrored on even pages.
+
+An advanced \METAPOST\ user may wonder why we hard code the dimensions, and avoid
+\METAPOST's powerful mechanisms for defining relations. Our experience has taught
+us that in pictures like this, providing a general solution seldom pays large
+dividents or savings in time.
+
+\typebuffer[a]
+
+As you can see, the left graphic is defined as a series of rectangles. The \type
+{xyscaled} macro is part of the \CONTEXT\ files, and saves some typing and space.
+It is defined as a primary, requiring both left and right operands.
+
+\starttyping
+primarydef p xyscaled q =
+ p xscaled (xpart q) yscaled (ypart q)
+enddef ;
+\stoptyping
+
+Zooming in on the top left corner only takes a few lines. First we clip the
+correct part, next we scale it up, and finally we let the bounding box suit the
+left picture.
+
+\typebuffer[b]
+
+This code demonstrates how you can reuse a graphic inside another one. This
+strategy can easily be used to stepwise build (or extend) graphics. The two
+graphics were put side by side with the following command. Watch the use of line
+correction commands. They optimize the white space around the graphic.
+
+\typebuffer[c]
+
+As soon as you want to make an electronic document, you will want to use
+different areas of the screen for different purposes: text, menus, buttons, etc.
+For this reason, \CONTEXT\ provides not only left and right margins, but also
+additional left and right edge areas and top and bottom margins. These areas are
+shown in the figure on the next page.
+
+\startbuffer[aa]
+pickup pencircle scaled 2pt ;
+
+numeric w[], h[], x[], y[], u ; u := .5cm ;
+
+numeric width ; width := \the\textwidth ;
+numeric height ; height := \the\textheight ;
+\stopbuffer
+
+\startbuffer[bb]
+w[1] = 2u ; w[2] = 3u ; w[4] = 3u ; w[5] = 2u ;
+h[1] = 1u ; h[2] = 1u ; h[4] = 1u ; h[5] = 1u ;
+
+w[1]+w[2]+w[3]+w[4]+w[5]+4u = width ;
+h[1]+h[2]+h[3]+h[4]+h[5]+4u = height ;
+
+x[1] = 1u ; y[1] = 1u ;
+x[2] = x[1] + w[1] + .5u ; y[2] = y[1] + h[1] + .5u ;
+x[3] = x[2] + w[2] + .5u ; y[3] = y[2] + h[2] + .5u ;
+x[4] = x[3] + w[3] + .5u ; y[4] = y[3] + h[3] + .5u ;
+x[5] = x[4] + w[4] + .5u ; y[5] = y[4] + h[4] + .5u ;
+\stopbuffer
+
+\startbuffer[cc]
+def do_it (expr xx, yy, cc) =
+ draw unitsquare
+ xyscaled (w[xx],h[yy]) shifted (x[xx],y[yy])
+ withcolor if cc : .625red else : .625yellow fi ;
+enddef ;
+
+fill unitsquare xyscaled (width,height) withcolor .85white;
+
+do_it (1,1,false) ; do_it (5,1,false) ;
+do_it (2,1,false) ; do_it (3,1,false) ; do_it (4,1,false) ;
+
+do_it (1,2,false) ; do_it (5,2,false) ;
+do_it (2,2,true ) ; do_it (3,2,true ) ; do_it (4,2,true ) ;
+
+do_it (1,3,false) ; do_it (5,3,false) ;
+do_it (2,3,true ) ; do_it (3,3,true ) ; do_it (4,3,true ) ;
+
+do_it (1,4,false) ; do_it (5,4,false) ;
+do_it (2,4,true ) ; do_it (3,4,true ) ; do_it (4,4,true ) ;
+
+do_it (1,5,false) ; do_it (5,5,false) ;
+do_it (2,5,false) ; do_it (3,5,false) ; do_it (4,5,false) ;
+\stopbuffer
+
+\startbuffer[dd]
+def do_it (expr yy, tt) =
+ path p ;
+ p := unitsquare xyscaled (w[1],h[yy]) shifted (x[1],y[yy]) ;
+ label.lft(tt, center p shifted (-w[1]/2-u-.25cm,0)) ;
+enddef ;
+
+do_it (1,btex bottom etex) ;
+do_it (2,btex footer etex) ;
+do_it (3,btex text etex) ;
+do_it (4,btex header etex) ;
+do_it (5,btex top etex) ;
+\stopbuffer
+
+\startbuffer[ee]
+def do_it (expr xx, tt) =
+ path p ;
+ p := unitsquare xyscaled (w[xx],h[1]) shifted (x[xx],y[1]) ;
+ label(tt, center p shifted (0,height-h[1]/2)) ;
+enddef ;
+
+do_it (1,btex edge etex) ;
+do_it (2,btex margin etex) ;
+do_it (3,btex text etex) ;
+do_it (4,btex margin etex) ;
+do_it (5,btex edge etex) ;
+\stopbuffer
+
+\startbuffer[ff]
+setbounds currentpicture to
+ unitsquare xyscaled (width,height) ;
+\stopbuffer
+
+% We use two chars for buffer names, otherwise we can get
+% get in conflict with the next buffers with similar names.
+
+\startpostponing
+\centerbox{\processMPbuffer[aa,bb,cc,dd,ee,ff]}
+\stoppostponing
+
+When defining this graphic, all areas have related dimensions. Here it makes
+sense to let \METAPOST\ calculate these dimensions as much as possible. First we
+define the five by five matrix of areas. We pass the width and height of the main
+text area. Because they are stored in \TEX\ dimension registers, we have to
+prefix them by \type {\the}.
+
+\typebuffer[aa]
+
+We now specify the lower left corners using \type {=} instead of the \type {:=},
+which means that \METAPOST\ will calculate \type {w[3]} and \type {h[3]} for us.
+
+\typebuffer[bb]
+
+Because we are going to repeat ourselves, we draw the areas using a macro.
+Depending on its importance, we color it red or yellow.
+
+\typebuffer[cc]
+
+This picture in itself is not yet explanatory, so we add some labels. Again, we
+use a macro, which we feed with a picture generated by \TEX. Since these pictures
+are filtered from the source and pre||processed, we cannot embed the \type
+{btex}||\type {etex} in the macro \type {do_it} and pass a string. It has to be
+done this way. \footnote {This is true only in a regular \METAPOST\ run. In
+\CONTEXT\ \MKIV\ we follow a different route.}
+
+\typebuffer[dd]
+
+In the horizontal direction we have edges, margins and text. There are left and
+right edges and margins, which are swapped on even pages when you typeset a
+double sided document.
+
+\typebuffer[ee]
+
+Since we want the graphic to match the dimensions of the text area of the current
+page, we have to make sure that the bounding box is adapted accordingly. By this
+action, the labels will fall outside the bounding box. When we directly embed a
+graphic, this works ok, but when we start scaling and reusing, due to the object
+reuse mechanism the graphic will be clipped to the bounding box.
+
+\typebuffer[ff]
+
+In the following sections we will demonstrate how you can put graphics behind
+these 25~areas, as well as behind the (left and right) page.
+
+\stopsection
+
+\startsection[title={Setting up backgrounds}]
+
+\index {overlays}
+\index {backgrounds}
+
+One way of protecting a document for unwanted usage is to put an annoying word in
+the background. If you like this, you may try the following. The macro \type
+{ysized} is part of the macros that come with \CONTEXT\ and scales a picture to a
+specific size.
+
+\startbuffer[a]
+\startuniqueMPgraphic{concept}
+ draw btex \colored[s=.8]{\bf CONCEPT} etex rotated 60 ;
+ currentpicture := currentpicture
+ ysized (\overlayheight-.5cm) ;
+\stopuniqueMPgraphic
+
+\defineoverlay[concept][\uniqueMPgraphic{concept}]
+\stopbuffer
+
+\typebuffer[a]
+
+You can now put this graphic in the page background by
+saying:
+
+\starttyping
+\setupbackgrounds[page][background=concept]
+\stoptyping
+
+You may consider the next alternative a bit better, but still it renders the text
+unreadable. Like \type {xysized}, the macro \type {enlarged} is not part of
+standard \METAPOST, but comes with \CONTEXT.
+
+\startbuffer[b]
+\startuniqueMPgraphic{copyright}
+ picture p ; p := btex \colored[s=.8]{COPYRIGHT} etex
+ rotated 90 ;
+ setbounds p to boundingbox p enlarged 1pt ;
+ draw p ;
+ currentpicture := currentpicture
+ xysized (\overlaywidth,\overlayheight) ;
+\stopuniqueMPgraphic
+
+\defineoverlay[copyright][\uniqueMPgraphic{copyright}]
+\stopbuffer
+
+\typebuffer[b]
+
+Again, we put this graphic in the background. By using a unique graphic, we make
+sure that it's rendered only once and reused when possible.
+
+\startbuffer[c]
+\setupbackgrounds[text][rightmargin][background=copyright]
+\stopbuffer
+
+\typebuffer[c]
+
+\doifnotmode{screen}{\getbuffer[b,c]}
+
+In both cases, we slightly scale down the graphic. We do so because otherwise a
+small portion of the text is clipped off. This is unrelated to \TEX\ or
+\METAPOST, but a characteristic of the font. Compare the following Pagella, Latin
+Modern and Termes gi's (the Pagella is the body font of this text).
+
+\startbuffer
+\hbox \bgroup
+ \hbox{\definedfont[file:texgyrepagella-regular at 6cm]gi}%
+ \hbox{\definedfont[file:lmroman10-regular at 6cm]gi}%
+ \hbox{\definedfont[file:texgyretermes-regular at 6cm]gi}%
+\egroup
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+{\showboxes \getbuffer}
+\stoplinecorrection
+
+Watch how the bounding boxes differ and sometimes cross the shape. So, in order
+not to loose part of a glyph when clipping, you need to add a bit of space. \in
+{Figure} [fig:annoying] shows the two backgrounds in action.
+
+\startbuffer
+\getbuffer[a,b]
+\def\ShowPage#1% % (yet) no image as background to image
+ {\framed % possible due to nested file problems
+ [background=#1,offset=overlay]
+ {\typesetfile[mfun-900.tex][page=1,width=.4\textwidth]}}
+\startcombination
+ {\ShowPage{concept}} {concept}
+ {\ShowPage{copyright}} {copyright}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:annoying]
+ {Two examples of annoying backgrounds.}
+ {\getbuffer}
+
+If you really want to add such texts to a document, in \CONTEXT\ we don't have to
+use the page background, but can use one of the layout areas instead (like \type
+{[text][text]} or \type {[text][leftmargin]})
+
+\typebuffer[d]
+
+There is one drawback: when your left and right margin have different dimensions,
+the text will be scaled differently on odd and even pages. Normally this is no
+problem for a draft.
+
+As an alternative you can use the \type {\setuptexts} command and wrap the
+graphic in a box with the right dimensions, using code like:
+
+\starttyping
+\startuniqueMPgraphic{copyright}
+ picture p ; p := btex COPYRIGHT etex rotated 90 ;
+ setbounds p to boundingbox p enlarged 1pt ;
+ draw p withcolor .8white ;
+ xyscale_currentpicture(\the\leftmarginwidth,\the\textheight) ;
+\stopuniqueMPgraphic
+
+\setuptexttexts [margin] [] [\uniqueMPgraphic{copyright}]
+\stoptyping
+
+The graphic goes into the outer margin. The second argument can be used to put
+something in the inner margin.
+
+\stopsection
+
+\startsection[title={Multiple overlays}]
+
+\index{overlays+stack}
+
+\setupbackgrounds[text][rightmargin][background=]
+
+You can stack overlays. Consider the next case, where we assume that you have
+enabled interaction support using \type {\setupinteraction[state=start]}:
+
+\starttyping
+\setupbackgrounds
+ [page]
+ [background={color,nextpage},
+ backgroundcolor=darkyellow]
+\stoptyping
+
+Here, the page gets a colored background and a hyperlink to the next page,
+previously defined by:
+
+\starttyping
+\defineoverlay[nextpage][\overlaybutton{nextpage}]
+\stoptyping
+
+An \type {\overlaybutton} is just a button, with all attributes (color, frame,
+etc) set to nothing, having the dimensions of the overlay. The argument is one of
+the permitted destinations, like \type {nextpage}, \type {firstpage}, \type
+{SearchDocument} and alike.
+
+For efficiency reasons, the background areas (like \type {[text][text]}) are
+calculated only when their definition has changed. When a background changes per
+page, we have to recalculate it on each page. In the next example, the macro
+\type {\overlaybutton} generates a different button on each page. But, since we
+don't explicitly set the background at each page, there is no way the background
+drawing mechanism can know that this button has changed. Therefore, we must force
+recalculation with:
+
+\starttyping
+\setupbackgrounds[state=repeat]
+\stoptyping
+
+You can test this concept yourself with the following code. Here we assume that
+you have a file called \type {tufte.tex} on your system, which is the case if you
+have \CONTEXT\ installed. However, you can just as easily use any file having a
+paragraph of two of text.
+
+\starttyping
+\starttext
+\setupinteraction[state=start]
+\setupbackgrounds[state=repeat]
+\defineoverlay[nextpage][\overlaybutton{nextpage}]
+\setupbackgrounds[text][text][background=nextpage]
+\dorecurse{20}{\input tufte \par}
+\stoptext
+\stoptyping
+
+Note that you can move forward from page to page in the resulting \PDF\ file by
+clicking on each page with the mouse. Now compile this file without setting the
+background state to \type {repeat} and note the difference as you click pages
+with the mouse.
+
+Setting the state was not needed when we used the page background:
+
+\starttyping
+\setupbackgrounds[page][background=nextpage]
+\stoptyping
+
+The \type {\dorecurse} macro is handy for testing since it saves us typing. One
+can nest this macro as in:
+
+\starttyping
+\dorecurse{20}{\dorecurse{10}{Hello World! }\par}
+\stoptyping
+
+The current step is available in \type {\recurselevel} and the depth (nesting
+level) in \type {\recursedepth}.
+
+\stopsection
+
+\startsection[title={Crossing borders}]
+
+\index{backgrounds}
+
+In many cases, the previously mentioned background areas will suffice, but in the
+case of more complicated backgrounds, you may wish to use \METAPOST\ to draw
+graphics that combine or span these areas.
+
+At runtime \CONTEXT\ saves information on the layout that can be picked up by
+\METAPOST. The framework for a page graphic is:
+
+\starttyping
+StartPage;
+ % all kind of commands
+StopPage ;
+\stoptyping
+
+Between the \type {StartPage} and \type {StopPage} command you have access to a
+wide range of variables:
+
+\starttabulate[|l|Tp|]
+\HL
+\NC page \NC PaperHeight PaperWidth \NC \NR
+\NC \NC PrintPaperHeight PrintPaperWidth \NC \NR
+\NC \NC PageOffset PageDepth \NC \NR
+\NC margins \NC TopSpace BackSpace \NC \NR
+\NC text \NC MakeupHeight MakeupWidth \NC \NR
+\NC vertical \NC TopHeight TopDistance \NC \NR
+\NC \NC HeaderHeight HeaderDistance \NC \NR
+\NC \NC TextHeight \NC \NR
+\NC \NC FooterDistance FooterHeight \NC \NR
+\NC \NC BottomDistance BottomHeight \NC \NR
+\NC horizontal \NC LeftEdgeWidth LeftEdgeDistance \NC \NR
+\NC \NC LeftMarginWidth LeftMarginDistance \NC \NR
+\NC \NC TextWidth \NC \NR
+\NC \NC RightMarginDistance RightMarginWidth \NC \NR
+\NC \NC RightEdgeDistance RightEdgeWidth \NC \NR
+\HL
+\stoptabulate
+
+Since using these variables to construct paths is not that handy because the
+areas are available as predefined paths, which we will demonstrate here.
+
+\placefigure
+ [here][fig:back 1]
+ {A background with combined areas.}
+ {\startcombination
+ {\typesetfile[mfun-900.tex][page=2,width=.4\textwidth]}{even}
+ {\typesetfile[mfun-900.tex][page=3,width=.4\textwidth]}{odd}
+ \stopcombination}
+
+In \in {figure} [fig:back 1] you see two pages (odd and even) with a background
+spanning the outer margin and the text area. You can access an area in two ways.
+The area itself is available as \type {Area}.
+
+\starttyping
+StartPage ;
+ fill Area[Text][Text] withcolor .85white ;
+StopPage ;
+\stoptyping
+
+If you use an area this way, you will notice that it is not positioned at the
+right place. An \type {Area} is just a rectangle. If you want a positioned area,
+you should use the \type {Field} array:
+
+\starttyping
+StartPage ;
+ fill Field[Text][Text] withcolor .85white ;
+StopPage ;
+\stoptyping
+
+The location of an area is available in \type {Location}, so the previous
+definition is the same as:
+
+\starttyping
+StartPage ;
+ fill Area[Text][Text] shifted Location[Text][Text]
+ withcolor .85white ;
+StopPage ;
+\stoptyping
+
+The following definition fills and draws the margin and text areas.
+
+\typebuffer[back-2]
+
+This background is assigned to the page layer by saying:
+
+\typebuffer[back-0]
+
+As you can see in \in {figure} [fig:back 2], the text is typeset rather tightly
+between the left and right margins.
+
+\placefigure
+ [here][fig:back 2]
+ {A background with split areas.}
+ {\startcombination
+ {\typesetfile[mfun-900.tex][page=4,width=.4\textwidth]}{even}
+ {\typesetfile[mfun-900.tex][page=5,width=.4\textwidth]}{odd}
+ \stopcombination}
+
+This can easily be solved by enlarging the areas a bit. The next example
+demonstrates this on the text area, which is shown in \in {figure} [fig:back 3].
+
+\typebuffer[back-3]
+
+\placefigure
+ [here][fig:back 3]
+ {A background with enlarged text area.}
+ {\startcombination
+ {\typesetfile[mfun-900.tex][page=6,width=.4\textwidth]}{even}
+ {\typesetfile[mfun-900.tex][page=7,width=.4\textwidth]}{odd}
+ \stopcombination}
+
+The \type {enlarged} macro can be used like \type {shifted} and accepts either a
+numeric or a pair.
+
+How do we define a background as in \in {figure} [fig:back 1]? Because \type
+{Field} provides us the positioned areas, we can use the corners of those.
+
+\typebuffer[back-1]
+
+In this definition we calculate a different path for odd and even pages. When
+done, we enlarge the path a bit. If you want to use different offsets in all
+directions, you can use moved corner points.
+
+\typebuffer[back-4]
+
+Here we displace the corners randomly which leads to backgrounds like \in
+{figure} [fig:back 4]. The following definition would have worked as well:
+
+\typebuffer[back-4x]
+
+\placefigure
+ [here][fig:back 4]
+ {A random text area.}
+ {\startcombination
+ {\typesetfile[mfun-900.tex][page=8,width=.4\textwidth]}{even}
+ {\typesetfile[mfun-900.tex][page=9,width=.4\textwidth]}{odd}
+ \stopcombination}
+
+The previous graphics are defined as usable ones, which means that they will be
+recalculated each page. This is rather inefficient when the shapes don't change.
+But, using a reusable graphic instead, would result in only one graphic for both
+pages. Since the layout for the left and right page differs, another method is
+needed.
+
+Instead of putting the same graphic on the page layer, we put two different ones
+on the left and right page layer.
+
+\starttyping
+\defineoverlay[left page] [\useMPgraphic{left page}]
+\defineoverlay[right page][\useMPgraphic{right page}]
+
+\setupbackgrounds[leftpage] [background=left page]
+\setupbackgrounds[rightpage][background=right page]
+\stoptyping
+
+Now we only have to split the previously defined graphic into two parts. In order
+to force consistency, we isolate the code that fills and draws. The left page
+code looks like:
+
+\starttyping
+\startreusableMPgraphic{left page}
+ StartPage ;
+ path Main ; Main :=
+ llcorner Field[OuterMargin][Text] --
+ lrcorner Field[Text] [Text] --
+ urcorner Field[Text] [Text] --
+ ulcorner Field[OuterMargin][Text] -- cycle ;
+ \includeMPgraphic{draw page}
+ StopPage ;
+\stopreusableMPgraphic
+\stoptyping
+
+The right page text looks similar:
+
+\starttyping
+\startreusableMPgraphic{right page}
+ StartPage ;
+ path Main ; Main :=
+ lrcorner Field[OuterMargin][Text] --
+ llcorner Field[Text] [Text] --
+ ulcorner Field[Text] [Text] --
+ urcorner Field[OuterMargin][Text] -- cycle ;
+ \includeMPgraphic{draw page}
+ StopPage ;
+\stopreusableMPgraphic
+\stoptyping
+
+Watch how we used a reusable graphic first and a simple usable one next.
+Actually, the next graphic is not a stand alone graphic.
+
+\starttyping
+\startuseMPgraphic{draw page}
+ Main := Main enlarged 6pt ;
+ pickup pencircle scaled 2pt ;
+ fill Page withcolor .625white ;
+ fill Main withcolor .850white ;
+ draw Main withcolor .625red ;
+\stopuseMPgraphic
+\stoptyping
+
+We have seen some predefined paths and locations. Apart from the \type {Page}
+path, they take two arguments that specify their position on the layout grid.
+
+\starttabulate[|lT|l|]
+\HL
+\NC path Area [][] \NC an area similar to a \CONTEXT\ one \NC \NR
+\NC pair Location [][] \NC the position of this area \NC \NR
+\NC path Field [][] \NC the area positioned at the right place \NC \NR
+\NC path Page \NC the page itself \NC \NR
+\HL
+\stoptabulate
+
+Some less used and more obscure variables are the following.
+
+\starttabulate[|lT|l|]
+\HL
+\NC numeric Hstep [] \NC the horizontal distance to the previous area \NC \NR
+\NC numeric Vstep [] \NC the vertical distance to the previous area \NC \NR
+\NC numeric Hsize [] \NC the width of an area \NC \NR
+\NC numeric Vsize [] \NC the height of an area \NC \NR
+\HL
+\stoptabulate
+
+The array variables are accessed by using constants:
+
+\starttabulate[|l|l|]
+\HL
+\NC horizontal \NC vertical \NC \NR
+\HL
+\NC LeftEdge \NC Top \NC \NR
+\NC LeftEdgeSeparator \NC TopSeparator \NC \NR
+\NC LeftMargin \NC Header \NC \NR
+\NC LeftMarginSeparator \NC HeaderSeparator \NC \NR
+\NC Text \NC Text \NC \NR
+\NC RightMarginSeparator \NC FooterSeparator \NC \NR
+\NC RightMargin \NC Footer \NC \NR
+\NC RightEdgeSeparator \NC BottomSeparator \NC \NR
+\NC RightEdge \NC Bottom \NC \NR
+\HL
+\stoptabulate
+
+In addition to these, there are \type {Margin}, \type {InnerMargin} and \type
+{OuterMargin} which adapt themselves to the current odd or even page. The same is
+true for \type {Edge}, \type {InnerEdge} and \type {OuterEdge}, although these
+will seldom be used, since interactive documents are always single sided.
+
+We started this chapter with spending a lot of code to simulate the page areas.
+It will be clear now that in practice this is much easier using the mechanism
+described here.
+
+\placefigure
+ [here][fig:back 5]
+ {A quick way to draw all used areas.}
+ {\setupexternalfigures[background=color,backgroundcolor=white]%
+ \startcombination
+ {\typesetfile[mfun-900.tex][page=10,width=.4\textwidth]}{even}
+ {\typesetfile[mfun-900.tex][page=11,width=.4\textwidth]}{odd}
+ \stopcombination}
+
+In \in {figure} [fig:back 5] we see all used areas. Areas that are not used are
+not drawn (which saves some testing). This background was defined as:
+
+\typebuffer[back-5]
+
+We use two nested \type {for} loops to step over the areas. A \type {for} loop
+with a step of~1 will fail, because the indices are defined in a rather special
+way. On the other hand, the mechanism is rather tolerant, in the sense that \type
+{[i][j]} and \type {[j][i]} are both accepted.
+
+\stopsection
+
+\startsection[title={Bleeding}]
+
+\index {bleeding}
+
+If you want to share your document all over the world, it makes sense to use a
+paper format like {\em letter} or {\em A4}. In that case, the layout often
+matches the paper size.
+
+\startlinecorrection[blank]
+\startMPcode
+ path p ; p := fullcircle xyscaled (21mm,29.7mm) ;
+ path q ; q := boundingbox p ;
+ fill q withcolor .625white ;
+ fill p withcolor .625yellow ;
+ currentpicture := currentpicture shifted (-31mm,0) ;
+ fill q withcolor .625white ;
+ fill p xsized (bbwidth(p)-2mm) withcolor .625yellow ;
+ currentpicture := currentpicture shifted (-31mm,0) ;
+ fill q withcolor .625white ;
+ fill p withcolor .625yellow ;
+ draw q enlarged -1mm withpen pencircle scaled 2mm withcolor .625white ;
+\stopMPcode
+\stoplinecorrection
+
+The left picture demonstrates what happens when you have a printer that is
+capable of printing from edge to edge. If you have such a printer, you're lucky.
+The middle picture demonstrates what happens if you have a properly set up
+printing program and|/|or printer: the page is scaled down so that the content
+fits into the non printable area of the printer. One reason why printers don't
+print from edge to edge is that the engine is not that happy when toner or ink
+ends up next to the page. The third picture shows what happens when a printer
+simply ignores content that runs over the non printable area. In many cases it's
+best to make sure that the content leaves a margin of 5mm from the edges.
+
+Books and magazines seldom use the popular desk||top paper sizes. Here the
+designer determined the paper size and layout more or less independent from the
+size of the sheet on which the result is printed. Instead of one page per sheet,
+arrangements of 2 upto 32 or more pages per sheet are made. The process of
+arranging pages in such a way that these sheets can be folded and combined into
+books is called page imposition. \CONTEXT\ supports a wide range of page
+imposition schemes. More information on this can be found in the \CONTEXT\
+manuals.
+
+The fact that the sheet on which a page is printed is larger than the page itself
+opens the possibility to use the full page for content. In that case, especially
+when you use background graphics, you need to make sure that indeed the page is
+covered completely. Where in desk top printing you can get away with imperfection
+simply because the printing engines have their limitations, in professional
+output you need to be more considerate.
+
+\startlinecorrection[blank]
+\startMPcode
+ path p ; p := fullsquare xyscaled (4cm,5cm) ;
+ path q ; q := fullsquare xyscaled (3cm,4cm) ;
+ path r ; r := fullsquare xyscaled (2cm,3cm) shifted (-.5cm,.5cm) ;
+ fill p withcolor .625white ;
+ fill q withcolor .850white ;
+ currentpicture := currentpicture shifted (-45mm,0) ;
+ fill p withcolor .625white ;
+ fill q withcolor .850white ;
+ fill r withcolor transparent(1,.5,.625yellow) ;
+ currentpicture := currentpicture shifted (-45mm,0) ;
+ fill p withcolor .625white ;
+ fill q withcolor .850white ;
+ r := r topenlarged 2mm leftenlarged 2mm ;
+ fill r withcolor transparent(1,.5,.625yellow) ;
+\stopMPcode
+\stoplinecorrection
+
+Slightly enlarging a graphic so that it exceeds the natural page limits is called
+bleeding. Because quite often layout elements have a rectangular nature,
+\METAFUN\ provides a couple of operations that can save you some work in defining
+bleeding boxes.
+
+\startbuffer
+path p, q ;
+def ShowPath =
+ fill p withcolor transparent(1,.5,.625yellow) ;
+ fill q withcolor transparent(1,.5,.625yellow) ;
+ currentpicture := currentpicture shifted (-25mm,0) ;
+enddef ;
+p := q := fullsquare xyscaled (2cm,3cm) ; ShowPath ;
+p := p leftenlarged 2mm ; ShowPath ;
+p := p topenlarged 2mm ; ShowPath ;
+p := p rightenlarged 2mm ; ShowPath ;
+p := p bottomenlarged 2mm ; ShowPath ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+This graphic is generated as follows:
+
+\typebuffer
+
+The trick is in the last couple of lines. In addition to the general \type
+{enlarged} operator, we have 4~operators that enlarge a rectangle in a certain
+direction. This means that we can define the original path using dimensions
+related to the layout, and add bleed strips independently.
+
+\startbuffer
+path p ; p := fullsquare xyscaled (4cm,1cm) ;
+path q ; q := p leftenlarged 2mm topenlarged 2mm ;
+fill p withcolor transparent(1,.5,.625yellow) ;
+fill q withcolor transparent(1,.5,.625yellow) ;
+draw boundingbox currentpicture withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+This example demonstrates that when we enlarge a graphic, the bounding box also
+gets larger. Because this can interfere with the placement of such a graphic, we
+need to make sure that the bleeding is there but not seen.
+
+\startbuffer
+path p ; p := fullsquare xyscaled (4cm,1cm) ;
+path q ; q := p leftenlarged 2mm topenlarged 2mm ;
+fill p withcolor transparent(1,.5,.625yellow) ;
+fill q withcolor transparent(1,.5,.625yellow) ;
+setbounds currentpicture to p ;
+draw boundingbox currentpicture withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+There are two more operators: \type {innerenlarged} and \type {outerenlarged}.
+These expand to either \type {leftenlarged} or \type {rightenlarged}, depending
+on the page being left or right hand.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-backpage.tex b/doc/context/sources/general/manuals/metafun/metafun-backpage.tex
new file mode 100644
index 000000000..82931d756
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-backpage.tex
@@ -0,0 +1,53 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\doifmode{book}{\endinput}
+
+\startcomponent metafun-backpage
+
+\environment metafun-environment
+
+\startstandardmakeup[doublesided=no,page=right]
+ % back page
+\stopstandardmakeup
+
+\setupbackgrounds
+ [leftpage]
+ [background=back page]
+
+\definecolor[twhite][s=1,t=.80,a=1]
+
+\setupbackgrounds
+ [text][text]
+ [background=color,
+ backgroundcolor=twhite,
+ backgroundoffset=.5cm]
+
+\setuplayout
+ [cutspace=2cm,
+ backspace=8cm,
+ header=0pt,
+ footer=0pt,
+ topspace=17cm,
+ bottomspace=2cm]
+
+\startstandardmakeup[doublesided=no,page=left,top=,bottom=]
+
+ \switchtobodyfont[big]
+
+ \setupinterlinespace[stretch=.5]
+
+ \getbuffer[backtext]
+
+ \blank
+
+ \getbuffer[backbanner]
+
+\stopstandardmakeup
+
+\setupbackgrounds
+ [rightpage]
+ [background=]
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-basics.tex b/doc/context/sources/general/manuals/metafun/metafun-basics.tex
new file mode 100644
index 000000000..df556e239
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-basics.tex
@@ -0,0 +1,3587 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-basics
+
+\environment metafun-environment
+
+\startchapter[title={A few more details}]
+
+\startintro
+
+In this chapter we will see how to define a \METAPOST\ graphic, and how to
+include it in a document. Since the exact dimensions of graphics play an
+important role in the placement of a graphic, we will explore the way a bounding
+box is constructed.
+
+We will also pay attention to the usage of units and the side effects of scaling
+and shifting, since they can contradict our expectations in unexpected ways.
+Furthermore we will explore a few obscure areas.
+
+\stopintro
+
+\startsection[title={Making graphics}]
+
+\index{graphics}
+
+In this manual we will use \METAPOST\ in a rather straightforward way, and we
+will try to avoid complicated math as much as possible. We will do a bit of
+drawing, clipping, and moving around. Occasionally we will see some more
+complicated manipulations.
+
+When defined as stand||alone graphic, a \METAPOST\ file looks like this:
+
+\starttyping
+% Let's draw a circle.
+
+beginfig (7) ;
+ draw fullcircle scaled 3cm withpen pencircle scaled 1cm ;
+endfig ;
+
+end .
+\stoptyping
+
+The main structuring components in such a file are the \type {beginfig} and \type
+{endfig} macros. Like in a big story, the file has many sub||sentences, where
+each sub||sentence ends with a semi||colon. Although the \type {end} command at
+the end of the file concludes the story, putting a period there is a finishing
+touch. Actually, after the \type {end} command you can put whatever text you
+wish, your comments, your grocery list, whatever. Comments in \METAPOST, prefixed
+by a percent sign, as in \typ {% Let's draw a circle}, are ignored by the
+interpreter, but useful reminders for the programmer.
+
+If the file is saved as \type {yourfile.mp}, then the file is processed by
+\METAPOST\ by issuing the following command:
+
+\starttyping
+mpost yourfile
+\stoptyping
+
+after which you will have a graphic called \type {yourfile.7}, which contains a
+series of \POSTSCRIPT\ commands. Because \METAPOST\ does all the work, this file
+is efficient and compact. The number of distinct \POSTSCRIPT\ operators used is
+limited, which has the advantage that we can postprocess this file rather easily.
+Alternatively \METAPOST\ can generate \SVG\ output. It does when you say
+
+\starttyping
+outputformat := "svg" ;
+\stoptyping
+
+Here we will not go into details about this format. Even \POSTSCRIPT\ is not
+covered in detail as we use \METAPOST\ mostly in embedded form.
+
+We can view this file in a \POSTSCRIPT\ viewer like \GHOSTVIEW\ or convert the
+graphic to \PDF\ (using \type {mptopdf}) and view the result in a suitable \PDF\
+viewer like \ACROBAT. Of course, you can embed such a file in a \CONTEXT\
+document, using a command like:
+
+\starttyping
+\externalfigure[yourfile.7]
+\stoptyping
+
+We will go in more detail about embedding graphics in \in {chapter}
+[sec:embedding].
+
+If you have installed \CONTEXT, somewhere on your system there resides a file
+\type {mp-tool.mp}. If you make a stand||alone graphic, it's best to put the
+following line at the top of your file:
+
+\starttyping
+input mp-tool ; % or input metafun ;
+\stoptyping
+
+By loading this file, the resulting graphic will provide a high resolution
+bounding box, which enables more accurate placement. The file also sets the \typ
+{prologues := 1} so that viewers like \GHOSTVIEW\ can refresh the file when it is
+changed.
+
+Next we will introduce some more \METAPOST\ commands. From now on, we will omit
+the encapsulating \type {beginfig} and \type {endfig} macros. If you want to
+process these examples yourself, you should add those commands yourself, or if
+you use \CONTEXT\ you don't need them at all.
+
+\startbuffer
+pickup pencircle scaled .5cm ;
+draw unitsquare xscaled 8cm yscaled 1cm withcolor .625white ;
+draw origin withcolor .625yellow ;
+pickup pencircle scaled 1pt ;
+draw bbox currentpicture withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+In this example we see a mixture of so called primitives as well as macros. A
+primitive is something hard coded, a built||in command, while a macro is a
+collection of such primitives, packaged in a way that they can be recalled
+easily. Where \type {scaled} is a primitive and \type {draw} a macro, \type
+{unitsquare} is a path variable, an abbreviation for:
+
+\starttyping
+unitsquare = (0,0) -- (1,0) -- (1,1) -- (0,1) -- cycle ;
+\stoptyping
+
+The double dash (\type {--}) is also a macro, used to connect two points with a
+straight line segment. However, \type {cycle} is a primitive, which connects the
+last point of the unitsquare to the first on unitsquare's path. Path variables
+must first be declared, as in:
+
+\starttyping
+path unitsquare ;
+\stoptyping
+
+A large collection of such macros is available when you launch \METAPOST. Consult
+the \METAPOST\ manual for details.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+In the first line of our example, we set the drawing pen to \type {.5cm}. You can
+also specify such a dimension in other units, like points (\type {pt}). When no
+unit is provided, \METAPOST\ will use a big point (\type {bp}) , the \POSTSCRIPT\
+approximation of a point.
+
+The second line does just as it says: it draws a rectangle of certain dimensions
+in a certain color. In the third line we draw a colored dot at the origin of the
+coordinate system in which we are drawing. Finally, we set up a smaller pen and
+draw the bounding box of the current picture, using the variable \type
+{currentpicture}. Normally, all drawn shapes end up in this picture variable.
+
+\stopsection
+
+\startsection[title={Bounding boxes}]
+
+\index{boundingbox}
+
+If you take a close look at the last picture in the previous section, you will
+notice that the bounding box is larger than the picture. This is one of the nasty
+side effects of \METAPOST's \type {bbox} macro. This macro draws a box, but with
+a certain offset. The next example shows how we can manipulate this offset.
+Personally I never use the \type {bbox} macro because this offset is rather
+annoying. Also, the \type {boundingbox} operator combined with \type {enlarged}
+can provide any offset you want.
+
+\startbuffer
+pickup pencircle scaled .5cm ;
+draw unitsquare xscaled 8cm yscaled 1cm withcolor .625white ;
+path bb ; bboxmargin := 0pt ; bb := bbox currentpicture ;
+draw bb withpen pencircle scaled 1pt withcolor .625red ;
+draw origin withpen pencircle scaled 5pt withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+In the third line we define a path variable. We assign the current bounding box
+to this variable, but first we set the offset to zero. The last line demonstrates
+how to draw such a path. Instead of setting the pen as we did in the first line,
+we pass the dimensions directly.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Where \type {draw} draws a path, the \type {fill} macro fills one. In order to be
+filled, a path should be closed, which is accomplished by the \type {cycle}
+primitive, as we saw in constructing the \type {unitsquare} path.
+
+\startbuffer
+pickup pencircle scaled .5cm ;
+fill unitsquare xscaled 8cm yscaled 1cm withcolor .625white ;
+path bb ; bboxmargin := 0pt ; bb := bbox currentpicture ;
+draw bb withpen pencircle scaled 1pt withcolor .625red ;
+draw origin withpen pencircle scaled 5pt withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+This example demonstrates that when we fill the path, the resulting graphic is
+smaller. Where \type {draw} follows the center of a path, \type {fill} stays
+inside the path.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+A third alternative is the \type {filldraw} macro. From the previous examples, we
+would expect a bounding box that matches the one of the drawn path.
+
+\startbuffer
+pickup pencircle scaled .5cm ;
+filldraw unitsquare xscaled 8cm yscaled 1cm withcolor .625white ;
+path bb ; bboxmargin := 0pt ; bb := bbox currentpicture ;
+draw bb withpen pencircle scaled 1pt withcolor .625red ;
+draw origin withpen pencircle scaled 5pt withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+% The resulting graphic has the bounding box of the fill. Note
+% how the path, because it is stroked with a .5cm pen, extends
+% beyond the border of the bounding box. The way this image
+% shows up depends on the viewer (settings) you use to render
+% the graphic. For example, in \GHOSTVIEW, if you disable
+% clipping to the bounding box, only the positive quadrant of
+% the graphic is shown. Further, if you enable clipping to the
+% bounding box, this image will look exactly like the previous
+% image created with the fill command. In many cases, it may
+% be best to avoid the \type {filldraw} command.
+
+The resulting graphic has the bounding box of the fill. Note how the path,
+because it is stroked with a .5cm pen, extends beyond the border of the previous
+bounding box. The way this image shows up depends on the viewer (settings) you
+use to render the graphic. For example, in \GHOSTVIEW, if you disable clipping to
+the bounding box, only the positive quadrant of the graphic is shown. \footnote
+{Old versions of \METAPOST\ calculated the boundingbox differently for a \type
+{filldraw}: through the middle of the penpath.}
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+From the previous examples, you can conclude that the following alternative
+results in a proper bounding box:
+
+\startbuffer
+pickup pencircle scaled .5cm ;
+path p ; p := unitsquare xscaled 8cm yscaled 1cm ;
+fill p withcolor .625white ;
+draw p withcolor .625white ;
+path bb ; bboxmargin := 0pt ; bb := bbox currentpicture ;
+draw bb withpen pencircle scaled 1pt withcolor .625red ;
+draw origin withpen pencircle scaled 5pt withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The \CONTEXT\ distribution comes with a set of \METAPOST\ modules, one of which
+contains the \type {drawfill} macro, which provides the outer bounding box.
+\footnote {Starting from version 1.0 \METAPOST\ calculates the boundingbox
+differently and the distinction between \type {drawfill} and \type {filldraw} is
+gone. We keep them around both for compatibility.} Next we demonstrate its use in
+another, more complicated example.
+
+\startbuffer
+picture finalpicture ; finalpicture := nullpicture ;
+numeric n ; n := 0 ; bboxmargin := 0pt ;
+pickup pencircle scaled .5cm ;
+
+def shape =
+ unitsquare scaled 2cm withcolor .625white ;
+ draw bbox currentpicture
+ withpen pencircle scaled .5mm withcolor .625red ;
+ addto finalpicture also currentpicture shifted(n*3cm,0) ;
+ currentpicture := nullpicture ; n := n+1 ;
+enddef ;
+
+fill shape ; draw shape ; filldraw shape ; drawfill shape ;
+
+currentpicture := finalpicture ;
+\stopbuffer
+
+\typebuffer
+
+Here we introduce a macro definition, \type {shape}. In \METAPOST, the start of a
+macro definition is indicated with the keyword \type {def}. Thereafter, you can
+insert other variables and commands, even other macro definitions. The keyword
+\type {enddef} signals the end of the macro definition. The result is shown in
+\in {figure} [fig:draws and fills]; watch the bounding boxes. Close reading of
+the macro will reveal that the \type {fill}, \type {draw}, \type {filldraw} and
+\type {drawfill} macros are applied to the first \type {unitsquare} path in the
+macro.
+
+\placefigure
+ [here]
+ [fig:draws and fills]
+ {A \type {fill}, \type {draw}, \type {filldraw} and \type
+ {drawfill} applied to the same square.}
+ {\processMPbuffer}
+
+In this macro, \type {bbox} calls a macro that returns the enlarged bounding box
+of a path. By setting \type {bboxmargin} we can influence how much the bounding
+box is enlarged. Since this is an existing variable, we don't have to allocate
+it, like we do with~\type{numeric n}. Unless you take special precautions,
+variables are global by nature and persistent outside macros.
+
+\starttyping
+picture finalpicture ; finalpicture := nullpicture ;
+\stoptyping
+
+Just as \type {numeric} allocates an integer variable, the \type {picture}
+primitive allocates a picture data structure. We explicitly have to set this
+picture to nothing using the built||in primitive \type {nullpicture}.
+
+Later on, we will add the drawn paths as accumulated in \type {currentpicture} to
+this \type {finalpicture} in the following manner.
+
+\starttyping
+addto finalpicture also currentpicture shifted(n*3cm,0) ;
+\stoptyping
+
+Since we want to add a few more and don't want them to overlap, we shift them.
+Therefore we have to erase the current picture as well as increment the shift
+counter.
+
+\starttyping
+currentpicture := nullpicture ; n := n+1 ;
+\stoptyping
+
+The \type {drawfill} macro is one of the \METAFUN\ macros. Another handy macro is
+\type {boundingbox}. When used instead of \type {bbox}, you don't have to set the
+margin to zero.
+
+\startbuffer
+drawoptions (withcolor .625white) ;
+path p ; p := unitsquare scaled 2cm ;
+fill p shifted (3cm,0) ;
+pickup pencircle scaled .5cm ; fill p shifted (6cm,0) ;
+fill p shifted (9cm,0) withpen pencircle scaled .5cm ;
+\stopbuffer
+
+\placefigure
+ [here]
+ [fig:more draws and fills]
+ {The influence of pens on \type {fill}.}
+ {\processMPbuffer}
+
+There is a subtle point in filling a shape. In \in {figure} [fig:more draws and
+fills] you see the influence of the pen on a \type {fill} operation. An indirect
+specification has no influence, and results in a filled rectangle with sharp
+corners. The third rectangle is drawn with a direct pen specification which
+results in a larger shape with rounds corners. However, the bounding box is the
+same in all three cases. The graphic is defined as follows. This time we don't
+use a (complicated) macro.
+
+\typebuffer
+
+When a graphic is constructed, its components end up in an internal data
+structure in a more or less layered way. This means that as long as a graphic is
+not flushed, you may consider it to be a stack of paths and texts with the paths
+being drawn or filled shapes or acting as clipping paths or bounding boxes.
+
+When you ask for the dimensions of a graphic the lower left and upper right
+corner are calculated using this stack. Because you can explicitly set bounding
+boxes, you can lie about the dimensions of a graphic. This is a very useful
+feature. In the rare case that you want to know the truth and nothing but the
+truth, you can tweak the \type {truecorners} numeric variable. We will
+demonstrate this with a few examples.
+
+\startbuffer
+fill fullcircle scaled 1cm withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\ruledhbox{\processMPbuffer}\stoplinecorrection
+
+\startbuffer
+fill fullcircle scaled 1cm withcolor .625yellow ;
+setbounds currentpicture to boundingbox currentpicture enlarged 2mm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\ruledhbox{\processMPbuffer}\stoplinecorrection
+
+\startbuffer
+fill fullcircle scaled 1cm withcolor .625yellow ;
+setbounds currentpicture to boundingbox currentpicture enlarged 2mm ;
+interim truecorners := 1 ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\ruledhbox{\processMPbuffer}\stoplinecorrection
+
+\startbuffer
+fill fullcircle scaled 1cm withcolor .625yellow ;
+interim truecorners := 1 ;
+setbounds currentpicture to boundingbox currentpicture enlarged 2mm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\ruledhbox{\processMPbuffer}\stoplinecorrection
+
+As you can see here, as soon as we set \type {truecorners} to~1, the bounding box
+settings are ignored. \footnote {Normally you will use grouping to keep the
+interim local. In \METAFUN\ each figure restores this variable at the beginning.}
+
+There are two related macros: \type {bbwidth} and \type {bbheight} that you can
+apply to a path.
+
+\startbuffer
+fill unitcircle xscaled 4cm yscaled 2cm
+ withpen pencircle scaled 1mm withcolor .625red ;
+draw origin -- (bbwidth(currentpicture),0)
+ withpen pencircle scaled 1mm withcolor .625yellow ;
+draw origin -- (0,bbheight(currentpicture))
+ withpen pencircle scaled 1mm withcolor .625white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+\stopsection
+
+Yet another helper is \type {boundingcircle}. Its effect can best be demonstrated with
+a few examples:
+
+\startbuffer[a]
+path p ; p := fullsquare scaled 2cm ;
+
+draw p withpen pencircle scaled 3mm withcolor .625white ;
+draw center p withpen pencircle scaled 3mm withcolor .625white ;
+draw boundingbox p withpen pencircle scaled 1mm withcolor .625red ;
+draw boundingcircle p withpen pencircle scaled 1mm withcolor .625yellow ;
+\stopbuffer
+
+\startbuffer[b]
+path p ; p := fullcircle scaled 2cm ;
+
+draw p withpen pencircle scaled 3mm withcolor .625white ;
+draw center p withpen pencircle scaled 3mm withcolor .625white ;
+draw boundingbox p withpen pencircle scaled 1mm withcolor .625red ;
+draw boundingcircle p withpen pencircle scaled 1mm withcolor .625yellow ;
+\stopbuffer
+
+\startbuffer[c]
+path p ; p := fulltriangle scaled 2cm ;
+
+draw p withpen pencircle scaled 3mm withcolor .625white ;
+draw center p withpen pencircle scaled 3mm withcolor .625white ;
+draw boundingbox p withpen pencircle scaled 1mm withcolor .625red ;
+draw boundingcircle p withpen pencircle scaled 1mm withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer[a,b,c]
+
+You can consider the \type {boundingcircle} to be a round boundingbox.
+
+\startlinecorrection
+\startcombination[nx=3,ny=1,location=middle]
+ {\processMPbuffer[a]} {square}
+ {\processMPbuffer[b]} {circle}
+ {\processMPbuffer[c]} {triangle}
+\stopcombination
+\stoplinecorrection
+
+\startsection[title={Units}]
+
+\index{units}
+
+Like \TEX, \METAPOST\ supports multiple units of length. In \TEX, these units are
+hard coded and handled by the parser, where the internal unit of length is the
+scaled point (\type {sp}), something on the nanometer range. Because \METAPOST\
+is focused on \POSTSCRIPT\ output, its internal unit is the big point (\type
+{bp}). All other units are derived from this unit and available as numeric
+instead of hard coded.
+
+\starttyping
+mm = 2.83464 ; pt = 0.99626 ; dd = 1.06601 ; bp := 1 ;
+cm = 28.34645 ; pc = 11.95517 ; cc = 12.79213 ; in := 72 ;
+\stoptyping
+
+Careful reading reveals that only the \type {bp} and \type {in} are fixed, while
+the rest of the dimensions are scalar multiples of \type {bp}.
+
+Since we are dealing with graphics, the most commonly used dimensions are \type
+{pt}, \type {bp}, \type {mm}, \type {cm} and~\type {in}.
+
+\startuseMPgraphic{pt}
+ fill fullsquare scaled 72.27pt withcolor .625yellow ;
+ fill fullcircle scaled 72.27pt withcolor white ;
+ label("72.27pt", center currentpicture) ;
+\stopuseMPgraphic
+\startuseMPgraphic{bp}
+ fill fullsquare scaled 72bp withcolor .625yellow ;
+ fill fullcircle scaled 72bp withcolor white ;
+ label("72bp", center currentpicture) ;
+\stopuseMPgraphic
+\startuseMPgraphic{mm}
+ fill fullsquare scaled 25.4mm withcolor .625yellow ;
+ fill fullcircle scaled 25.4mm withcolor white ;
+ label("25.4mm", center currentpicture) ;
+\stopuseMPgraphic
+\startuseMPgraphic{cm}
+ fill fullsquare scaled 2.54cm withcolor .625yellow ;
+ fill fullcircle scaled 2.54cm withcolor white ;
+ label("2.54cm", center currentpicture) ;
+\stopuseMPgraphic
+\startuseMPgraphic{in}
+ fill fullsquare scaled 1in withcolor .625yellow ;
+ fill fullcircle scaled 1in withcolor white ;
+ label("1in", center currentpicture) ;
+\stopuseMPgraphic
+
+\startlinecorrection[blank]
+\hbox to \hsize
+ {\useMPgraphic{pt}\hss
+ \useMPgraphic{bp}\hss
+ \useMPgraphic{mm}\hss
+ \useMPgraphic{cm}\hss
+ \useMPgraphic{in}}
+\stoplinecorrection
+
+The text in the center of the leftmost graphic is typeset by \METAPOST\ as a
+label.
+
+\starttyping
+fill fullsquare scaled 72.27pt withcolor .625yellow ;
+fill fullcircle scaled 72.27pt withcolor white ;
+label("72.27pt", center currentpicture) ;
+\stoptyping
+
+In \METAPOST\ the following lines are identical:
+
+\starttyping
+draw fullcircle scaled 100 ;
+draw fullcircle scaled 100bp ;
+\stoptyping
+
+You might be tempted to omit the unit, but this can be confusing, particularly if
+you also program in a language like \METAFONT, where the \type {pt} is the base
+unit. This means that a circle scaled to 100 in \METAPOST\ is not the same as a
+circle scaled to 100 in \METAFONT. Consider the next definition:
+
+\startbuffer
+pickup pencircle scaled 0 ;
+fill unitsquare
+ xscaled 400pt yscaled -.5cm withcolor .625red ;
+fill unitsquare
+ xscaled 400bp yscaled +.5cm withcolor .625yellow ;
+drawoptions(withcolor white) ;
+label.rt("400 pt", origin shifted (0, -.25cm)) ;
+label.rt("400 bp", origin shifted (0, +.25cm)) ;
+\stopbuffer
+
+\typebuffer
+
+When processed, the difference between a \type {pt} and \type {bp} shows rather
+well. Watch how we use \type {.rt} to move the label to the right; you can
+compare this with \TEX's macro \type {\rlap}. You might want to experiment with
+\type {.lft}, \type {.top}, \type {.bot}, \type {.ulft}, \type {.urt}, \type
+{.llft} and \type {.lrt}.
+
+The difference between both bars is exactly \scratchdimen = 400 bp
+\advance\scratchdimen by -400 pt \the \scratchdimen \space (as calculated by
+\TEX).
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Where \TEX\ is anchored in tradition, and therefore more or less uses the \type
+{pt} as the default unit, \METAPOST, much like \POSTSCRIPT, has its roots in the
+computer sciences. There, to simplify calculations, an inch is divided in 72 big
+points, and .72pt is sacrificed.
+
+When you consider that \POSTSCRIPT\ is a high end graphic programming language,
+you may wonder why this sacrifice was made. Although the difference between \type
+{1bp} and \type {1pt} is miniscule, this difference is the source of much
+(unknown) confusion. When \TEX\ users talk about a \type {10pt} font, a desktop
+publisher hears \type {10bp}. In a similar vein, when we define a papersize
+having a width of \type {600pt} and a height of \type {450pt}, which is papersize
+\type {S6} in \CONTEXT, a \POSTSCRIPT\ or \PDF\ viewer will report slightly
+smaller values as page dimensions. This is because those programs claim the \type
+{pt} to be a \type {bp}. [This confusion can lead to interesting discussions with
+desktop publishers when they have to use \TEX. They often think that their demand
+of a baseline distance of \type {13.4} is met when we set it to \type {13.4pt},
+while actually they were thinking of \type {13.4bp}, which of course in other
+programs is specified using a \type {pt} suffix.]
+
+Therefore, when embedding graphics in \CONTEXT, we strongly recommend that you
+use \type {pt} as the base unit instead. The main reason why we spend so many
+words on this issue is that, when neglected, large graphics may look inaccurate.
+Actually, when taken care of, it is one of the (many) reasons why \TEX\ documents
+always look so accurate. Given that the eye is sensitive to distortions of far
+less than \type {1pt}, you can be puzzled by the fact that many drawing programs
+only provide a bounding box in rounded units. Thereby, they round to the next
+position, to prevent unwanted cropping. For some reason this low resolution has
+made it into the high end \POSTSCRIPT\ standard.
+
+In \CONTEXT\ we try to deal with these issues as well as possible.
+
+\stopsection
+
+\startsection[title={Scaling and shifting}]
+
+\index{scaling}
+\index{shifting}
+
+When we draw a shape, \METAPOST\ will adapt the bounding box accordingly. This
+means that a graphic has its natural dimensions, unless of course we adapt the
+bounding box manually. When you limit your graphic to a simple shape, say a
+rectangle, shifting it to some place can get obscured by this fact. Therefore,
+the following series of shapes appear to be the same.
+
+\startbuffer
+draw
+ unitsquare xscaled 6cm yscaled 1.5cm
+ withpen pencircle scaled 2mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+\startbuffer
+draw
+ unitsquare shifted (.5,.5) xscaled 6cm yscaled 1.5cm
+ withpen pencircle scaled 2mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+\startbuffer
+draw
+ unitsquare shifted (-.5,-.5) xscaled 6cm yscaled 1.5cm
+ withpen pencircle scaled 2mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+\startbuffer
+draw
+ unitsquare xscaled 6cm yscaled 1.5cm shifted (1cm,1cm)
+ withpen pencircle scaled 2mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+\startbuffer
+draw
+ unitsquare xscaled 6cm yscaled 1.5cm shifted (1.5cm,1cm)
+ withpen pencircle scaled 2mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+However, when we combine such graphics into one, we will see in what respect the
+scaling and shifting actually takes place.
+
+\startbuffer
+draw
+ unitsquare xscaled 6cm yscaled 2cm
+ withpen pencircle scaled 3.0mm withcolor .625yellow ;
+draw
+ unitsquare shifted (.5,.5) xscaled 6cm yscaled 2cm
+ withpen pencircle scaled 3.0mm withcolor .625red ;
+draw
+ unitsquare xscaled 6cm yscaled 2cm shifted (1cm,1cm)
+ withpen pencircle scaled 3.0mm withcolor .625white ;
+draw
+ unitsquare xscaled 6cm yscaled 2cm shifted (1.5cm,1cm)
+ withpen pencircle scaled 1.5mm withcolor white ;
+draw
+ unitsquare shifted (-.5,-.5) xscaled 6cm yscaled 2cm
+ withpen pencircle scaled 1mm withcolor black ;
+draw origin withpen pencircle scaled 1mm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+As you can see, the transformations are applied in series. Sometimes this is not
+what we want, in which case we can use parentheses to force the desired
+behaviour. The lesson learned is that {\em scaling and shifting} is not always
+the same as {\em shifting and scaling}.
+
+\startbuffer
+draw
+ origin -- origin shifted ((4cm,0cm) shifted (4cm,0cm))
+ withpen pencircle scaled 1cm withcolor .625white ;
+draw
+ origin -- origin shifted (4cm,0cm) shifted (4cm,0cm)
+ withpen pencircle scaled 8mm withcolor .625yellow ;
+draw
+ (origin -- origin shifted (4cm,0cm)) shifted (4cm,0cm)
+ withpen pencircle scaled 6mm withcolor .625red ;
+draw
+ origin -- (origin shifted (4cm,0cm) shifted (4cm,0cm))
+ withpen pencircle scaled 4mm withcolor white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+Especially when a path results from a call to a macro, using parentheses around a
+path may help, as in the following example.
+
+\startbuffer
+def unitslant = origin -- origin shifted (1,1) enddef ;
+draw
+ unitslant xscaled 5cm yscaled 1cm
+ withpen pencircle scaled 1cm withcolor .625red ;
+draw
+ (unitslant) xscaled 5cm yscaled 1cm
+ withpen pencircle scaled 5mm withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+The next definition of \type {unitslant} is therefore better.
+
+\startbuffer
+def unitslant = (origin -- origin shifted (1,1)) enddef ;
+draw
+ unitslant xscaled 5cm yscaled 1cm
+ withpen pencircle scaled 5mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+An even better alternative is:
+
+\startbuffer
+path unitslant ; unitslant = origin -- origin shifted (1,1) ;
+draw
+ unitslant xscaled 5cm yscaled 1cm
+ withpen pencircle scaled 5mm withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Curve construction}]
+
+\index{curves}
+
+\doifmodeelse{screen}
+ {\def\Xcom{3}\def\Ycom{2}\def\Zcom{\the\textheight}}
+ {\def\Xcom{2}\def\Ycom{3}\def\Zcom{\the\textwidth }}
+
+Chapter 3 of the \METAFONT\ book explains the mathematics behind the construction
+of curves. Both \METAFONT\ and \METAPOST\ implement B\'ezier curves. The fact
+that these curves are named after Pierre B\'ezier obscures the fact that the math
+behind them originates with Serge\u{\i} Bernshte\u{\i}n.
+
+The points on the curve are determined by the following formula:
+
+\placeformula[-]
+\startformula
+z(t) = (1-t)^3 z_1 + 3 (1-t)^2 t z_2 + 3 (1-t) t^2 z_3 + t^3 z_4
+\stopformula
+
+Here, the parameter $t$ runs from $[0,1]$. As you can see, we are dealing with
+four points. In practice this means that when we construct a curve from multiple
+points, we act on two points and the two control points in between. So, the
+segment that goes from $z_1$ to $z_4$ is calculated using these two points and
+the points that \METAFONT|/|\METAPOST\ calls post control point and pre control
+point.
+
+\startbuffer[a]
+vardef dodrawmidpoints (expr a, b, c, d, n, col, m) =
+ save e, f, g, h, i, j ; pair e, f, g, h, i, j ;
+ e := .5[a,b] ; f := .5[b,c] ; g := .5[c,d] ;
+ h := .5[e,f] ; i := .5[f,g] ; j := .5[h,i] ;
+ if m= 0 : drawpoints j elseif
+ m= 1 : draw a--b--c--d elseif
+ m= 2 : draw e--f--g elseif
+ m= 3 : draw h--i elseif
+ m= 4 : draw a--e--h--j elseif
+ m= 5 : draw j--i--g--d elseif
+ m=11 : drawpoints a--b--c--d elseif
+ m=12 : drawpoints e--f--g elseif
+ m=13 : drawpoints h--i elseif
+ m=14 : drawpoints a--e--h--j elseif
+ m=15 : drawpoints j--i--g--d fi withcolor col ;
+ if n>1 :
+ dodrawmidpoints(a, e, h, j, n-1, col, m) ;
+ dodrawmidpoints(j, i, g, d, n-1, col, m) ;
+ fi ;
+enddef ;
+
+vardef drawmidpoints (expr p, n, col, m) =
+ save a, b, c, d ; pair a, b, c, d ;
+ for x=0 upto length(p)-1 :
+ a := point x of p ; b := postcontrol x of p ;
+ d := point x+1 of p ; c := precontrol x+1 of p ;
+ dodrawmidpoints(a,b,c,d,n,col,m) ;
+ endfor ;
+enddef ;
+\stopbuffer
+
+\startbuffer[b]
+path p ; p := (4cm,4cm)..(6cm,0cm)..(1cm,2cm) ;
+\stopbuffer
+
+\startbuffer[c]
+drawpath p ;
+drawcontrollines p withcolor .625yellow ;
+drawcontrolpoints p withcolor .625red ;
+drawpoints p withcolor .625red ;
+freelabel(btex $z_1$ etex, point 0 of p, center p) ;
+freelabel(btex $z_2$ etex, postcontrol 0 of p, center p) ;
+freelabel(btex $z_3$ etex, precontrol 1 of p, center p) ;
+freelabel(btex $z_4$ etex, point 1 of p, center p) ;
+freelabel(btex $z_5$ etex, postcontrol 1 of p, center p) ;
+freelabel(btex $z_6$ etex, precontrol 2 of p, center p) ;
+freelabel(btex $z_7$ etex, point 2 of p, center p) ;
+\stopbuffer
+
+\startbuffer[x]
+draw boundingbox p enlarged 1cm ;
+setbounds currentpicture to boundingbox p enlarged 1cm ;
+currentpicture := currentpicture xsized (.45*\Zcom) ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,x]
+\stoplinecorrection
+
+The previous curve is constructed from the three points $z_1$, $z_4$ and $z_7$.
+The curve is drawn in \METAPOST\ by \type {z1..z4..z7} and is made up out of two
+segments. The first segment is determined by the following points:
+
+\startitemize[packed,n]
+\item point $z_1$ of the curve
+\item the postcontrol point $z_2$ of $z_1$
+\item the precontrol point $z_3$ of $z_4$
+\item point $z_4$ of the curve
+\stopitemize
+
+On the next pages we will see how the whole curve is constructed from these
+quadruples of points. The process comes down to connecting the mid points of the
+straight lines to the points mentioned. We do this three times, which is why
+these curves are classified as third order approximations.
+
+The first series of graphics demonstrates the process of determining the mid
+points. The third order midpoint is positioned on the final curve. The second
+series focuses on the results: new sets of four points that will be used in a
+next stage. The last series only shows the third order midpoints. As you can see,
+after some six iterations we have already reached a rather good fit of the final
+curve. The exact number of iterations depends on the resolution needed. You will
+notice that the construction speed (density) differs per segment.
+
+\startpostponing
+
+% cc .. hh in order to avoid conflicts with c-...
+
+\startbuffer[cc]
+drawpath p ; drawpoints p ; drawcontrolpoints p ;
+\stopbuffer
+
+\startbuffer[dd]
+drawmidpoints(p,1,.625red, 11) ; drawmidpoints(p,1,.625yellow, 1) ;
+\stopbuffer
+
+\startbuffer[ee]
+drawmidpoints(p,1,.625red, 12) ; drawmidpoints(p,1,.625yellow, 2) ;
+\stopbuffer
+
+\startbuffer[ff]
+drawmidpoints(p,1,.625red, 13) ; drawmidpoints(p,1,.625yellow, 3) ;
+\stopbuffer
+
+\startbuffer[gg]
+drawmidpoints(p,1,.625red, 14) ; drawmidpoints(p,1,.625yellow, 4) ;
+\stopbuffer
+
+\startbuffer[hh]
+drawmidpoints(p,1,.625red, 15) ; drawmidpoints(p,1,.625yellow, 5) ;
+\stopbuffer
+
+\startbuffer
+\startcombination[\Xcom*\Ycom]
+ {\processMPbuffer[a,b,cc,x]} {points}
+ {\processMPbuffer[a,b,cc,dd,x]} {first order curve}
+ {\processMPbuffer[a,b,cc,dd,ee,x]} {second order curve}
+ {\processMPbuffer[a,b,cc,dd,ee,ff,x]} {third order curve}
+ {\processMPbuffer[a,b,cc,dd,ee,gg,x]} {left side curves}
+ {\processMPbuffer[a,b,cc,dd,ee,hh,x]} {right side curves}
+\stopcombination
+\stopbuffer
+
+\getbuffer \page
+
+\startbuffer[dd]
+drawmidpoints(p,1,.625red, 11) ;
+drawmidpoints(p,1,.625yellow, 1) ;
+\stopbuffer
+
+\startbuffer[ee]
+for i=11, 12 : drawmidpoints(p,1,.625red, i) ; endfor ;
+drawmidpoints(p,1,.625yellow, 2) ;
+\stopbuffer
+
+\startbuffer[ff]
+for i=11, 12, 13 : drawmidpoints(p,1,.625red, i) ; endfor ;
+drawmidpoints(p,1,.625yellow, 3) ;
+\stopbuffer
+
+\startbuffer[gg]
+for i=11,12,13,14 : drawmidpoints(p,1,.625red, i) ; endfor ;
+drawmidpoints(p,1,.625yellow, 4) ;
+\stopbuffer
+
+\startbuffer[hh]
+for i=11, 12, 13, 14, 15 : drawmidpoints(p,1,.625red, i) ; endfor ;
+drawmidpoints(p,1,.625yellow, 5) ;
+\stopbuffer
+
+\startbuffer
+\startcombination[\Xcom*\Ycom]
+ {\processMPbuffer[a,b,cc,x]} {points}
+ {\processMPbuffer[a,b,cc,dd,x]} {first order points}
+ {\processMPbuffer[a,b,cc,ee,x]} {second order points}
+ {\processMPbuffer[a,b,cc,ff,x]} {third order points}
+ {\processMPbuffer[a,b,cc,gg,x]} {left side points}
+ {\processMPbuffer[a,b,cc,hh,x]} {right side points}
+\stopcombination
+\stopbuffer
+
+\getbuffer \page
+
+\startbuffer[cc]
+drawpath p ; drawmidpoints (p,1,.625yellow, 0) ;
+\stopbuffer
+
+\startbuffer[dd]
+drawpath p ; drawmidpoints (p,2,.625yellow, 0) ;
+\stopbuffer
+
+\startbuffer[ee]
+drawpath p ; drawmidpoints (p,3,.625yellow, 0) ;
+\stopbuffer
+
+\startbuffer[ff]
+drawpath p ; drawmidpoints (p,4,.625yellow, 0) ;
+\stopbuffer
+
+\startbuffer[gg]
+drawpath p ; drawmidpoints (p,5,.625yellow, 0) ;
+\stopbuffer
+
+\startbuffer[hh]
+drawpath p ; drawmidpoints (p,6,.625yellow, 0) ;
+\stopbuffer
+
+\startbuffer
+\startcombination[\Xcom*\Ycom]
+ {\processMPbuffer[a,b,cc,x]} {first iteration}
+ {\processMPbuffer[a,b,cc,dd,x]} {second iteration}
+ {\processMPbuffer[a,b,cc,dd,ee,x]} {third iteration}
+ {\processMPbuffer[a,b,cc,dd,ee,ff,x]} {fourth iteration}
+ {\processMPbuffer[a,b,cc,dd,ee,ff,gg,x]} {fifth iteration}
+ {\processMPbuffer[a,b,cc,dd,ee,ff,gg,hh,x]} {sixths iteration}
+\stopcombination
+\stopbuffer
+
+\getbuffer \page
+
+\stoppostponing
+
+% here we pick up the thread, if we would not flush the
+% pages before the next text, the reader could become
+% confused
+
+The path in these examples is defined as follows:
+
+\typebuffer[b]
+
+If you are playing with graphics like this, the \METAFUN\ macro \type {randomize}
+may come in handy:
+
+\startbuffer[bb]
+p := p randomized (1cm,.5cm) ;
+\stopbuffer
+
+\typebuffer[bb]
+
+If we apply this operation a couple of times we can see how the (control) points
+vary. (Using the randomizer saves us the troubles of finding nice example
+values.) The angle between the tangent as well as the distance from the parent
+point determine the curve.
+
+\startbuffer[xx]
+currentpicture := currentpicture scaled .5 ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\hbox to \hsize
+ {\processMPbuffer[a,b,bb,c,x,xx]\hss
+ \processMPbuffer[a,b,bb,c,x,xx]\hss
+ \processMPbuffer[a,b,bb,c,x,xx]\hss
+ \processMPbuffer[a,b,bb,c,x,xx]}
+\stoplinecorrection
+
+% new thread
+
+Just in case you are interested in how such graphical simulations can be
+organized, we show simplified versions of the macros used here. (In the previous
+examples we minimized the complexity of the code by using buffers, but describing
+this mechanism is out of the scope of this section.)
+
+\startbuffer[demo]
+vardef dodrawmidpoints (expr a, b, c, d, n) =
+ save e, f, g, h, i, j ; pair e, f, g, h, i, j ;
+ e := .5[a,b] ; f := .5[b,c] ; g := .5[c,d] ;
+ h := .5[e,f] ; i := .5[f,g] ; j := .5[h,i] ;
+ draw j ;
+ if n>1 :
+ dodrawmidpoints(a, e, h, j, n-1) ;
+ dodrawmidpoints(j, i, g, d, n-1) ;
+ fi ;
+enddef ;
+
+vardef drawmidpoints (expr p, n) =
+ save a, b, c, d ; pair a, b, c, d ;
+ for x=0 upto length(p)-1 :
+ a := point x of p ; b := postcontrol x of p ;
+ d := point x+1 of p ; c := precontrol x+1 of p ;
+ dodrawmidpoints(a, b, c, d, n) ;
+ endfor ;
+enddef ;
+\stopbuffer
+
+We need to loop over all segments of a curve, where for each segment the left and
+right side sub curves are handled recursively, upto the requested depth (denoted
+as \type {n}). For this we define the following macros.
+
+\typebuffer[demo]
+
+\startbuffer[zero]
+drawoptions (withpen pencircle scaled 5pt withcolor .625red);
+\stopbuffer
+
+\startbuffer[extra]
+drawoptions (withpen pencircle scaled 5pt withcolor .625yellow);
+\stopbuffer
+
+We apply this macro to a simple shape:
+
+\startbuffer[one]
+drawmidpoints (fullcircle xscaled 300pt yscaled 50pt, 1) ;
+\stopbuffer
+
+\typebuffer[one]
+
+When drawn, this results in the points that makes up the
+curve:
+
+\startlinecorrection[blank]
+\processMPbuffer[demo,zero,one]
+\stoplinecorrection
+
+We now add an extra iteration (resulting in the yellow points):
+
+\startbuffer[two]
+drawmidpoints (fullcircle xscaled 300pt yscaled 50pt, 2) ;
+\stopbuffer
+
+\typebuffer[two]
+
+and get:
+
+\startlinecorrection[blank]
+\processMPbuffer[demo,zero,two,extra,one]
+\stoplinecorrection
+
+We don't even need that much iterations to get a good result. The depth needed to
+get a good result depends on the size of the pen and the resolution of the device
+on which the curve is visualized.
+
+\startbuffer[zero]
+drawoptions (withpen pencircle scaled 2pt withcolor .625red) ;
+\stopbuffer
+
+\startbuffer[three]
+for i=1 upto 7 :
+ drawmidpoints (fullcircle
+ xscaled (300pt+i*10pt) yscaled (50pt+i*10pt), i) ;
+endfor ;
+\stopbuffer
+
+\typebuffer[three]
+
+Here we show 7 iterations in one graphic.
+
+\startlinecorrection[blank]
+\processMPbuffer[demo,zero,three]
+\stoplinecorrection
+
+In practice it is not that trivial to determine the depth needed. The next
+example demonstrates how the resolution of the result depends on the length and
+nature of the segment.
+
+\startbuffer[four]
+drawmidpoints (fullsquare
+ xscaled 300pt yscaled 50pt randomized (20pt,10pt), 5) ;
+\stopbuffer
+
+\typebuffer[four]
+
+\startlinecorrection[blank]
+\processMPbuffer[demo,zero,four]
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Inflection, tension and curl}]
+
+\index{inflection}
+\index{tension}
+\index{curl}
+
+The \METAPOST\ manual describes the meaning of \type {...} as \quotation {choose
+an inflection||free path between these points unless the endpoint directions make
+this impossible}. To use the words of David Arnold: a point of inflection is
+where a path switches concavity, from concave up to concave down, for example.
+
+It is surprisingly difficult to find nice examples that demonstrate the
+difference between \type {..} and \type {...}, as it is often \quote {impossible}
+to honour the request for less inflection. We will demonstrate this with a few
+graphics.
+
+In the four figures on the next pages, you will see that \type {...} is not
+really suited for taming wild curves. If you really want to make sure that a
+curve stays within certain bounds, you have to specify it as such using control
+or intermediate points. In the figures that follow, the gray curves draw the
+random path using \type {..} on top of yellow curves that use the \type {...}
+connection. As you can see, in only a few occasions do the yellow \quote
+{inflection} free curves show up.
+
+For those who asked for the code that produces these pictures, we now include it
+here. We use a macro \type {sample} which we define as a usable graphic (nearly
+all examples in this manual are coded in the document source).
+
+\startbuffer
+\startuseMPgraphic{sample}
+def sample (expr rx, ry) =
+ path p, q ; numeric n, m, r, a, b ;
+ color c ; c := \MPcolor{lightgray} ;
+ a := 3mm ; b := 2mm ; r := 2cm ; n := 7 ; m := 5 ;
+ q := unitsquare scaled r xyscaled (n,m) shifted (.5r,.5r) ;
+ draw q withpen pencircle scaled (b/4) withcolor .625yellow;
+ for i=1 upto n : for j=1 upto m :
+ p := (fullcircle scaled r randomized (r/rx,r/ry))
+ shifted ((i,j) scaled r) ;
+ pickup pencircle scaled a ;
+ draw for k=0 upto length(p) :
+ point k of p .. endfor cycle withcolor c ;
+ draw for k=0 upto length(p) :
+ point k of p ... endfor cycle withcolor c ;
+ pickup pencircle scaled b ;
+ draw for k=0 upto length(p) :
+ point k of p .. endfor cycle withcolor .625yellow ;
+ draw for k=0 upto length(p) :
+ point k of p ... endfor cycle withcolor .625white ;
+ for k=0 upto length(p) :
+ draw point k of p withcolor .625red ;
+ endfor ;
+ endfor ; endfor ;
+ setbounds currentpicture to q ;
+enddef ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+As you see, not so much code is needed. The graphics themselves were produced
+with a couple of commands like:
+
+\startbuffer
+\placefigure
+ {Circles with minimized inflection and 25\% randomized points.}
+ {\startMPcode
+ \includeMPgraphic{sample} ; sample(4,4) ;
+ \stopMPcode}
+\stopbuffer
+
+\typebuffer
+
+\startpostponing
+
+\placefigure
+ {Circles with minimized inflection and 25\% randomized points.}
+ {\startMPcode\includeMPgraphic{sample} ; sample(4,4) ; \stopMPcode}
+
+\placefigure
+ {Circles with minimized inflection and 33\% randomized points.}
+ {\startMPcode\includeMPgraphic{sample} ; sample(3,3) ; \stopMPcode}
+
+\page
+
+\placefigure
+ {Circles with minimized inflection and 50\% randomized points.}
+ {\startMPcode\includeMPgraphic{sample} ; sample(2,2) ; \stopMPcode}
+
+\placefigure
+ {Circles with minimized inflection and 100\% randomized points.}
+ {\startMPcode\includeMPgraphic{sample} ; sample(1,1) ; \stopMPcode}
+
+\page
+
+\stoppostponing
+
+The tension specifier can be used to influence the curvature. To quote the
+\METAPOST\ manual once more: \quotation {The tension parameter can be less than
+one, but it must be at least $3/4$}. The following paths are the same:
+
+\starttyping
+z1 .. z2
+z1 .. tension 1 .. z2
+z1 .. tension 1 and 1 .. z2
+\stoptyping
+
+The triple dot command \type {...} is actually a macro that makes the following
+commands equivalent. Both commands will draw identical paths.
+
+\starttyping
+z1 ... z2
+z1 .. tension atleast 1 .. z2
+\stoptyping
+
+The \type {atleast} directive tells \METAPOST\ to do some magic behind the
+screens. Both the $3/4$ and the \type {atleast} lead directly to the question:
+\quotation {What, exactly, is the influence of the tension directive?} We will
+try to demystify the \type {tension} specifier through a sequence of graphics.
+
+\startbuffer
+u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
+def sample (expr p, c) =
+ draw p withpen pencircle scaled 2.5mm withcolor white ;
+ draw p withpen pencircle scaled 2.0mm withcolor c ;
+enddef ;
+for i=.75 step .05 until 1 :
+ sample (z1 .. tension i .. z2 .. z3, .625red) ;
+endfor ;
+for i=1 step .05 until 2 :
+ sample (z1 .. tension i .. z2 .. z3, .625yellow) ;
+endfor ;
+sample (z1 .. z2 .. z3, .625white) ;
+sample (z1 ... z2 ... z3, .625white) ;
+\stopbuffer
+
+\typebuffer
+
+Indeed values less than .75 give an error message, but large values are okay. As
+you can see, the two gray curves are the same. Here, \type {atleast 1} means~1,
+even if larger values are useful.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\startbuffer
+u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
+def sample (expr p, c) =
+ draw p withpen pencircle scaled 2.5mm withcolor white ;
+ draw p withpen pencircle scaled 2.0mm withcolor c ;
+enddef ;
+for i=.75 step .05 until 1 :
+ sample (z1 .. tension i and 2i .. z2 .. z3, .625red) ;
+endfor ;
+for i=1 step .05 until 2 :
+ sample (z1 .. tension i and 2i .. z2 .. z3, .625yellow) ;
+endfor ;
+sample (z1 .. z2 .. z3, .625white) ;
+sample (z1 ... z2 ... z3, .625white) ;
+\stopbuffer
+
+Curves finally are made up out of points, and each point has two control points.
+Since the \type {tension} specifier finally becomes a control point, it is not
+surprising that you may specify two tension values. If we replace the tension in
+the previous example by
+
+\starttyping
+.. tension i and 2i ..
+\stoptyping
+
+we get the following graphic:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\startbuffer
+u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
+def sample (expr p, c) =
+ draw p withpen pencircle scaled 2.5mm withcolor white ;
+ draw p withpen pencircle scaled 2.0mm withcolor c ;
+enddef ;
+for i=.75 step .05 until 1 :
+ sample (z1 .. tension 2i and i .. z2 .. z3, .625red) ;
+endfor ;
+for i=1 step .05 until 2 :
+ sample (z1 .. tension 2i and i .. z2 .. z3, .625yellow) ;
+endfor ;
+sample (z1 .. z2 .. z3, .625white) ;
+sample (z1 ... z2 ... z3, .625white) ;
+\stopbuffer
+
+If we swap both values (\type {.. tension 2i and i ..}) we get:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\startbuffer[a]
+u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
+def sample (expr p, c) =
+ drawpath p withpen pencircle scaled 2.5mm withcolor c ;
+ drawcontrollines p withcolor c ;
+ drawpoints p ;
+ drawcontrolpoints p ;
+enddef ;
+\stopbuffer
+
+We mentioned control points. We will now draw a few extreme tensions and show the
+control points as \METAPOST\ calculates them.
+
+\startbuffer[b]
+sample (z1 .. tension 0.75 .. z2 .. z3, .625red) ;
+sample (z1 .. tension 2.00 .. z2 .. z3, .625yellow) ;
+sample (z1 .. z2 .. z3, .625white) ;
+\stopbuffer
+
+\typebuffer[b]
+
+First we will show the symmetrical tensions.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+The asymetrical tensions are less prominent. We use the following values:
+
+\startbuffer[b]
+sample (z1 .. tension .75 and 10 .. z2 .. z3, .625red) ;
+sample (z1 .. tension 10 and .75 .. z2 .. z3, .625yellow) ;
+sample (z1 .. z2 .. z3, .625white) ;
+\stopbuffer
+
+\typebuffer[b]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+What happens when you use the \METAPOST\ maximum value of \type {infinity}
+instead of 10? Playing with this kind of graphic can be fun, especially when we
+apply a few tricks.
+
+\startbuffer
+def sample (expr p, c) =
+ draw p withpen pencircle scaled 2.5mm withcolor white ;
+ draw p withpen pencircle scaled 2.0mm withcolor c ;
+enddef;
+
+u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
+
+for i=0 step .05 until 1 :
+ sample(z1 .. tension (.75+i) .. z2 .. z3, i[.625red,.625yellow]) ;
+endfor;
+\stopbuffer
+
+\typebuffer
+
+Here we change the color along with the tension. This clearly demonstrates that
+we're dealing with a non linear phenomena.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+We can (misuse) transparant colors to illustrate how the effect becomes less with
+growing tension.
+
+\startbuffer
+def sample (expr p) (text c)=
+ draw p withpen pencircle scaled 2.0mm withcolor c ;
+enddef;
+
+u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
+
+for i=0 step .05 until 1 :
+ sample(z1 .. tension (.75+i) .. z2 .. z3, transparent(1,1-i,.625red)) ;
+endfor;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+A third magic directive is \type {curl}. The curl is attached to a point between
+\type {{ }}, like \type {{curl 2}}. Anything between curly braces is a direction
+specifier, so instead of a \type {curl} you may specify a vector, like \type
+{{(2,3)}}, a pair of numbers, as in \type {{2,3}}, or a direction, like \type
+{{dir 30}}. Because vectors and angles are straightforward, we will focus a bit
+on \type {curl}.
+
+\starttyping
+z0 .. z1 .. z2
+z0 {curl 1} .. z1 .. {curl 1} z2
+\stoptyping
+
+So, a \type {curl} of~1 is the default. When set to~1, the begin and|/|or end
+points are approached. Given the following definitions:
+
+\startbuffer[a]
+u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
+def sample (expr p, c) =
+ draw p withpen pencircle scaled 2.5mm withcolor white ;
+ draw p withpen pencircle scaled 2.0mm withcolor c ;
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+We can draw three curved paths.
+
+\startbuffer[b]
+sample (z1 {curl 0} .. z2 .. {curl 0} z3, .625red) ;
+sample (z1 {curl 2} .. z2 .. {curl 2} z3, .625yellow) ;
+sample (z1 {curl 1} .. z2 .. {curl 1} z3, .625white) ;
+\stopbuffer
+
+\typebuffer[b]
+
+The third (gray) curve is the default situation, so we could have left the \type
+{curl} specifier out of the expression.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+\startbuffer[b]
+sample (z1 {curl 0} .. z2 .. {curl 0} z3, .625red) ;
+sample (z1 {curl infinity} .. z2 .. {curl infinity} z3, .625yellow) ;
+sample (z1 {curl 1} .. z2 .. {curl 1} z3, .625white) ;
+\stopbuffer
+
+The curly specs have a lower bound of zero and no upper bound. When we use
+\METAPOST\ maximum value of \type {infinity} instead of~2, we get:
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+These curves were defined as:
+
+\typebuffer[b]
+
+It may sound strange, but internally \METAPOST\ can handle
+larger values than \type {infinity}.
+
+\startbuffer[b]
+sample (z1 {curl infinity} .. z2 .. {curl infinity} z3, .625red) ;
+sample (z1 {curl 4infinity} .. z2 .. {curl 4infinity} z3, .625yellow) ;
+sample (z1 {curl 8infinity} .. z2 .. {curl 8infinity} z3, .625white) ;
+\stopbuffer
+
+\typebuffer[b]
+
+Although this is quite certainly undefined behaviour, interesting effects can be
+achieved. When you turn off \METAPOST's first stage overflow catcher by setting
+\type {warningcheck} to zero, you can go upto 8 times \type {infinity}, which,
+being some $2^{15}$, is still far from what today's infinity is supposed to be.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+As the built||in \METAPOST\ command \type {..} accepts the \type {curl} and \type
+{tension} directives as described in this section, you will now probably
+understand the following plain \METAPOST\ definitions:
+
+\starttyping
+def -- = {curl 1} .. {curl 1} enddef ;
+def --- = .. tension infinity .. enddef ;
+def ... = .. tension atleast 1 .. enddef ;
+\stoptyping
+
+These definitions also point out why you cannot add directives to the left or
+right side of \type {--}, \type {---} and \type {...}: they are directives
+themselves!
+
+\stopsection
+
+\startsection[title={Transformations}]
+
+\index{transformations}
+
+A \type {transform} is a vector that is used in what is called an affine
+transformation. To quote the \METAPOST\ manual:
+
+\startquotation
+If $p=(p_x,p_y)$ is a pair and $T$ is a transform, then
+\type {p transform T} is a pair of the form:
+
+\startformula
+(t_x + t_{xx} p_x + t_{xy} p_y, t_y + t_{yx} p_x + t_{yy} p_y)
+\stopformula
+
+where the six numeric quantities $(t_x, t_y, t_{xx}, t_{xy},
+t_{yx}, t_{yy})$ determine T.
+\stopquotation
+
+In literature concerning \POSTSCRIPT\ and \PDF\ you will find many references to
+such transformation matrices. A matrix of $(s_x,0,0,s_y,0,0)$ is scaling by $s_x$
+in the horizontal direction and $s_y$ in the vertical direction, while
+$(1,0,t_x,1,0,t_y)$ is a shift over $t_x,t_y$. Of course combinations are also
+possible.
+
+Although these descriptions seem in conflict with each other in the nature and
+order of the transform components in the vectors, the concepts are the same. You
+normally populate transformation matrices using \type {scaled}, \type {shifted},
+\type {rotated}.
+
+\starttyping
+transform t ; t := identity shifted (a,b) rotated c scaled d ;
+path p ; p := fullcircle transformed t ;
+\stoptyping
+
+The previous lines of code are equivalent to:
+
+\starttyping
+path p ; p := fullcircle shifted (a,b) rotated c scaled d ;
+\stoptyping
+
+You always need a starting point, in this case the identity matrix \type
+{identity}: $(0,0,1,0,0,1)$. By the way, in \POSTSCRIPT\ the zero vector is
+$(1,0,0,1,0,0)$. So, unless you want to extract the components using \type
+{xpart}, \type {xypart}, \type {xxpart}, \type {ypart}, \type {yxpart} and|/|or \
+\type {yypart}, you may as well forget about the internal representation.
+
+You can invert a transformation using the \type {inverse} macro, which is defined
+as follows, using an equation:
+
+\starttyping
+vardef inverse primary T =
+ transform T_ ; T_ transformed T = identity ; T_
+enddef ;
+\stoptyping
+
+Using transform matrices makes sense when similar transformations need to be
+applied on many paths, pictures, pens, or other transforms. However, in most
+cases you will use the predefined commands \type {scaled}, \type {shifted}, \type
+{rotated} and alike. We will now demonstrate the most common transformations in a
+text example.
+
+\startbuffer[a]
+draw btex \bfd MetaFun etex ;
+draw boundingbox currentpicture withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer[a]
+
+Before an independent \METAPOST\ run, the \typ {btex ... etex}'s are filtered
+from the file and passed on to \TEX. After that, the \DVI\ file is converted to a
+list of pictures, which is consulted by \METAPOST. This is no longer the case in
+\LUATEX\ where we use \MPLIB, so users don't have to worry about these issues:
+just ignore what is mentioned in the official \METAPOST\ manual.
+
+We can manipulate the pictures representing text like any graphic as well as draw
+it with \type {draw}.
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+We show the transformations in relation to the origin and make the origin stand
+out a bit more by painting it a bit larger in white first.
+
+\startbuffer[c]
+draw origin withpen pencircle scaled 1.5mm withcolor white ;
+draw origin withpen pencircle scaled 1mm withcolor .625red
+\stopbuffer
+
+\typebuffer[c]
+
+The origin is in the lower left corner of the picture.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,c]
+\stoplinecorrection
+
+Because the transformation keywords are proper english, we let the pictures speak
+for themselves.
+
+% shifted
+
+\startbuffer[b]
+currentpicture := currentpicture shifted (0,-1cm) ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% rotated
+
+\startbuffer[b]
+currentpicture := currentpicture rotated 180 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% rotatedaround
+
+\startbuffer[b]
+currentpicture := currentpicture rotatedaround(origin,30) ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% scaled
+
+\startbuffer[b]
+currentpicture := currentpicture scaled 1.75 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% scaled
+
+\startbuffer[b]
+currentpicture := currentpicture scaled -1 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% xscaled
+
+\startbuffer[b]
+currentpicture := currentpicture xscaled 3.50 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% xscaled
+
+\startbuffer[b]
+currentpicture := currentpicture xscaled -1 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% yscaled
+
+\startbuffer[b]
+currentpicture := currentpicture yscaled .5 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% yscaled
+
+\startbuffer[b]
+currentpicture := currentpicture yscaled -1 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% slanted
+
+\startbuffer[b]
+currentpicture := currentpicture slanted .5 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% slanted
+
+\startbuffer[b]
+currentpicture := currentpicture slanted -.5 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% zscaled
+
+\startbuffer[b]
+currentpicture := currentpicture zscaled (.75,.25) ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% reflectedabout
+
+\startbuffer[b]
+currentpicture := currentpicture
+ reflectedabout(llcorner currentpicture,urcorner currentpicture) ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% reverse counterclockwise turningnumber
+
+A path has a certain direction. When the \type {turningnumber} of a path is
+larger than zero, it runs in clockwise direction. The \METAPOST\ primitive \type
+{reverse} changes the direction, while the macro \type {counterclockwise} can be
+used to get a path running in a well defined direction.
+
+\startbuffer
+drawoptions(withpen pencircle scaled 2pt withcolor .625red) ;
+path p ; p := fullcircle scaled 1cm ;
+drawarrow p ;
+drawarrow reverse p shifted (2cm,0) ;
+drawarrow counterclockwise p shifted (4cm,0) ;
+drawarrow counterclockwise reverse p shifted (6cm,0) ;
+drawarrow reverse counterclockwise p shifted (8cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Only this far}]
+
+When you take a close look at the definitions of the Computer Modern Roman fonts,
+defined in the \METAFONT\ book, you will notice a high level of abstraction.
+Instead of hard coded points you will find points defined in terms of \quote
+{being the same as this point} or \quote {touching that point}. In this section
+we will spend some time on this touchy aspect.
+
+\startbuffer[a]
+pickup pencircle scaled 2mm ;
+path p ; p := fullsquare scaled 2cm ;
+draw p withcolor .625white ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+This rectangle is a scaled instance of the predefined \METAFUN\ path \type
+{fullsquare} which is centered around the origin.
+
+\typebuffer[a]
+
+On this path, halfway between two of its corners, we define a point \type {q}:
+
+\startbuffer[b]
+pair q ; q := .5[llcorner p, lrcorner p] ;
+\stopbuffer
+
+\typebuffer[b]
+
+We draw this point in red, using:
+
+\startbuffer[c]
+draw q withcolor .625red ;
+\stopbuffer
+
+\typebuffer[c]
+
+As you can see, this point is drawn on top of the path.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+There are four of those midpoints, and when we connect them, we get:
+
+\startbuffer[c]
+draw q -- q rotated 90 -- q rotated 180 --
+ q rotated 270 -- cycle withcolor .625red ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+Because path \type {p} is centered around the origin, we can simply rotate point
+\type {q} a few times.
+
+\typebuffer[c]
+
+There are situations, where you don't want the red path to be drawn inside
+another path, or more general: where you want points to touch instead of being
+overlayed.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+We can achieve this by defining point \type {q} to be located on top of the
+midpoint.
+
+\startbuffer[b]
+pair q ; q := top .5[llcorner p, lrcorner p] ;
+\stopbuffer
+
+\typebuffer[b]
+
+The predefined macro \type {top} moves the point over the distance similar to the
+current pen width.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+Because we are dealing with two drawing operations, and since the path inside is
+drawn through the center of points, we need to repeat this move in order to draw
+the red path really inside the other one.
+
+\startbuffer[b]
+pair q ; q := top top .5[llcorner p, lrcorner p] ;
+\stopbuffer
+
+\typebuffer[b]
+
+Operations like \type {top} and its relatives \type {bot}, \type {lft} and \type
+{rt} can be applied sequentally.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+We already showed that \type {q} was defined as a series of rotations.
+
+\typebuffer[c]
+
+As an intermezzo we will show an alternative definition of \type {q}. Because
+each point is rotated 90 degrees more, we can define a macro that expands into
+the point and rotates afterwards. Because each consecutive point on the path is
+rotated an additional 90 degrees, we use the \METAPOST\ macro \type {hide} to
+isolate the assignment. The \type {hide} command executes the hidden command and
+afterwards continues as if it were never there. You must not confuse this with
+grouping, since the hidden commands are visible to its surroundings.
+
+\startbuffer[c]
+def qq = q hide(q := q rotated 90) enddef ;
+draw qq -- qq -- qq -- qq -- cycle withcolor .625red ;
+\stopbuffer
+
+\typebuffer[c]
+
+The macro \type {top} uses the characteristics of the current pen to determine
+the displacement. However, for the more complicated pen shapes we need a
+different trick to get an inside path. Let's start by defining an elliptical
+path.
+
+\startbuffer[a]
+pickup pencircle xscaled 3mm yscaled 5mm rotated 30 ;
+path p ; p := fullcircle xscaled 6cm yscaled 3cm ;
+draw p withcolor .625white ;
+\stopbuffer
+
+\typebuffer[a]
+
+We draw this path using a non standard pen. In the \METAFONT\ manual you will
+find methods to draw shapes with similar pens, where the pen is also turning, as
+it does in real calligraphy. Here we stick to a more simple one.
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+We construct the inner path from the points that make up the curve. Watch how we
+use a for loop to compose the new path. When used this way, no semi colon may be
+used to end the loop, since it would isolate the color directive.
+
+\startbuffer[b]
+draw point 0 of p
+ for i=1 upto length(p) : -- point (i) of p endfor
+ withcolor .625red ;
+\stopbuffer
+
+\typebuffer[b]
+
+The points are still located on the original path.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+We can move the points to the inside by shifting them over the penwidth in the
+direction perpendicular to the point. Because we use this transformation more
+than once, we wrap it into a macro. This also keeps the code readable.
+
+\startbuffer[b]
+vardef inside expr pnt of p =
+ (point pnt of p shifted
+ -(penoffset direction pnt of p of currentpen))
+enddef ;
+draw inside 0 of p
+ for i=1 upto length(p) : -- inside i of p endfor
+ withcolor .625red ;
+\stopbuffer
+
+\typebuffer[b]
+
+Whenever you define a pen, \METAPOST\ stores its characteristics in some private
+variables which are used in the \type {top} and alike directives. The \type
+{penoffset} is a built in primitive and is defined as the \quotation {point on
+the pen furthest to the right of the given direction}. Deep down in \METAPOST\
+pens are actually simple paths and therefore \METAPOST\ has a notion of a point
+on the penpath. In the \METAFONT\ book and \METAPOST\ manual you can find in
+depth discussions on pens.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+We're still not there. Like in a previous example, we need to shift over twice
+the pen width. To get good results, we should determine the width of the pen at
+that particular point, which is not trivial. The more general solution, which
+permits us to specify the amount of shifting, is as follows.
+
+\startbuffer[b]
+vardef penpoint expr pnt of p =
+ save n, d ; numeric n, d ;
+ (n,d) = if pair pnt : pnt else : (pnt,1) fi ;
+ (point n of p shifted
+ ((penoffset direction n of p of currentpen) scaled d))
+enddef ;
+\stopbuffer
+
+\typebuffer[b]
+
+When the point specification is extended with a distance, in which case we have a
+pair expression, the point and distance are derived from this specification.
+First we demonstrate the simple case:
+
+\startbuffer[c]
+draw penpoint 0 of p
+ for i=1 upto length(p)-1 : .. penpoint i of p endfor .. cycle
+ withcolor .625red ;
+\stopbuffer
+
+\typebuffer[c]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+In the next graphic, we draw both an inner and and outer path.
+
+\startbuffer[c]
+draw penpoint (0,-2) of p
+ for i=1 upto length(p)-1 : .. penpoint (i,-2) of p endfor .. cycle
+ withcolor .625red ;
+draw penpoint (0,+2) of p
+ for i=1 upto length(p)-1 : .. penpoint (i,+2) of p endfor .. cycle
+ withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer[c]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+\startbuffer[a]
+path p, q, r ;
+
+p := fullcircle scaled 3cm ;
+q := p shifted (7cm,0cm) ;
+r := center p -- center q ;
+\stopbuffer
+
+\startbuffer[b]
+pair pr, qr ;
+
+pr := p intersectionpoint r ;
+qr := q intersectionpoint r ;
+
+r := r cutbefore pr cutafter qr ;
+\stopbuffer
+
+\startbuffer[c]
+r := r cutbefore (point 5pt on r) ;
+r := r cutafter (point -5pt on r) ;
+\stopbuffer
+
+\startbuffer[cc]
+r := r cutends 5pt ;
+\stopbuffer
+
+\startbuffer[d]
+draw p withpen pencircle scaled 10pt withcolor .625red ;
+draw q withpen pencircle scaled 10pt withcolor .625yellow ;
+draw r withpen pencircle scaled 20pt withcolor .625white ;
+\stopbuffer
+
+\startbuffer[dd]
+draw r withpen pencircle scaled 20pt withcolor .625white ;
+draw p withpen pencircle scaled 10pt withcolor .625red ;
+draw q withpen pencircle scaled 10pt withcolor .625yellow ;
+\stopbuffer
+
+Another case when \type {top} and friends cannot be applied in a general way is
+the following. Consider the three paths:
+
+\typebuffer[a]
+
+We draw these paths with:
+
+\typebuffer[d]
+
+The line is drawn from center to center and since the line has a non zero width
+and a round line cap, it extends beyond this point.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,d]
+\stoplinecorrection
+
+If we want the line to stop at the circular paths, we can cut off the pieces that
+extend beyond those paths.
+
+\typebuffer[b]
+
+This time we get:
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,d]
+\stoplinecorrection
+
+Due to the thicker line width used when drawing the straight line, part of that
+line is still visible inside the circles. So, we need to clip off a bit more.
+
+\typebuffer[c]
+
+The \type {point ... on} operation is a \METAFUN\ macro that takes a dimension.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d]
+\stoplinecorrection
+
+In order to save you some typing, \METAFUN\ provides a macro \type {cutends} that
+does the same job:
+
+\typebuffer[cc]
+
+This time we draw the path in a different order:
+
+\typebuffer[dd]
+
+That way we hide the still remaining overlapping part of the line.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,cc,dd]
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Directions}]
+
+\index{directions}
+
+Quite often you have to tell \METAPOST\ in what direction a line should be drawn.
+A direction is specified as a vector. There are four predefined vectors: \type
+{up}, \type {down}, \type {left}, \type {right}. These are defined as follows:
+
+\starttyping
+pair up, down, left, right ;
+up = -down = (0,1) ; right = -left = (1,0) ;
+\stoptyping
+
+We can use these predefined pairs as specifications and in calculations.
+
+\startbuffer
+dotlabel.top("up" , up * 1cm) ;
+dotlabel.bot("down" , down * 1cm) ;
+dotlabel.lft("left" , left * 1cm) ;
+dotlabel.rt ("right", right * 1cm) ;
+
+drawoptions (withpen pencircle scaled .25mm withcolor .625 red) ;
+
+drawarrow origin -- up * 1cm ;
+drawarrow origin -- down * 1cm ;
+drawarrow origin -- left * 1cm ;
+drawarrow origin -- right * 1cm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+This graphic can also be defined in a more efficient (but probably more cryptic)
+way. The next definition demonstrates a few nice tricks. Instead of looping over
+the four directions, we loop over their names. Inside the loop we convert these
+names, or strings, into a pair by scanning the string using \type {scantokens}.
+The \type {freedotlabel} macro is part of \METAFUN\ and takes three arguments: a
+label string (or alternatively a picture), a point (location), and the \quote
+{center of gravity}. The label is positioned in the direction opposite to this
+center of gravity.
+
+\startbuffer
+pair destination ;
+for whereto = "up", "down", "left", "right" :
+ destination := scantokens(whereto) * 1cm ;
+ freedotlabel(whereto, destination, origin) ;
+ drawarrow origin -- destination
+ withpen pencircle scaled .25mm withcolor .625 red ;
+endfor ;
+\stopbuffer
+
+\typebuffer
+
+So, in this code fragment, we use the string as string and (by means of \type
+{scantokens}) as a point or vector.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The previous definition is a stepping stone to the next one. This time we don't
+use points, but the \type {dir} command. This command converts an angle into an
+unitvector.
+
+\startbuffer
+pair destination ;
+for whereto = 0 step 30 until 330 :
+ destination := dir(whereto) * 1.5cm ;
+ freedotlabel(decimal whereto, destination, origin) ;
+ drawarrow origin -- destination
+ withpen pencircle scaled .25mm withcolor .625 red ;
+endfor ;
+\stopbuffer
+
+\typebuffer
+
+In \METAPOST\ the angles go counter clockwise, which is not that illogical if you
+look at it from the point of view of vector algebra.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Analyzing pictures}]
+
+\index{pictures+analyzing}
+
+{\em Unless you really want to know all details, you can safely skip this
+section. The \METAPOST\ features discussed here are mainly of importance when you
+write (advanced) macros.}
+
+% Later we will discuss in detail how you can use either \METAPOST\ or \TEX\ to
+% typeset text (\in {section} [sec:text] and \in {chapter} [sec:typesetting]), so
+% here we limit our exploration to a quick introduction. The most direct way of
+% processing text in \METAPOST\ is using the \type {infont} operator.
+%
+% \startbuffer[mp]
+% draw "this string will become a sequence of glyphs (MP)"
+% infont defaultfont scaled defaultscale ;
+% \stopbuffer
+%
+% \typebuffer[mp]
+%
+% The text between \type {"} is passed to \TEX, and the resulting \DVI\ will be
+% converted into a picture with textual components. So, we get:
+%
+% \startlinecorrection[blank]
+% \midaligned{\processMPbuffer[mp]}
+% \stoplinecorrection
+%
+% The same string typeset by \TEX\ shows up as:
+%
+% \blank
+% \midaligned{this string will become a sequence of glyphs (\TeX)}
+% \blank
+%
+% The following \METAPOST\ features are not covered by the \METAPOST\ manual, but
+% most of them are discussed in the appendix of the \type {graph} package written
+% by John Hobby.
+%
+%It is possible to disassemble a picture by means of a special for loop using the
+%\type {within} specifier. The following code walks over a picture and draws the
+%components with their bounding boxes.
+%
+% \startbuffer[show]
+% for i within currentpicture :
+% draw boundingbox i withcolor .625yellow ;
+% endfor ;
+% \stopbuffer
+%
+% \typebuffer[show]
+%
+% We can use the disassemble loop feature to look into the previously shown
+% example text.
+%
+% \startlinecorrection[blank]
+% \processMPbuffer[mp,show]
+% \stoplinecorrection
+%
+% The second line is typeset by \TEX. The resulting \DVI\ code is converted into a
+% series of pictures, which \METAPOST\ pastes into one picture. You may also notice
+% that in the set of pictures that originate in \TEX, the space is replaced by a
+% shift (this is because \TEX\ knows no space).
+%
+% An interesting aspect of this \quote {loop over a picture} feature, is that it
+% can provide insight in how \TEX\ is composing a paragraph.
+%
+% \startbuffer
+% draw btex \framed[width=fit,align=middle]{\input tufte \relax} etex ;
+% for i within currentpicture :
+% draw boundingbox i withpen pencircle scaled .2pt withcolor .625yellow ;
+% endfor ;
+% \stopbuffer
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% You may also notice, that rules produced by \TEX\ are converted to straight line
+% segments. Because the line extends 50\% of its linewidth beyond a point, there is
+% a slight overshoot. This picture was defined in a few lines:
+%
+% \typebuffer
+%
+% If we use a Times Roman instead of a Palatino, we get quite
+% different results.
+%
+% \startlinecorrection[blank]
+% \startMPenvironment
+% %\let\fontclass\empty
+% \usetypescript[times][texnansi]
+% \switchtobodyfont[times,10pt]
+% \stopMPenvironment
+% \processMPbuffer
+% \stoplinecorrection
+%
+% In \CONTEXT, you can easily change the body font for
+% \METAPOST\ graphics with directives like:
+%
+% \starttyping
+% \startMPenvironment
+% \usetypescript[times][texnansi]
+% \switchtobodyfont[times,10pt]
+% \stopMPenvironment
+% \stoptyping
+%
+% This font has far less kerning. Even more interesting is the Lucida Bright
+% Handwriting font, which is defined in such a way that no kerning is needed at
+% all.
+%
+% \startlinecorrection[blank]
+% \resetMPenvironment
+% \startMPenvironment
+% %\let\fontclass\empty
+% \usetypescript[lucida][texnansi]
+% \switchtobodyfont[lucida,hw,10pt]
+% \stopMPenvironment
+% \processMPbuffer
+% \stoplinecorrection
+%
+% You can ask for the number of components with \type {length}. A component can be
+% a stroked or filled path, or a text resulting from an \type {infont} operation.
+% If the (last) path is a clip path, or when the whole picture has a forced
+% boundingbox, the picture is treated as a whole. We will demonstrate this later.
+
+We can decompose \METAPOST\ pictures using a \type {within} loop. You may wonder
+if such a \type {within} loop construct has any real application, and as you can
+expect, it has. In \in {section} [sec:color circles] a macro is defined that
+draws a colored circle. If you want the inverted alternative, you can pass the
+inverted color specification, but wouldn't it be more convenient if there was an
+operator that did this for you automatically? Unfortunately there isn't one so we
+have to define one ourselves in a macro.
+
+\startbuffer
+colorcircle(4cm,(.4,.6,.8),(.4,.8,.6),(.6,.4,.8)) ;
+addto currentpicture also inverted currentpicture shifted (5cm,0) ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+These circles were drawn using:
+
+\typebuffer
+
+When we \type {draw} a path, or stroke a path, as it is called officially, we
+actually perform an addition:
+
+\starttyping
+addto currentpicture doublepath somepath
+\stoptyping
+
+The \type {fill} command is actually:
+
+\starttyping
+addto currentpicture contour somepath
+\stoptyping
+
+We will need both \type {doublepath} and \type {contour} operations in the
+definition of \type {inverted}.
+
+When \METAPOST\ has digested a path into a picture, it keeps track of some
+characteristics. We can ask for them using \type {part...} operators. The
+following operators can be applied to a transform vector (one of \METAPOST's data
+types), but also to a picture. Say that we have drawn a circle:
+
+\startbuffer[a]
+draw fullcircle
+ xscaled 3cm yscaled 2cm
+ dashed dashpattern(on 3mm off 3mm)
+ withpen pencircle scaled 1mm
+ withcolor .625red ;
+picture p ; p := currentpicture ;
+\stopbuffer
+
+\typebuffer[a]
+
+This circle looks like:
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+We can now ask for some of the characteristics of \type {currentpicture}, like
+its color. We could write the values to the log file, but it is more convenient
+to put them on paper.
+
+\startbuffer[b]
+label.rt("redpart: " & decimal redpart p, (4cm,+.5cm)) ;
+label.rt("greenpart: " & decimal greenpart p, (4cm, 0cm)) ;
+label.rt("bluepart: " & decimal bluepart p, (4cm,-.5cm)) ;
+\stopbuffer
+
+\typebuffer[b]
+
+Here the \type {&} glues strings together, while the decimal operator converts a
+number into a string.
+
+The result has no typographic beauty |<|keep in mind that here we use \METAPOST\
+to typeset the text|>|but the result serves its purpose.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+We can also ask for the path itself (\type {pathpart}), the pen (\type {penpart})
+and the dashpattern (\type {dashpart}), but these can only be assigned to
+variables of the corresponding type.
+
+A path can be stroked or filled, in which case it is a cyclic path. It can have a
+non natural bounding box, be a clip path, consist of line segments or contain
+text. All these characteristics can be tested.
+
+\startbuffer[b]
+label.rt("filled: " & condition filled p, (4cm,+1.25cm)) ;
+label.rt("stroked: " & condition stroked p, (4cm,+0.75cm)) ;
+label.rt("textual: " & condition textual p, (4cm,+0.25cm)) ;
+label.rt("clipped: " & condition clipped p, (4cm,-0.25cm)) ;
+label.rt("bounded: " & condition bounded p, (4cm,-0.75cm)) ;
+label.rt("cycle: " & condition cycle pathpart p, (4cm,-1.25cm)) ;
+\stopbuffer
+
+\typebuffer[b]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+In this code snippet, \type {condition} is a macro that takes care of translating
+a boolean value into a string (like \type {decimal} does with a numeric value).
+
+\starttyping
+def condition primary b =
+ if b : "true" else : "false" fi
+enddef ;
+\stoptyping
+
+Clip paths and bounding boxes are kind of special in the sense that they can
+obscure components. The following examples demonstrate this. In case of a clip
+path or bounding box, the \type {pathpart} operator returns this path. In any
+case that asking for a value does not make sense |<|a clipping path for instance
+has no color|>| a zero (null) value is returned.
+
+\startbuffer[b]
+n := 1 ;
+for i within currentpicture : n := n + 1 ;
+ label("n: " & decimal n & " / " &
+ "length: " & decimal length i & " / " &
+ "stroked: " & condition stroked i & " / " &
+ "clipped: " & condition clipped i & " / " &
+ "bounded: " & condition bounded i , (0,-n*.5cm)) ;
+endfor ;
+\stopbuffer
+
+\startbuffer[c]
+\startlinecorrection[blank]
+\framed[offset=overlay,frame=off,background=color,backgroundcolor=gray]{\processMPbuffer[a,b]}
+\stoplinecorrection
+\stopbuffer
+
+\startbuffer[a]
+draw fullcircle withpen pencircle scaled 6mm ;
+clip currentpicture to fullcircle ;
+setbounds currentpicture to fullcircle ;
+\stopbuffer
+
+\typebuffer[a] \getbuffer[c]
+
+\startbuffer[a]
+draw fullcircle withpen pencircle scaled 6mm ;
+setbounds currentpicture to fullcircle ;
+clip currentpicture to fullcircle ;
+\stopbuffer
+
+\typebuffer[a] \getbuffer[c]
+
+\startbuffer[a]
+clip currentpicture to fullcircle ;
+draw fullcircle withpen pencircle scaled 6mm ;
+setbounds currentpicture to fullcircle ;
+\stopbuffer
+
+\typebuffer[a] \getbuffer[c]
+
+\startbuffer[a]
+clip currentpicture to fullcircle ;
+setbounds currentpicture to fullcircle ;
+draw fullcircle withpen pencircle scaled 6mm ;
+\stopbuffer
+
+\typebuffer[a] \getbuffer[c]
+
+\startbuffer[a]
+setbounds currentpicture to fullcircle ;
+clip currentpicture to fullcircle ;
+draw fullcircle withpen pencircle scaled 6mm ;
+\stopbuffer
+
+\typebuffer[a] \getbuffer[c]
+
+\startbuffer[a]
+setbounds currentpicture to fullcircle ;
+draw fullcircle withpen pencircle scaled 6mm ;
+clip currentpicture to fullcircle ;
+\stopbuffer
+
+\typebuffer[a] \getbuffer[c]
+
+The description lines were generated by the following loop:
+
+\typebuffer[b]
+
+% % The following is no longer valid in MetaFun:
+%
+% If we have a textual picture, we can also ask for the text and font. Take the
+% following picture:
+%
+% \startbuffer[a]
+% picture p ;
+% p := "MetaFun" normalinfont "rm-lmr10" scaled 2 rotated 30 slanted .5 ;
+% p := p shifted (0,-ypart center p) ;
+% currentpicture := p ;
+% \stopbuffer
+%
+% \typebuffer[a]
+%
+% Here we can ask for:
+%
+% \startbuffer[b]
+% label.rt("textpart: " & textpart p, (4cm,+0.25cm)) ;
+% label.rt("fontpart: " & fontpart p, (4cm,-0.25cm)) ;
+% \stopbuffer
+%
+% \typebuffer[b]
+%
+% and get:
+%
+% \startlinecorrection[blank]
+% \processMPbuffer[a,b]
+% \stoplinecorrection
+%
+% We use \type {normalinfont} instead of \type {infont} because in \METAFUN\ this
+% operator is overloaded and follows another route for including text.
+%
+% If we're dealing with a path, the transformations have ended up in the path
+% specification. If we have a text picture, we can explicitly ask for the transform
+% components.
+%
+% \startbuffer[b]
+% label.rt("xpart: " & decimal xpart p, (4cm,+1.25cm)) ;
+% label.rt("ypart: " & decimal ypart p, (4cm,+0.75cm)) ;
+% label.rt("xxpart: " & decimal xxpart p, (4cm,+0.25cm)) ;
+% label.rt("xypart: " & decimal xypart p, (4cm,-0.25cm)) ;
+% label.rt("yxpart: " & decimal yxpart p, (4cm,-0.75cm)) ;
+% label.rt("yypart: " & decimal yypart p, (4cm,-1.25cm)) ;
+% \stopbuffer
+%
+% \typebuffer[b]
+%
+% \startlinecorrection[blank]
+% \processMPbuffer[a,b]
+% \stoplinecorrection
+%
+% We will now define the \type {inverted} macro using these primitives. Because we
+% have to return a picture, we cannot use \type {draw} and \type {fill} but need to
+% use the low level operators. Because a picture can consist of more than one path,
+% we need a temporary picture \type {pp}.
+%
+% \starttyping
+% vardef inverted expr p =
+% save pp ; picture pp ; pp := nullpicture ;
+% for i within p :
+% addto pp
+% if stroked i or filled i :
+% if filled i : contour else : doublepath fi pathpart i
+% dashed dashpart i withpen penpart i
+% else :
+% also i
+% fi
+% withcolor white-(redpart i, greenpart i, bluepart i) ;
+% endfor ;
+% pp
+% enddef ;
+% \stoptyping
+%
+% We probably need to handle a few more border cases, but for general purposes,
+% this macro works as expected.
+
+The textual capabilities built in \METAPOST\ are rather limited but in \CONTEXT\
+we have overloaded the relevant operators. There we hook into the normal font
+handler. The native text related operators are:
+
+\starttyping
+draw "MetaFun" infont "somefont" scaled 2 rotated 30 slanted .5 ;
+draw btex MetaFun etex scaled 2 rotated 30 slanted .5 ;
+\stoptyping
+
+The \type {infont} operator directly calls for a font and in stock \METAPOST\ is
+limited to (eight bit) \TYPEONE\ fonts. In \CONTEXT\ you can do this:
+
+\startbuffer[a]
+draw "MetaFun" infont "SerifBold*default" xscaled 5 rotated 5 slanted .5 ;
+\stopbuffer
+
+\typebuffer[a]
+
+The specification is a regular \CONTEXT\ font specification.
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+The \type {btex ... etex} variant in normal \METAPOST\ delegates to \TEX\ and in \MKII\
+indeed we filter them and process them between runs (or at runtime). In \MKIV\ they are
+also handled by \TEX\ but in an even more integrated and immediate way.
+
+The two primitives \type {textpart} and \type {fontpart} that can be used to disassemble
+a picture don't apply to \METAFUN\ as contrary to \METAPOST\ we don't convert the result
+to a picture. In later chapters we will discuss text in more detail.
+
+From the previous examples it may be clear that each picture has some associated
+data stored with it. From the \type {bounded} boolean test we can conclude that
+the bounding box is part of this data. Internally \METAPOST\ keeps track of two
+bounding boxes: the natural one, and the forced one. The forced one is actually a
+component of the picture which applies to all previously added graphics. You can
+calculate the bounding box from the \type {llcorner} and \type {urcorner} or if
+you like \type {ulcorner} and \type {lrcorner} and the \METAFUN\ command \type
+{boundingbox} does so.
+
+The four corners that make up the bounding box are either the natural ones, or
+the ones forced by \type {setbounds}. You can force \METAPOST\ to report the
+natural ones by setting \type {truecorners} to~1. The next example demonstrates
+this feature.
+
+\startbuffer
+pickup pencircle scaled 2mm ; path p, q ;
+draw fullcircle
+ scaled 4cm slanted .5 withcolor .625white ;
+setbounds currentpicture to
+ boundingbox currentpicture enlarged -5mm ;
+interim truecorners := 0 ; p := boundingbox currentpicture ;
+interim truecorners := 1 ; q := boundingbox currentpicture ;
+pickup pencircle scaled 1mm ;
+draw p withcolor .625red ;
+draw q withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+We use \type {interim} because \type {truecorners} is an internal \METAPOST\
+variable.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+% % we already redefined infont so it's kind of dangerous to provide this example
+%
+% Since \METAPOST\ can handle fonts (it can even generate font metric files) it is
+% no surprise that we can also ask for the natural size of a font. For this we use
+% \type {fontsize}. However, you should beware of the fact that the size reported
+% is in base points. Since this is \METAPOST's native unit, this is no problem in
+% calculations, but it may look confusing when you \type {show} this size on your
+% terminal and get less that 10 reported for a \type {cmr10} font.
+%
+% \starttyping
+% show fontsize "cmr10" ;
+% \stoptyping
+%
+% In order to demonstrate that \type {fontsize} is useful, we extend the \type
+% {infont} command. In the process we show a few macro definition tricks. What we
+% want is a \TEX\ like specification of a font size:
+%
+% \startbuffer[txt]
+% draw "MetaFun" infont defaultfont at 20pt ;
+% \stopbuffer
+%
+% \typebuffer[txt]
+%
+% We can store the current meaning of a primitive or macro in a new macro. We do so
+% with \type {infont}:
+%
+% \startbuffer[a]
+% let normalinfont = infont ;
+% \stopbuffer
+%
+% \typebuffer[a]
+%
+% We can only know the size if we know the name of the font, so we have to redefine
+% \type {infont} to pick up this name.
+%
+% \startbuffer[b]
+% numeric lastfontsize ; lastfontsize = fontsize defaultfont ;
+% \stopbuffer
+%
+% \startbuffer[c]
+% primarydef infont primary name = % patched: def should work too
+% hide(lastfontsize := fontsize name)
+% normalinfont name
+% enddef ;
+% \stopbuffer
+%
+% \typebuffer[c]
+%
+% Because we are replacing an operator, and since \METAPOST\ expects one, we have
+% to use \type {def} instead of \type {vardef} (which is actually a kind of
+% variable). For the same reason, we have to pick up a \type {primary}. If we would
+% use a \typ {expr name}, we would end up in an unwanted look ahead. The \type
+% {hide} macro hides the assignment and makes this macro behave like a \type
+% {vardef} with respect to hiding expressions. We may not put a semi colon after
+% the \type {)} because it would stop \METAPOST\ from reading on, and thereby
+% invoke an error message.
+%
+% We can now define \type {at}. This macro picks up an expression (which can be
+% more than just a number) and return a scale transform that normalizes the given
+% size to the design size.
+%
+% \startbuffer[d]
+% def at expr size =
+% scaled (size/lastfontsize)
+% enddef ;
+% \stopbuffer
+%
+% \typebuffer[d]
+%
+% Because this macro is defined global, and therefore can be used apart from \type
+% {infont}, we predefine the size:
+%
+% \typebuffer[b]
+%
+% When defined this way \type {at} a comfortable 20 points, the string \type
+% {MetaFun} comes out as follows:
+%
+% \startlinecorrection[blank]
+% \processMPbuffer[a,b,c,d,txt]
+% \stoplinecorrection
+
+\stopsection
+
+\startsection[title={Filling}]
+
+\index{filling}
+\index{reversing}
+
+In most cases a path ends up being drawn or filled. When filling a path, it
+doesn't matter in what direction the path runs, as long as it's closed you're
+fine. You can however change the direction any time along the path. Here is an
+example of what happens when you fill a path that is partially reversed.
+
+\startbuffer
+fill fullsquare rotated 45 scaled 2cm
+ withcolor .625 red ;
+fill fullcircle scaled 2cm -- reverse fullcircle scaled 1cm -- cycle
+ withcolor .625 yellow ;
+\stopbuffer
+
+\typebuffer
+
+You'll notice that the inner circle is not filled:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Now watch the following:
+
+\startbuffer
+fill
+ fullsquare rotated 45 scaled 2cm
+ -- fullcircle scaled 2cm
+ -- cycle
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+This results in:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Compare this with:
+
+\startbuffer
+fill
+ fullsquare rotated 45 scaled 2cm
+ -- reverse fullcircle scaled 2cm -- cycle
+ -- cycle
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+giving:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The normal filling happens according to the non||zero winding rule. An alternative is the
+odd||even rule. There we don't need the reverse trick:
+
+\startbuffer
+eofill fullsquare rotated 45 scaled 2cm
+ -- fullcircle scaled 2cm -- cycle
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+The \type {eofill} is a \METAFUN\ extension. Hopefully the next explains a bit
+how this works (you can find explanations zon the internet).
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\startuseMPgraphic{demo}
+ def DrawIt(text how) =
+ path p ; p := ((0,0) .. (1,0) .. (1,1) .. (0,1) .. (1,0) .. (2,1) .. cycle) scaled 2cm ;
+ how p withcolor .625 yellow ;
+ draw p withcolor .625 red ;
+ for i=0 step 0.05 until 1 :
+ fill arrowheadonpath (p,i)
+ withcolor .625 red ;
+ endfor ;
+ draw (0.5,0.5) scaled 2cm withpen pencircle scaled .5mm withcolor .375 white ;
+ draw ((0.5,0.5) scaled 2cm -- llcorner p) withpen pencircle scaled .5mm withcolor .375 white ;
+ draw (1.5,1.5) scaled 2cm withpen pencircle scaled .5mm withcolor .375 white ;
+ draw ((1.5,1.5) scaled 2cm -- urcorner p) withpen pencircle scaled .5mm withcolor .375 white ;
+ enddef ;
+\stopuseMPgraphic
+
+\startlinecorrection[blank]
+ \startcombination[distance=4em]
+ {\startMPcode \includeMPgraphic{demo} DrawIt(eofill) \stopMPcode} {\type{eofill}}
+ {\startMPcode \includeMPgraphic{demo} DrawIt(fill) \stopMPcode} {\type{fill}}
+ \stopcombination
+\stoplinecorrection
+
+In the case of a normal fill, the non||zero winding rule is applied: a winding
+number is calculated by subtracting 1 each time the line (from inside an area to
+someplace outside) is crossed clockwise while 1 is added each time we cross
+anti||clockwise. When the total is non zero the area is filled. Here we run in one
+direction and therefore we always get a fill. In the previous example where we
+used a reverse, an anti||clockwise crossing was nilled by a clockwise one.
+
+The leftmost shape uses \type {eofill} and therefore the odd||even rule gets
+applied. This time we follow the line and when it gets crossed en even number of
+times the area will not be filled.
+
+A glyph is often constructed from more than one path and eventually the shape is
+filled with an odd||even fill (\type {eofill}) operation. Take the following
+sequence:
+
+\startbuffer
+pickup pencircle scaled 1mm ;
+draw fullsquare scaled 2cm ;
+draw fullsquare scaled 2cm shifted (1cm,0) ;
+draw fullsquare scaled 2cm shifted (0,1cm) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+We can use a sequence of \type {nofill} ending with a \type {eofill} to create
+a combined shape. This is not done in \METAPOST\ but in the backend.
+
+\startbuffer
+nofill fullsquare scaled 2cm ;
+nofill fullsquare scaled 2cm shifted (1cm,0) ;
+eofill fullsquare scaled 2cm shifted (0,1cm) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+As this is used for glyphs, we demonstrate this mechanism with a simple \type {O}
+shape:
+
+\startbuffer
+nofill fullcircle xyscaled (2cm,3cm) ;
+eofill fullcircle xyscaled (1cm,2cm) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Another backend related feature is \type {fillup}. This is just a combination
+of a fill and a draw in one go. It can save some bytes in the output file.
+
+\startbuffer
+draw image (
+ pickup pencircle scaled 5mm ;
+ fill fullsquare scaled 2cm ;
+ draw fullsquare scaled 2cm ;
+ fillup fullsquare scaled 2cm shifted (4cm,0) ;
+) withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Pitfalls}]
+
+When writing macros, you need to be careful in what
+operations apply to what object. There is for instance a
+difference between the following code:
+
+\startbuffer
+pickup pencircle scaled 2pt ;
+draw (0,0)--(0,1)--(1,1) scaled 1cm withcolor .625 red ;
+draw ((0,0)--(0,1)--(1,1)) scaled 2cm withcolor .625 yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The \type {scaled} operates on the previous expression which in the first case is
+the point \type {(1,1)} and in the second case the whole path.
+
+\startbuffer
+pickup pencircle scaled 2pt ;
+draw (0,0)--(0,1)--(1,1)--cycle scaled 1cm withcolor .625 red ;
+draw ((0,0)--(0,1)--(1,1)--cycle) scaled 2cm withcolor .625 yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Here the last element in the first case is not the cycle, and the next
+alternative does not help us much in discovering what is going on. (Well, at
+least something {\em is} going on, because the result seems to have some
+dimensions.)
+
+\startbuffer
+pickup pencircle scaled 2pt ;
+draw (1,1)--cycle scaled 1cm withcolor .625 red ;
+draw ((1,1)--cycle) scaled 1cm withcolor .625 yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The next lines demonstrate that we're dealing with the dark sides of \METAPOST,
+and from that we may conclude that in case of doubt it's best to add parenthesis
+when such fuzzy situations threaten to occur.
+
+\startbuffer
+pickup pencircle scaled 2pt ;
+draw (0,1)--(1,1)--cycle scaled 1cm withcolor .625 red ;
+draw ((0,1)--(1,1)--cycle) scaled 1cm withcolor .625 yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+There are more cases where the result may surprise you. Take the following code:
+
+\startbuffer
+drawarrow ((0,0)--(10,0))
+ withpen pencircle scaled 2pt
+ withcolor red randomized (.4,.9) ;
+currentpicture := currentpicture scaled 8 ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The arrow is made up out of two pieces and each piece gets a different shade of
+red. This is because the attributes are collected and applied to each of the
+components that make up the arrow. Because for each component the attribute code
+is expanded again, we get two random colors. One way around this is to apply the
+color afterwards.
+
+\startbuffer
+draw
+ image (drawarrow ((0,0)--(10,0)) withpen pencircle scaled 2pt)
+ scaled 8 withcolor red randomized (.4,.9) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Here the \type {image} macro creates a picture and as you can see, this provides
+a way to draw within a draw operation.
+
+Once you see the benefits of \type {image}, you will use it frequently. Another
+handy (at first sight strange) macro is \type {hide}. You can use this in
+situations where you don't want code to interfere.
+
+\starttyping
+def mydraw text t =
+ boolean error ; error := false ;
+ def withpencil expr p = hide (error := true) enddef ;
+ draw t ;
+ if error : message "pencils are not supported here" fi ;
+enddef ;
+mydraw fullcircle scaled 10cm withpencil sharp ;
+\stoptyping
+
+Here, setting the boolean normally interferes with the draw operation, but by
+hiding the assignment, this code becomes valid. This code will bring the message
+to your terminal and log file.
+
+Once you start using expressions you have a good chance of encountering messages
+with regard to redundant expressions. The following code is for instance a
+recipe for problems:
+
+\starttyping
+z1 = (1,0) ; z1 = (2,0) ;
+\stoptyping
+
+Changing the \type {=} into \type {:=} helps, but this may not be what you want.
+
+Because the \type {z}||variables are used frequently, they are reset each figure.
+You can also reset them yourself, using the \type {clearxy} macro. The \METAFUN\
+version clears all \type {z}||variables, unless you explictly specify what
+variables to reset. \footnote {This version resulted from a discussion on the
+\METAFONT\ discussion list and is due to Bogus\l{}aw Jackowski.} If you want to
+play with this macro, see what happens when you run the following code:
+
+\starttyping
+show x0 ; z0 = (10,10) ;
+show x0 ; x0 := whatever ; y0 := whatever ;
+show x0 ; z0 = (20,20) ;
+show x0 ; clearxy 0 ;
+show x0 ; z0 = (30,30) ;
+\stoptyping
+
+So, the following calls are all legal:
+
+\starttyping
+clearxy ; clearxy 1 ; clearxy 1, 8, 10 ;
+\stoptyping
+
+Keep in mind that for each figure a full clear is done anyway. You should not
+confuse this command with \type {clearit}, which clears \type {currentpicture}.
+
+\stopsection
+
+\startsection[title={\TeX\ versus \MetaPost}]
+
+If you are defining your own \TEX\ and \METAPOST\ macros, you will notice that
+there are a couple of essential differences between the two macro languages. In
+\TEX\ the following code is invalid. \footnote {In \ETEX\ the calculation can be
+done in less lines using a \type {\numexpr}.}
+
+\starttyping
+\def\fancyplied#1%
+ {\ifnum#1=0
+ \message{zero argument}%
+ \fi
+ \count0=#1 \multiply \count0 by \count0
+ \count2=#1 \multiply \count2 by 2
+ \count4=#1 \divide \count4 by 2
+ \advance \count0 by \count2
+ \advance \count0 by \count4
+ \count4 }
+\hskip \fancyplied{3} pt
+\stoptyping
+
+This is because \TEX\ is very strict in what tokens it expects next. In
+\METAPOST\ however, you can use \type {vardef}'d macros to hide nasty
+intermediate calculations.
+
+\starttyping
+vardef fancyplied expr x =
+ if x=0 : message "x is zero" ; (x*x+2x+x/2)
+enddef ;
+a := a shifted (fancyplied 3pt,0) ;
+\stoptyping
+
+Hiding intermediate calculations and manipulations is a very strong point of
+\METAPOST.
+
+Another important difference between both languages is the way grouping is
+implemented. Because \TEX\ is dealing with a flow of information, strong grouping
+is a must and therefore part of the language. Occasionally you run into
+situations where you wished that you could reach over a group (for instance in
+order to pass a value).
+
+In \METAPOST\ grouping behaves quite different. First of all, it provides the
+mechanism that hides processing from the current flow. The previously mentioned
+\type {vardef} is implicitly grouped. Contrary to \TEX, in \METAPOST\ all
+assignments are global by default, even in a group. If you assign a variable
+inside a group it is persistent unless you first save the variable (or macro)
+using the \type {save} operator.
+
+So, in the next code snippet, the value of \type {\value} inside the box is {\em
+no} but after the box is typeset, it will be {\em yes} again.
+
+\starttyping
+\def\value{yes} \hbox{\def\value{no}\value} \value
+\stoptyping
+
+To make a value local in \METAPOST, the following code is needed.
+
+\starttyping
+string value ; value := "yes" ;
+def intermezzo
+ begingroup ;
+ save value ; string value ; value := "no" ;
+ endgroup ;
+enddef ;
+\stoptyping
+
+Once you start writing your own \METAPOST\ macros, you will appreciate this
+\quote {always global} behaviour. As with other differences between the two
+languages, they make sense if you look at what the programs are supposed to do.
+
+\stopsection
+
+\startsection[title={Internals and Interims}]
+
+\index{internals}
+\index{interims}
+
+Related to grouping is the internal numeric datatype. When numeric variables are
+defined as interim, you can quickly overload them inside a group.
+
+\starttyping
+newinternal mynumber ; mynumber := 1 ;
+
+begingroup ; ... interim mynumber := 0 ; ... ; endgroup ;
+\stoptyping
+
+You can only \type {interim} a variable if it is already defined using \type
+{newinternal}.
+
+Among the \METAPOST\ macros is one called \type {drawdot}. This macro is kind of
+redundant because, at least at first sight, you can use draw to achieve the same
+result. There is however a very subtle difference: a dot is slightly larger than
+a drawn point. We guess that it's about the device pixel, so you may not even
+notice it. It may even be due to differences in accuracy of the methods to render
+them.
+
+\startbuffer
+pickup pencircle scaled 50pt ;
+drawdot origin shifted (-120pt,0) ; draw origin shifted (-60pt,0) ;
+drawdot origin ; draw origin withcolor white ;
+setbounds currentpicture to boundingbox currentpicture enlarged 1pt ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=Named colors]
+
+The \type {withcolor} operator accepts a color expression but in \METAFUN\ it
+also accepts a string indicating a color defined at the \TEX\ end. Most helpers
+that deal with colors are able to deal with named colors as well. Here are some
+examples. First we define a few colors:
+
+\startbuffer
+\definecolor[MyColor1][r=.5]
+\definecolor[MyColor2][g=.5]
+\definecolor[MyColor3][b=.5]
+\definecolor[MyColor4][s=.8]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Here we access them:
+
+\startbuffer
+fill fullcircle scaled 12 withcolor "MyColor1" ;
+fill fullcircle scaled 10 withcolor "MyColor2" ;
+fill fullcircle scaled 8 withcolor complementary "MyColor3" ;
+fill fullcircle scaled 6 withcolor complemented "MyColor3" ;
+fill fullcircle scaled 4 withcolor "MyColor4" randomized 2 ;
+fill fullcircle scaled 2 withcolor "MyColor4" randomized 2 ;
+addbackground
+ withcolor .5[resolvedcolor("MyColor4"),resolvedcolor("MyColor2")] ;
+currentpicture := currentpicture ysized 4cm ;
+\stopbuffer
+
+\typebuffer
+
+And get:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=Formatted text]
+
+Text support in \METAFUN\ has evolved quite a bit over years. For compatibility
+reasons we keep old methods around but in practice one can probably do all with
+the following:
+
+\starttabulate[|T|p|]
+\NC textext[.anchor](str) \NC position a text relative to the origin \NC \NR
+\NC thetextext[.anchor](str,pos) \NC position a text relative to the given position \NC \NR
+\NC rawtextext[.anchor](str,pos) \NC idem but with less checking \NC \NR
+\stoptabulate
+
+If needed all functionality could be combined in one call (textext) but we keep
+it this way.
+
+You need to keep in mind that text in \METAPOST\ is not a first class object but
+something virtual that is known to \METAFUN\ as something with path like properties
+but is actually dealt with in the backend. This means that timing is important.
+
+\starttyping
+\startMPinitializations
+picture p ; p := image(draw textext("Foo"););
+\stopMPinitializations
+
+\startMPcode
+ picture q ; q := image(draw textext("Bar"););
+ picture r ; r := image(draw textext("Gnu"););
+ draw p ;
+ draw q shifted (2cm,0) ;
+ draw r shifted (4cm,0) ;
+\stopMPcode
+\stoptyping
+
+This will work out well because an initialization is part of a figure, but
+this will fail:
+
+\starttyping
+\startMPinclusions
+picture p ; p := image(draw textext("Foo"););
+\stopMPinclusions
+\stoptyping
+
+because inclusions happen before the local textexts get initialized and
+due to the multipass implementation are not seeN a second time. The order of
+processing is:
+
+\starttabulate[|l|c|c|]
+\BC action \BC first pass \BC second pass \NC \NR
+\NC definitions \NC yes \NC \NC \NR
+\NC extensions \NC yes \NC \NC \NR
+\NC inclusions \NC yes \NC \NC \NR
+\NC begin figure \NC yes \NC yes \NC \NR
+\NC initializations \NC yes \NC yes \NC \NR
+\NC metapost code \NC yes \NC yes \NC \NR
+\NC end figure \NC yes \NC yes \NC \NR
+\stoptabulate
+
+The graph package (that comes with \METAPOST) has some pseudo typesetting on
+board needed to format numbers. Because we don't want to interfere with the
+definitions of macros used in that package we provide another set of macros for
+formatting: \type {fmttext}, \type {thefmttext} and \type {rawfmttext}.
+
+\startbuffer
+\startMPcode
+draw thefmttext("\bf@3.2f done",123.45678) withcolor darkred ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+Here we pass one variable to the format but there can be more: \inlinebuffer. In
+\LUA\ the \type {%} is used as format directive but that does not work well in
+\TEX\ and \LUA\ which is why we use \type {@} instead. The formatting is done
+with the formatters subsystem which is an extension to the regular \LUA\ \type
+{format} function. More information can be found in \type {clf-mkiv.pdf} but one
+extension is not mentioned there: \type {%!texexp!}. This directive takes one
+argument by default but optionally can take one or two extra arguments: the
+format of the base number and one for the exponent. The following code
+demonstrates this:
+
+\startbuffer
+\startMPcode{doublefun}
+draw image (
+ draw thefmttext.rt("@!texexp!", 10.4698E30, (0,-1LineHeight)) ;
+ draw thefmttext.rt("@1!texexp!",10.4698E30, (0,-2LineHeight)) ;
+ draw thefmttext.rt("@2!texexp!",10.4698E30,"@2.3f", (0,-3LineHeight)) ;
+ draw thefmttext.rt("@3!texexp!",10.4698E30,false,"@2i", (0,-4LineHeight)) ;
+ draw thefmttext.rt("@3!texexp!",10.4698E30,"@2.3f","@2i",(0,-5LineHeight)) ;
+) withcolor darkblue ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+We switch to double mode because we use large numbers.
+
+\startlinecorrection[blank]
+ \getbuffer
+\stoplinecorrection
+
+Of course this extra formatter is also supported in the \type {context}
+command:
+
+\startbuffer
+\startluacode
+context("%!texexp!, ", 10.4698E30)
+context("%1!texexp!, ", 10.4698E30)
+context("%2!texexp!, ", 10.4698E30,"@2.3f")
+context("%3!texexp! and ",10.4698E30,false,"@2i")
+context("%3!texexp!", 10.4698E30,"@2.3f","@2i")
+\stopluacode
+\stopbuffer
+
+\typebuffer
+
+This gives: \inlinebuffer .
+
+\stopsection
+
+\startsection[title=Lists (aka suffixed variables)]
+
+Sometimes graphics are constructed using lists. There are a few helpers (and
+maybe there will be some more) that can make things a bit easier. Say that we
+do this:
+
+\startbuffer
+pair a[] ;
+a[1] := (0,0) ; a[2] := (1,0) ;
+a[3] := (1,1) ; a[4] := (0,1) ;
+a[5] := (1,1) ; a[6] := (2,0) ;
+
+draw topath(a,--) ysized 2cm
+ withpen pencircle scaled 1mm
+ withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The \type {topath} macro converts the list into a path, in this case an ugly one.
+
+Say that we want to get rid of the sixth entry. For that we can use the \type
+{dispose} macro. You can use the dispose for any type (except a macro).
+
+\startbuffer
+dispose(a[6]) ;
+draw topath(a,--) ysized 2cm
+ withpen pencircle scaled 1mm
+ withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+We still have some duplicate entries here:
+
+\startbuffer
+dispose(a[6]) ;
+drawpoints topath(a,--) ysized 2cm
+ withpen pencircle scaled 1mm
+ withcolor .625red ;
+drawpointlabels topath(a,--) ysized 2cm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+These can be removed with:
+
+\startbuffer
+uniquelist(a) ;
+draw topath(a,--) ysized 2cm
+ withpen pencircle scaled 1mm
+ withcolor .625yellow ;
+drawpoints topath(a,--) ysized 2cm
+ withpen pencircle scaled 1mm
+ withcolor .625red ;
+drawpointlabels topath(a,--) ysized 2cm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Sometimes a list needs to be sorted and here is the solution:
+
+\startbuffer
+sortlist(a,nothing) ;
+draw topath(a,--) ysized 2cm
+ withpen pencircle scaled 1mm
+ withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The second argument can be an operator that takes a pair variable:
+
+\startbuffer
+sortlist(a,xpart) ;
+draw topath(a,--) ysized 2cm
+ withpen pencircle scaled 3mm
+ withcolor .625red ;
+sortlist(a,ypart) ;
+draw topath(a,--) ysized 2cm
+ withpen pencircle scaled 2mm
+ withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Constructing a list can be sped up with the \type {tolist} macro.
+
+\startbuffer
+pair a[], b[], c[], d[] ;
+tolist(a,1,(0,0),(1,0),(1,1),(0,1)--(1,1)--(2,2)) ;
+tolist(b,0,(0,0),(1,0),(1,1),(0,1)--(1,1)--(2,2)) ;
+tolist(c,(0,0),(1,0),(1,1),(0,1)--(1,1)--(2,2)) ;
+tolist(d,(0,0),(1,0),(1,1)) ;
+
+draw image (
+ draw topath(a,--) shifted (0,0) ;
+ draw topath(b,--) shifted (3,0) ;
+ draw topath(c,--) shifted (6,0) ;
+ draw topath(d,--) shifted (9,0) ;
+) ysized 2cm withpen pencircle scaled 1mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=Segmented paths]
+
+\index {segmented paths}There are all kind of helpers in \METAFUN\ and some are
+discussed here. In \in {figure} [fig:segmentedpaths] we see a few macros that
+return a (smooth) path made from segments. You can for instance use these to do
+things that use the points on a path, like anchoring text.
+
+\startbuffer
+def DrawSomePath(text t) =
+ drawpath t withcolor .625red ;
+ drawpoints t withcolor white ;
+ drawpointlabels t ;
+enddef ;
+
+DrawSomePath(circularpath(5) scaled 12cm) ;
+DrawSomePath(squarepath (5) scaled 8cm) ;
+DrawSomePath(linearpath (5) scaled 4cm) ;
+\stopbuffer
+
+\typebuffer
+
+\startplacefigure[title={A few segmented paths.},reference=fig:segmentedpaths]
+ \processMPbuffer
+\stopplacefigure
+
+\index {crossing paths}The following examples demonstrates two mechanisms. In the
+image two paths are drawn on top of each other but one of them has holes where
+the other one crosses. The \type {crossingunder} macro was written by Alan
+Braslau as part of the node based diagram builder. In the process the arrow
+drawing code was adapted to accept a picture.
+
+\startbuffer[a]
+drawarrow image (
+ draw ((fullcircle scaled 2.25cm) crossingunder (fullsquare scaled 2cm))
+ withpen pencircle scaled 1mm withcolor .625green ;
+ draw (fullsquare scaled 2cm)
+ withpen pencircle scaled 1mm withcolor .625blue ;
+) ;
+drawarrow image (
+ draw (fullsquare scaled 4cm)
+ withpen pencircle scaled 1mm withcolor .625red ;
+ draw ((fullcircle scaled 5cm) crossingunder (fullsquare scaled 4cm))
+ withpen pencircle scaled 1mm withcolor .625yellow ;
+) ;
+\stopbuffer
+
+\startbuffer[b]
+drawarrow image (
+ draw ((fullsquare scaled 2cm) crossingunder (fullcircle scaled 2.25cm))
+ withpen pencircle scaled 1mm withcolor .625blue ;
+ draw (fullcircle scaled 2.25cm)
+ withpen pencircle scaled 1mm withcolor .625green ;
+) ;
+drawarrow image (
+ draw (fullcircle scaled 5cm)
+ withpen pencircle scaled 1mm withcolor .625yellow ;
+ draw ((fullsquare scaled 4cm) crossingunder (fullcircle scaled 5cm))
+ withpen pencircle scaled 1mm withcolor .625red ;
+) ;
+\stopbuffer
+
+\typebuffer[a]
+
+The next variant uses a different order:
+
+\typebuffer[b]
+
+The results are shown in \in {figure} [fig:crossingunder]. The internal variable
+\type {crossingscale} can be used to make the gap wider or narrower. The gap has
+a default value of 20.
+
+\startplacefigure[title=Crossing paths without touching,reference=fig:crossingunder]
+ \startcombination
+ {\processMPbuffer[a]} {}
+ {\processMPbuffer[b]} {}
+ \stopcombination
+\stopplacefigure
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-colofon-paper.tex b/doc/context/sources/general/manuals/metafun/metafun-colofon-paper.tex
new file mode 100644
index 000000000..1a611a325
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-colofon-paper.tex
@@ -0,0 +1,19 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-colofon-paper
+
+\environment metafun-environment
+
+\startstandardmakeup
+
+ \vfill
+
+ \setupalign[flushright,broad]
+
+ \component metafun-colofon
+
+\stopstandardmakeup
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-colofon-screen.tex b/doc/context/sources/general/manuals/metafun/metafun-colofon-screen.tex
new file mode 100644
index 000000000..590c7725f
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-colofon-screen.tex
@@ -0,0 +1,21 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-colofon-screen
+
+\environment metafun-environment
+
+\page
+
+\start
+
+ \setupalign[flushright,broad]
+
+ \component metafun-colofon
+
+\stop
+
+\page
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-colofon.tex b/doc/context/sources/general/manuals/metafun/metafun-colofon.tex
new file mode 100644
index 000000000..b4c162a89
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-colofon.tex
@@ -0,0 +1,56 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-colofon
+
+\environment metafun-environment
+
+\introsubject{For them}
+
+I owe much inspiration to both my parents. My mother Jannie constantly
+demonstrated me that computer graphics will never improve nature. She also
+converted one of my first \METAPOST\ graphics into a patchwork that will remind
+me forever that handcraft is more vivid than computer artwork. My father Hein has
+spent a great deal of his life teaching math, and I'm sure he would have loved
+\METAPOST. I inherited his love for books. I therefore dedicate this document to
+them.
+
+\introsubject{Colofon}
+
+This manual is typeset with \CONTEXT\ \MKIV. No special tricks are used and
+everything you see in here, is available for \CONTEXT\ users. The text is typeset
+in Palatino and Computer Modern Typewriter. We used \LUATEX\ as \TEX\ processing
+engine. Since this document is meant to be printed in color, some examples will
+look sub||optimal when printed in black and white.
+
+\introsubject{Graphics}
+
+The artist impression of one of Hasselts canals at \at {page} [canal] is made by
+Johan Jonker. The \CDROM\ production process graphic at \at {page} [hacker] is a
+scan of a graphic made by Hester de Weert.
+
+\introsubject{Copyright}
+
+\startlines
+Hans Hagen, PRAGMA Advanced Document Engineering, Hasselt NL
+copyright: 1999-\currentdate[year] / version 4: \currentdate
+\stoplines
+
+\introsubject{Publisher}
+
+\startlines
+publisher: Boekplan, NL
+isbn-ean: 978-94-90688-02-8
+website: www.boekplan.nl
+\stoplines
+
+\introsubject{Info}
+
+\startlines
+internet: www.pragma-ade.com
+support: ntg-context@ntg.nl
+context: www.contextgarden.net
+\stoplines
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-contents.tex b/doc/context/sources/general/manuals/metafun/metafun-contents.tex
new file mode 100644
index 000000000..0767a0248
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-contents.tex
@@ -0,0 +1,17 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-contents
+
+\environment metafun-environment
+
+\starttitle[reference=content,title={Content}]
+
+ \startcolumns
+ \placelist[chapter,section]
+ \stopcolumns
+
+\stoptitle
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-conventions.tex b/doc/context/sources/general/manuals/metafun/metafun-conventions.tex
new file mode 100644
index 000000000..6a6072c56
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-conventions.tex
@@ -0,0 +1,117 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-conventions
+
+\environment metafun-environment
+
+\startchapter[title={Conventions}]
+
+\index {running}
+\index {processing}
+
+When reading this manual, you may be tempted to test the examples shown. This can
+be done in several ways. You can make a file and process that file by \METAPOST.
+Such a file looks like:
+
+\starttyping
+beginfig(1) ;
+ fill fullcircle scaled 5cm withcolor red ; % a graphic
+endfig ;
+
+end .
+\stoptyping
+
+Don't forget the semi||colons that end the statements. If the file is saved as
+\type {yourfile.mp}, then the file can be processed. Before we process this file,
+we first need to load some basic \METAPOST\ definitions, because the built in
+repertoire of commands is rather limited. Such a set is called a format. The
+standard format is called {metapost} but we will use a more extensive set of
+macros \type {metafun}. In the past such a set was converted into a \type {mem}
+file and running the above file was done with:
+
+\starttyping
+mpost --mem=metafun.mem yourfile
+\stoptyping
+
+However, this is no longer the case and macros need to be loaded at startup as
+follows:
+
+\starttyping
+mpost --ini metafun.mpii yourfile.mp
+\stoptyping
+
+Watch the suffix \type {mpii}: this refers to the stand alone, the one that
+doesn't rely on \LUATEX.
+
+After the run the results are available in \type {yourfile.1} and can be viewed
+with \GHOSTSCRIPT. You don't need to close the file so reprocessing is very
+convenient.
+
+Because we will go beyond standard \METAPOST, we will use the \type {mpiv} files.
+These work with the library which in turn means that we will run from within
+\CONTEXT. This has the advantage that we also have advanced font support at our
+hands. In that case, a simple file looks like:
+
+\starttyping
+\starttext
+ \startMPpage
+ fill fullcircle scaled 5cm withcolor red ;
+ \stopMPpage
+ \startMPpage
+ fill unitsquare scaled 5cm withcolor red ;
+ \stopMPpage
+\stoptext
+\stoptyping
+
+If the file is saved as \type {yourfile.tex}, then you can produce a \PDF\ file
+with: \footnote {In fact, you could also process the \METAPOST\ file directly
+because the \type {context} script will recognize it as such and wrap it into
+a page.}
+
+\starttyping
+context yourfile
+\stoptyping
+
+The previous call will use \LUATEX\ and \CONTEXT\ \MKIV\ to produce a file with
+two pages using the built in \METAPOST\ library with \METAFUN. When you use this
+route you will automatically get the integrated text support shown in this
+manual, including \OPENTYPE\ support. If one page is enough, you can also say:
+
+\starttyping
+\startMPpage
+fill fullcircle scaled 5cm withcolor red ;
+\stopMPpage
+\stoptyping
+
+So when you have a running \CONTEXT\ on your system you don't need to bother
+about installing \METAPOST\ and running \METAFUN.
+
+We will use lots of color. Don't worry if your red is not our red, or your yellow
+does not match ours. We've made color definitions to match the overall design of
+this document, but you should feel free to use any color of choice in the
+upcoming examples.
+
+By default, \CONTEXT\ has turned its color mechanism on. If you don't want your
+graphics to have color, you should say:
+
+\starttyping
+\setupcolors[state=stop]
+\stoptyping
+
+but in todays documents color is so normal that you will probably never do that.
+Because \METAFUN\ hooks into the \CONTEXT\ color mechanism, you can also use its
+color space and conversion related features.
+
+You need to keep in mind that just like \CONTEXT\ \MKII\ is frozen, the \type
+{mpii} macros are also not extended. From now on we assume that you use \CONTEXT\
+\MKIV\ which exclusively uses \type {mpiv} macros.
+
+Even if you want to use \METAFUN\ but not \CONTEXT, you can still best use the
+mentioned page method as it will give you decent text processing. You need to
+know (and use) only a few \CONTEXT\ commands then.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-debugging.tex b/doc/context/sources/general/manuals/metafun/metafun-debugging.tex
new file mode 100644
index 000000000..4174d34e1
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-debugging.tex
@@ -0,0 +1,383 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent mfun-debugging
+
+\environment metafun-environment
+
+\startchapter[reference=sec:debugging,title={Debugging}]
+
+\index{debugging}
+
+\startintro
+
+Those familiar with \CONTEXT\ will know that it has quite some visual debugging
+features build in. So, what can you expect of the \METAPOST\ macros that come
+with \CONTEXT ? In this chapter we will introduce a few commands that show some
+insight in what \METAPOST\ is doing.
+
+\stopintro
+
+\startsection[title=Showing paths]
+
+Since the outcome of \METAPOST\ code is in many respects more predictable than
+that of \TEX\ code, we don't need that advanced visual debugging features.
+Nevertheless we provide a few, that are all based on visualizing paths.
+
+\startbuffer
+path p ; p := fullcircle scaled 4cm ;
+drawpath p ; drawpoints p ; drawpointlabels p ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+This visualization is achieved by using dedicated drawing commands:
+
+\typebuffer
+
+Since control points play an important role in defining the shape, visualizing
+them may shed some insight in what \METAPOST\ is doing.
+
+\startbuffer
+path p ; p := fullcircle xscaled 4cm yscaled 3cm ;
+drawpath p ; drawcontrollines p ;
+drawpoints p ; drawcontrolpoints p ; drawpointlabels p ;
+\stopbuffer
+
+\typebuffer
+
+The pre and post control points show up as small dots and are connected to their
+parent point with thin lines.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+You can deduce the direction of a path from the way the
+points are numbered, but using an arrow to indicate the
+direction is more clear.
+
+\startbuffer
+path p ; p := fullcircle xscaled 4cm yscaled 3cm ;
+drawarrowpath p ; drawcontrollines p ;
+drawpoints p ; drawcontrolpoints p ; drawpointlabels p ;
+\stopbuffer
+
+\typebuffer
+
+The \type {drawarrowpath} is responsible for the arrow. Especially when you are
+in the process of defining macros that have to calculate intersections or take
+subpaths, knowing the direction may be of help.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The next table summarizes the special drawing commands:
+
+\starttabulate[|lT|l|]
+\HL
+\NC drawpath \NC the path \NC \NR
+\NC drawarrowpath \NC the direction of the path \NC \NR
+\NC drawcontrollines \NC the lines to the control points \NC \NR
+\NC drawpoints \NC the points that make up the path \NC \NR
+\NC drawcontrolpoints \NC the control points of the points \NC \NR
+\NC drawpointlabels \NC the numbers of the points \NC \NR
+\HL
+\stoptabulate
+
+You can set the characteristics of these like you set \type {drawoptions}. The
+default settings are as follows:
+
+\starttyping
+drawpathoptions (withpen pencircle scaled 5 withcolor .8white) ;
+drawpointoptions (withpen pencircle scaled 4 withcolor black) ;
+drawcontroloptions(withpen pencircle scaled 2.5 withcolor black) ;
+drawlineoptions (withpen pencircle scaled 1 withcolor .5white) ;
+drawlabeloptions () ;
+\stoptyping
+
+Two more options are \type {draworiginoptions} and \type {drawboundoptions} which
+are used when visualizing the bounding box and origin.
+
+\startbuffer
+swappointlabels := true ;
+path p ; p := fullcircle xscaled 4cm yscaled 3cm ;
+drawarrowpath p ; drawcontrollines p ;
+drawpoints p ; drawcontrolpoints p ; drawpointlabels p ;
+drawboundingbox p ; draworigin ;
+\stopbuffer
+
+\typebuffer
+
+In this example we have set \type {swappointlabels} to change the place of the
+labels. You can set the variable \type {originlength} to tune the appearance of
+the origin.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+You can pass options directly, like you do with \type {draw} and \type {fill}.
+Those options override the defaults.
+
+\startbuffer
+path p ; p := fullcircle xscaled 6cm yscaled 3cm rotated 15 ;
+drawarrowpath p ;
+drawcontrollines p withcolor .625red ;
+drawpoints p withcolor .625yellow ;
+drawcontrolpoints p withcolor .625yellow ;
+drawpointlabels p withcolor .625yellow ;
+drawboundingbox p ;
+draworigin withcolor .625red ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Here we used the options:
+
+\typebuffer
+
+Sometimes it makes sense to draw a simple coordinate system, and for that purpose
+we have three more macros. They draw axis and tickmarks.
+
+\startbuffer
+drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ;
+\stopbuffer
+
+\typebuffer
+
+The system drawn is based on the bounding box specification of the path passed to
+the macro. You can also draw one axis, using \type {drawxticks} or \type
+{drawyticks}. Here we show the previous command.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+By default, the ticks are placed at .5cm distance, but you can change this by
+setting \type {tickstep} to a different value.
+
+\startbuffer
+tickstep := 1cm ; ticklength := 2mm ;
+drawticks fullsquare xscaled 4cm yscaled 3cm ;
+tickstep := tickstep/2 ; ticklength := ticklength/2 ;
+drawticks fullsquare xscaled 4cm yscaled 3cm ;
+\stopbuffer
+
+\typebuffer
+
+The \type {ticklength} variable specifies the length of a tick. Here we
+manipulated both the variables to get a more advanced system.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+If visualizing a path would mean that we would have to key in al those
+draw||commands, you could hardly call it a comfortable tool. Therefore, we can
+say:
+
+\startbuffer
+drawwholepath fullsquare scaled 3cm rotated 30 randomized 5mm ;
+\stopbuffer
+
+\typebuffer
+
+The \type {drawwholepath} command shows everything except the axis.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+If even this is too much labour, you may say:
+
+\starttyping
+visualizepaths ;
+\stoptyping
+
+This redefines the \type {draw} and \type {fill} command in such a way that they
+also show all the information.
+
+\startbuffer
+visualizepaths ;
+draw fullsquare scaled 3cm rotated 30 randomized 2mm ;
+\stopbuffer
+
+\typebuffer
+
+You may compare this feature to the \type {\showmakeup} command available in
+\CONTEXT, that redefines the \TEX\ primitives that deal with boxes, glues,
+penalties, and alike.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Of course you may want to take a look at the \METAPOST\ manual for its built in
+(more verbose) tracing options. One command that may prove to be useful is \type
+{show}, that you can apply to any variable. This command reports the current
+value (if known) to the terminal and log file.
+
+\startlinecorrection[blank]
+{\showmakeup\processMPbuffer}
+\stoplinecorrection
+
+The previous picture shows what is typeset when we also say \type {\showmakeup}.
+This command visualizes \TEX's boxes, skips, kerns and penalties. As you can see,
+there are some boxes involved, which is due to the conversion of \METAPOST\
+output to \PDF.
+
+\starttyping
+\startlinecorrection[blank]
+... the graphic ...
+\stoplinecorrection
+\stoptyping
+
+The small bar is a kern and the small rectangles are penalties. More details on
+this debugger can be found in the \CONTEXT\ manuals and the documentation of the
+modules involved.
+
+\stopsection
+
+\startsection[title=Comments]
+
+Sometimes, when trouble strikes, you might want to peek in the \PDF\ file to see
+what gets written there. Each graphic is marked with a number but when you
+have many it might make sense to add a comment to help you locate the code.
+
+\startbuffer
+\startMPcode
+ comment("test graphic") ;
+ message("processing a test graphic") ;
+ draw fullsquare scaled 1cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+This renders as:
+
+\startlinecorrection[blank]
+ \getbuffer
+\stoplinecorrection
+
+On the console we get these messages:
+
+\starttyping
+metapost > message : processing a test graphic
+metapost > warning : processing a test graphic
+\stoptyping
+
+And in the \PDF\ file we will find:
+
+\starttyping
+% mps graphic 1: begin
+% mps graphic 1: test graphic
+q 0 g 0 G 10 M 1 j 1 J
+0.500000000 w
+-14.173233032 -14.173233032 m
+14.173233032 -14.173233032 l
+14.173233032 14.173233032 l
+-14.173233032 14.173233032 l
+-14.173233032 -14.173233032 l
+h S
+0 g 0 G Q
+% mps graphic 1: end
+\stoptyping
+
+Here are some examples of constructed messages:
+
+\starttyping
+message "2: okay (done)" ;
+message "1: " & dq & "okay" & dq & " (done)" ;
+message "3: " & quotation "okay" & " (done)" ;
+message "3: " & quote "okay" & " (done)" ;
+message "4: " & quotation 123 & " (done)" ;
+message "5: " & quotation true & " (done)" ;
+message "6: " & quote true & " (done)" ;
+message "7: " & tostring true & " (done)" ;
+message "8: " & tostring (1,2) & " (done)" ;
+message "9: " & topair (1,2) & " (done)" ;
+\stoptyping
+
+and this is what you get:
+
+\starttyping
+metapost > message : 2: okay (done)
+metapost > message : 1: "okay" (done)
+metapost > message : 3: "okay" (done)
+metapost > message : 3: 'okay' (done)
+metapost > message : 4: "123" (done)
+metapost > message : 5: "true" (done)
+metapost > message : 6: 'true' (done)
+metapost > message : 7: true (done)
+metapost > message : 8: 1 2 (done)
+metapost > message : 9: (1,2) (done)
+\stoptyping
+
+\stopsection
+
+\startsection[title=Pens]
+
+A circular pen is applied to a path in a different way than for instance a
+square pen. Circular pens are mapped onto \POSTSCRIPT\ pens while for other
+pens an outline is calculated that gets filled. Take this code:
+
+\startbuffer[a]
+\startMPcode
+ draw fullcircle xscaled 6cm yscaled 3cm
+ withpen pensquare scaled 5mm rotated 30
+ withcolor .625yellow ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[b]
+\startMPcode
+ draw envelope pensquare scaled 5mm rotated 30 of
+ (fullcircle xscaled 6cm yscaled 3cm)
+ withpen pencircle scaled 1mm
+ withcolor .375white ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[c]
+\enabletrackers[metapost.forcestroke]
+\startMPcode
+ draw fullcircle xscaled 6cm yscaled 3cm
+ withpen pensquare scaled 5mm rotated 30
+ withcolor .625red ;
+\stopMPcode
+\disabletrackers[metapost.forcestroke]
+\stopbuffer
+
+\typebuffer[a]
+
+and this:
+
+\typebuffer[b]
+
+and:
+
+\typebuffer[c]
+
+When we overlay these three we get. The envelope only returns the outer curve.
+
+\startlinecorrection[blank]
+\startoverlay
+ {\getbuffer[a]}
+ {\getbuffer[b]}
+ {\getbuffer[c]}
+\stopoverlay
+\stoplinecorrection
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-document.tex b/doc/context/sources/general/manuals/metafun/metafun-document.tex
new file mode 100644
index 000000000..bb5540850
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-document.tex
@@ -0,0 +1,118 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-document
+
+\environment metafun-environment
+
+\startchapter[title={This document}]
+
+\startintro
+
+This document is produced in \CONTEXT\ and can serve as an example of how to
+integrate \METAPOST\ graphics into \TEX. In this appendix we will discuss some
+details of producing this document.
+
+\stopintro
+
+We did not use any special tricks, so most of the examples you have seen are
+coded just as shown. We used buffers to ensure that the code used to produce the
+accompanying graphic is identical to the typeset code in the document. Here is an
+example.
+
+\starttyping
+\startbuffer[dummy]
+draw fullcircle
+ xscaled 3cm yscaled 2cm
+ rotatedaround(origin,30)
+ withcolor .625red ;
+\stopbuffer
+\stoptyping
+
+Instead of using \type {\getbuffer}, we used the following command:
+
+\starttyping
+\startlinecorrection[blank]
+\processMPbuffer[dummy]
+\stoplinecorrection
+\stoptyping
+
+The line correction commands take care of proper spacing around the graphic. If
+you want to process more buffers at once, you can pass their names as a comma
+separated list. Alternatively, we could have said:
+
+\starttyping
+\startuseMPgraphic{dummy}
+ draw fullcircle
+ xscaled 3cm yscaled 2cm
+ rotatedaround(origin,30)
+ withcolor .625red ;
+\stopuseMPgraphic
+\stoptyping
+
+When including this graphic, we again take care of spacing.
+
+\starttyping
+\startlinecorrection[blank]
+\useMPgraphic{dummy}
+\stoplinecorrection
+\stoptyping
+
+The first version of this manual was produced with \PDFTEX\ and call|-|outs to
+\METAPOST. Because the number of graphics is large, we processed that version
+using the \type {--automp} directive (at that moment we were using \TEXEXEC). And
+even then runtime was so unconveniently long that updating this manual became
+less and less fun. The current version is produced with \LUATEX\ and \CONTEXT\
+\MKIV, which brings down the runtime (including runtime calls to independent
+\CONTEXT\ runs for the outline examples) to some 45 seconds on a 2.2 Gig Dell
+M90. Given that (at the time of writing this) over 1700 graphics are generated on
+the fly, this is not bad at all. On my current machine, a Dell M6700 with an
+Intel Core i7|-|3840QM running at 2.8 (3.9) Ghz (and Windows~8) the runtime of
+the third version was just above 20 seconds all|-|in and some 25\percent\ less
+when using \LUAJITTEX. When I started with updating to version 4 of this manual,
+I timed about 15 seconds on the same machine (but with Windows-10) which means
+that in the meantime the \CONTEXT|/|\LUATEX\ combination gained some 25\%
+performance. Using the new Bash|-|On|-|Windows subsystem gives the same
+performance. Of course each update adds pages so in the end we need more time
+with each update but it remains a nice test case. The tight integration of \TEX,
+\METAPOST\ and \LUA\ pays off.
+
+The document style is not that complicated. The main complication in such a
+document is to make sure that \METAPOST\ is operating under the same font regime,
+but in \MKIV\ this happens automatically. As document font we use the URW
+Palatino for the running text combined with Computer Modern Typewriter. Because
+this document is available as paper and screen document, some large graphics are
+scaled down in the screen version.
+
+We don't use any special tricks in typesetting this document, but when we added
+the section about transparency, a dirty trick was needed in a few cases in order to
+get the described results. Because the screen document has gray backgrounds,
+exclusive transparencies come out \quote {wrong}. In the function drawing example
+we use the following trick to get a black background behind the graphics only. We
+have a buffer that contains a few lines of code:
+
+% buffer only available in screen mode
+
+\starttyping
+picture savedpicture ;
+savedpicture := currentpicture ;
+currentpicture := nullpicture ;
+draw savedpicture withcolor black ;
+draw savedpicture ;
+\stoptyping
+
+Since we use buffers for the graphics as well, we can now process a buffer with
+name \type {example} as follows:
+
+\starttyping
+\processbuffer[example,wipe]
+\stoptyping
+
+This means that the example code is included two times. After it is processed, we
+recolor the currentpicture black, and after that we add the original picture once
+again.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-effects.tex b/doc/context/sources/general/manuals/metafun/metafun-effects.tex
new file mode 100644
index 000000000..74e7d487e
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-effects.tex
@@ -0,0 +1,2596 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+% graphic text takes 5 sec on 21
+
+\startcomponent metafun-effects
+
+\environment metafun-environment
+
+\useMPlibrary[outlines]
+
+\startchapter[reference=sec:effects,title={Special effects}]
+
+\startintro
+
+Sometimes we want to go beyond \METAPOST's native features. Examples of such an
+extension are \CMYK\ colors, shading and transparency. Although features like
+this should be used with care, sometimes the documents look and feel can profit
+from it.
+
+If you don't want the whole graphic, but only a part of it, clipping comes into
+play. In addition to the standard clipping features, we can use \METAPOST\ to
+provide a decent clipping path. In this chapter we will uncover the details.
+
+We will also introduce ways to include externally defined graphics and outline
+fonts. We will demonstrate that within reasonable bounds you can manipulate such
+graphics.
+
+\stopintro
+
+\startsection[title={Spot colors}]
+
+You can define spot and multitone colors directly in \METAFUN, although normally
+you will do it at the \TEX\ end for consistency. At the \TEX\ end we define this:
+
+\startbuffer
+\definecolor [SpotBlue] [c=1,m=.38,y=0,k=.64]
+\definecolor [SpotYellow] [c=0,m=.28,y=1,k=.06]
+\definemultitonecolor [MultiColor] [SpotBlue=.5,SpotYellow=.25]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+draw image (
+ fill unitsquare shifted (7,0)
+ withcolor namedcolor("MultiColor") ;
+ fill unitsquare shifted (6,0)
+ withcolor .6 * spotcolor("temp1",red) ;
+ fill unitsquare shifted (5,0)
+ withcolor .4 * spotcolor("temp1",red) ;
+ fill unitsquare shifted (4,0)
+ withcolor .5 * spotcolor("temp2",.5green) ;
+ fill unitsquare shifted (3,0)
+ withcolor .5 * spotcolor("temp3",green) ;
+ fill unitsquare shifted (2,0)
+ withcolor multitonecolor("temp4",blue/2,yellow/2,green/2,magenta/3) ;
+) xsized TextWidth ;
+\stopbuffer
+
+Next we process this graphic:
+
+\typebuffer
+
+and get:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Transparency}]
+
+\index{transparency}
+
+{\em In the screen version we use a light gray background color. As a result,
+some of the transparency methods demonstrated here give unexpected results. The
+A4 version of this document demonstrates the real effects.}
+
+Although transparent colors have been around for some time already, it was only
+around 2000 that they made it as a high level feature into document format
+languages like \PDF. Supporting such a feature at a higher abstraction level is
+not only more portable, but also less sensitive for misinterpretation.
+
+\startbuffer[mpdef]
+vardef ColorCircle (expr method, factor, ca, cb, cc) =
+ save u, p ; path p ; p := fullcircle shifted (1/4,0) ;
+ image
+ ( fill p rotated 90 withcolor ca withtransparency (method,factor) ;
+ fill p rotated 210 withcolor cb withtransparency (method,factor) ;
+ fill p rotated 330 withcolor cc withtransparency (method,factor) ; )
+enddef ;
+\stopbuffer
+
+\typebuffer[mpdef]
+
+\startbuffer[mp]
+draw ColorCircle ("normal", .5, red, green, blue) xsized 3cm ;
+currentpicture := currentpicture shifted (-4cm,0) ;
+draw ColorCircle ("exclusion", .5, red, green, blue) xsized 3cm ;
+currentpicture := currentpicture shifted (-4cm,0) ;
+draw ColorCircle ("exclusion", 1, red, green, blue) xsized 3cm ;
+\stopbuffer
+
+\typebuffer[mp]
+
+\startlinecorrection[blank]
+\processMPbuffer[mpdef,mp]
+\stoplinecorrection
+
+\startbuffer[mp]
+cmykcolor xcyan ; xcyan := (1,0,0,0) ;
+cmykcolor xmagenta ; xmagenta := (0,1,0,0) ;
+cmykcolor xyellow ; xyellow := (0,0,1,0) ;
+
+draw ColorCircle ("exclusion", .5, xcyan, xmagenta, xyellow) xsized 3cm ;
+\stopbuffer
+
+\typebuffer[mp]
+
+\startlinecorrection[blank]
+\processMPbuffer[mpdef,mp]
+\stoplinecorrection
+
+You can be tempted to use transparency as a convenient way to achieve soft
+colors. In that case you should be aware of the fact that rendering transparent
+colors takes more time than normal colors \footnote {When your printer does not
+support this feature natively, the intermediate (\POSTSCRIPT) file send to the
+printing engine is also larger.}
+
+Fortunatey, \METAPOST\ provides a similar mechanism. The last circle in the
+following row demonstrates how we can trigger colors proportionally to other
+colors. Normally \type {background} is white, but you can set predefined color
+variables to another value.
+
+\startbuffer[mp]
+path p ; p := fullcircle scaled 2cm ;
+fill p shifted (0cm,0) withcolor blue ;
+fill p shifted (3cm,0) withcolor .5blue ;
+fill p shifted (6cm,0) withcolor transparent (1,0.5,blue) ;
+fill p shifted (9cm,0) withcolor .5[blue,white] ;
+\stopbuffer
+
+\typebuffer[mp]
+
+\startlinecorrection[blank]
+\processMPbuffer[mp]
+\stoplinecorrection
+
+The next series demonstrates that we use the complementary factor \type {.7} in
+the \METAPOST\ soft color to achieve the same softness as the \type {.3}
+transparency.
+
+\startbuffer[mp]
+path p ; p := fullcircle scaled 2cm ;
+fill p shifted (0cm,0) withcolor red ;
+fill p shifted (3cm,0) withcolor .7red ;
+fill p shifted (6cm,0) withcolor transparent (1,0.3,red) ;
+fill p shifted (9cm,0) withcolor .7[red,white] ;
+\stopbuffer
+
+\typebuffer[mp]
+
+\startlinecorrection[blank]
+\processMPbuffer[mp]
+\stoplinecorrection
+
+\startbuffer[mp]
+vardef SampleText (expr t, c) =
+ save p ; picture p ;
+ p := image (draw t infont "\truefontname{Regular}") ;
+ draw (p shifted (- xpart center p,0)) scaled 5 withcolor c;
+enddef ;
+
+SampleText ("Much Of This" , transparent(1, .5, red )) ;
+SampleText ("Functionality" , transparent(1, .5, green)) ;
+SampleText ("Was Written" , transparent(1, .5, blue )) ;
+SampleText ("While Listening", transparent(1, .5, cmyk(1,0,0,0))) ;
+SampleText ("To the CD's Of" , transparent(1, .5, cmyk(0,1,0,0))) ;
+SampleText ("Tori Amos" , transparent(1, .5, cmyk(0,0,1,0))) ;
+\stopbuffer
+
+So far we have applied transparent colors to shapes but text can also be the
+target.
+
+\typebuffer[mp]
+
+The source code of this example illustrates that the \CMYK\ color space is also
+supported. The \type {\truefontname} macro communicates the running font from
+\TEX\ to \METAPOST. Instead of such low level code one can of course also use the
+\type {textext} macro.
+
+\startbuffer[mp]
+vardef SampleText (expr t) =
+ draw textext(t) scaled 5 ;
+enddef ;
+
+SampleText ("\colored[a=1,t=.5,r=1]{Much Of This}") ;
+SampleText ("\colored[a=1,t=.5,g=1]{Functionality}") ;
+SampleText ("\colored[a=1,t=.5,b=1]{Was Written}") ;
+SampleText ("\colored[a=1,t=.5,c=1]{While Listening}") ;
+SampleText ("\colored[a=1,t=.5,m=1]{To the CD's Of}") ;
+SampleText ("\colored[a=1,t=.5,y=1]{Tori Amos}") ;
+\stopbuffer
+
+However, as we do the typesetting in \TEX\ in \MKIV\ this is the way to go:
+
+\typebuffer[mp]
+
+As expected we get:
+
+\startlinecorrection[blank]
+\processMPbuffer[mp]
+\stoplinecorrection
+
+Currently the 12 in \PDF\ available transparency methods are supported. \footnote
+{In the future we may also support more control over the individual methods.} You
+can use both numbers and names. As you may expect, both \CONTEXT\ and \METAFUN\
+support transparency in the same way. \in {Figure} [fig:transparencies] shows how
+the method affects the result.
+
+\startuseMPgraphic{test}
+numeric u ; u := if lua.mp.mode("screen") : 12mm else : 20mm fi ;
+
+path p ; p := fullcircle scaled u shifted (u/4,0);
+
+% cmykcolor xyellow ; xyellow := (0,0,1,0) ;
+% color xgreen ; xgreen := (0,1,0) ;
+% color xblue ; xblue := (0,0,1) ;
+
+% fill p rotated 90 withcolor transparent("\MPvar{a}",.5,xyellow) ;
+% fill p rotated 210 withcolor transparent("\MPvar{a}",.5,xgreen) ;
+% fill p rotated 330 withcolor transparent("\MPvar{a}",.5,xblue) ;
+
+fill p rotated 90 withcolor (0,0,1,0) withtransparency("\MPvar{a}",.5) ;
+fill p rotated 210 withcolor (0,1,0) withtransparency("\MPvar{a}",.5) ;
+fill p rotated 330 withcolor (0,0,1) withtransparency("\MPvar{a}",.5) ;
+\stopuseMPgraphic
+
+\startplacefigure[location=here,reference=fig:transparencies,title={The 12 transparency alternatives by name.}]
+ \doifelsemode {screen} {
+ \setupcombination[nx=8,ny=2]
+ } {
+ \setupcombination[nx=4,ny=4]
+ }
+ \startcombination
+ {\useMPgraphic{test}{a=normal}} {\tttf normal}
+ {\useMPgraphic{test}{a=multiply}} {\tttf multiply}
+ {\useMPgraphic{test}{a=screen}} {\tttf screen}
+ {\useMPgraphic{test}{a=overlay}} {\tttf overlay}
+ {\useMPgraphic{test}{a=softlight}} {\tttf softlight}
+ {\useMPgraphic{test}{a=hardlight}} {\tttf hardlight}
+ {\useMPgraphic{test}{a=colordodge}} {\tttf colordodge}
+ {\useMPgraphic{test}{a=colorburn}} {\tttf colorburn}
+ {\useMPgraphic{test}{a=darken}} {\tttf darken}
+ {\useMPgraphic{test}{a=lighten}} {\tttf lighten}
+ {\useMPgraphic{test}{a=difference}} {\tttf difference}
+ {\useMPgraphic{test}{a=exclusion}} {\tttf exclusion}
+ {\useMPgraphic{test}{a=hue}} {\tttf hue}
+ {\useMPgraphic{test}{a=saturation}} {\tttf saturation}
+ {\useMPgraphic{test}{a=color}} {\tttf color}
+ {\useMPgraphic{test}{a=luminosity}} {\tttf luminosity}
+ \stopcombination
+\stopplacefigure
+
+In \CONTEXT\ a transparent color is defined in a similar way as \quote {normal}
+colors. The transparency method is specified with the \type {a} key (either by
+number or by name) and the factor \type {t}.
+
+\startbuffer
+\definecolor [tred] [r=1,t=.5,a=exclusion]
+\definecolor [tgreen] [g=1,t=.5,a=exclusion]
+\definecolor [tblue] [b=1,t=.5,a=exclusion]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Both keys are needed. You can define your own symbolic names using:
+
+\starttyping
+\definetransparency [myowndefault] [1]
+\stoptyping
+
+The \type {\MPcolor} macro passes a color from \CONTEXT\ to \METAPOST, including
+the transparency specification.
+
+\startbuffer[mp]
+u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0);
+
+fill p rotated 90 withcolor \MPcolor{tred} ;
+fill p rotated 210 withcolor \MPcolor{tgreen} ;
+fill p rotated 330 withcolor \MPcolor{tblue} ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[mp]
+\stoplinecorrection
+
+Of course this also works well for \CMYK\ colors.
+
+\startbuffer
+\definecolor[tred] [c=1,k=.2,t=.5,a=1]
+\definecolor[tgreen][m=1,k=.2,t=.5,a=1]
+\definecolor[tblue] [y=1,k=.2,t=.5,a=1]
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[mp]
+\stoplinecorrection
+
+Gray scales work as well:
+
+\startbuffer
+\definecolor[ta][s=.9,t=.7,a=11]
+\definecolor[tb][s=.7,t=.7,a=11]
+\definecolor[tc][s=.5,t=.7,a=11]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We apply this to some text. By using an overlay we can conveniently explore the
+difference in fonts.
+
+% \startbuffer
+% def SampleText (expr s, f, c) =
+% draw s infont f scaled 5 withcolor c ;
+% enddef ;
+
+% SampleText("Hello", "\truefontname{Regular}" , \MPcolor{ta}) ;
+% SampleText("Hello", "\truefontname{RegularBold}" , \MPcolor{tb}) ;
+% SampleText("Hello", "\truefontname{RegularSlanted}", \MPcolor{tc}) ;
+% \stopbuffer
+
+\startbuffer
+draw textext("\color[ta]{\tf Hello}") scaled 5 ;
+draw textext("\color[tb]{\bf Hello}") scaled 5 ;
+draw textext("\color[tc]{\sl Hello}") scaled 5 ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Shading}]
+
+\startsubsection[title=Introduction]
+
+\index{shading}
+
+In this section we introduce different kinds of shading. Since \METAPOST\ does
+not support this feature directly, we have to fall back on a few tricks. For the
+moment shading is only supported in \PDF. In the following examples, we will use
+the next three colors:
+
+\startbuffer
+\definecolor[a][darkyellow]
+\definecolor[b][s=.8]
+\definecolor[c][darkred]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+Shading support evolved in steps and alongside development of the backend code. Also,
+as it became more used a second interface came available. We discuss both here.
+
+\stopsubsection
+
+\startsubsection[title=The old method]
+
+First we discuss the old method which is still valid and also available in
+\MKII. It illustrates some of the principles.
+
+\startbuffer[a]
+\startuniqueMPgraphic{CircularShade}
+ path p ;
+ p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
+ circular_shade(p,0,\MPcolor{a},\MPcolor{b}) ;
+\stopuniqueMPgraphic
+
+\startuniqueMPgraphic{LinearShade}
+ path p ;
+ p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
+ linear_shade(p,0,\MPcolor{a},\MPcolor{b});
+\stopuniqueMPgraphic
+\stopbuffer
+
+\startbuffer[b]
+\defineoverlay[circular shade][\uniqueMPgraphic{CircularShade}]
+\defineoverlay[linear shade] [\uniqueMPgraphic{LinearShade}]
+\stopbuffer
+
+\startbuffer[c]
+\framed
+ [background=circular shade,frame=off]
+ {\bf \white Hi there, I'm Circular!}
+\stopbuffer
+
+\startbuffer[d]
+\framed
+ [background=linear shade,frame=off]
+ {\bf \white Whow, this is Linear!}
+\stopbuffer
+
+A shade is a fill with a stepwise change in color. In \POSTSCRIPT\ (level 2), the
+way this color changes can be circular, linear, or according to a user defined
+function. Circular and linear shades look like this:
+
+\startlinecorrection[blank]
+\getbuffer[a,b,c]
+\stoplinecorrection
+
+\startlinecorrection[blank]
+\getbuffer[a,b,d]
+\stoplinecorrection
+
+As you can see, the shade lays behind the text, as a background overlay. These
+overlays are unique \METAPOST\ graphics, so they will adapt themselves to the
+dimensions of the foreground.
+
+\typebuffer[b]
+
+The two framed texts are defined as:
+
+\typebuffer[c]
+
+and:
+
+\typebuffer[d]
+
+We still have to define the graphics. Here we use a macro that takes four
+arguments: a path, a number identifying the center of shading, and the colors to
+start and end with.
+
+\typebuffer[a]
+
+The \METAPOST\ macros, \type {circular_shade} and \type {linear_shade}, add
+information to the \METAPOST\ output file, which is interpreted by the converter
+built in \CONTEXT. Shading comes down to interpolation between two or more points
+or user supplied ranges. A poor mans way of doing this, is to build the graphics
+piecewise with slightly changing colors. But, instead of \quote {manually}
+stepping through the color values, we can use the more efficient and generalized
+\POSTSCRIPT\ level~2 and \PDF\ level~1.3 shading feature.
+
+\def\SomeShade#1#2#3% waarom unique ?
+ {\startuniqueMPgraphic{shade-#1}
+ width := \overlaywidth ;
+ height := \overlayheight ;
+ path p ; p := unitsquare xscaled width yscaled height ;
+ #2_shade(p,#3,\MPcolor{a},\MPcolor{b}) ;
+ \stopuniqueMPgraphic
+ \defineoverlay[shade-#1][\uniqueMPgraphic{shade-#1}]%
+ \framed[background=shade-#1,width=2cm,height=2cm,frame=off]{}}
+
+\startlinecorrection[blank]
+\startcombination[5*1]
+ {\SomeShade{20}{circular}{0}} {circular 0}
+ {\SomeShade{21}{circular}{1}} {circular 1}
+ {\SomeShade{22}{circular}{2}} {circular 2}
+ {\SomeShade{23}{circular}{3}} {circular 3}
+ {\SomeShade{24}{circular}{4}} {circular 4}
+\stopcombination
+\stoplinecorrection
+
+\startlinecorrection[blank]
+\startcombination[4*2]
+ {\SomeShade{32}{linear}{1}} {linear 1}
+ {\SomeShade{32}{linear}{2}} {linear 2}
+ {\SomeShade{33}{linear}{3}} {linear 3}
+ {\SomeShade{34}{linear}{4}} {linear 4}
+ {\SomeShade{35}{linear}{5}} {linear 5}
+ {\SomeShade{36}{linear}{6}} {linear 6}
+ {\SomeShade{37}{linear}{7}} {linear 7}
+ {\SomeShade{38}{linear}{8}} {linear 8}
+\stopcombination
+\stoplinecorrection
+
+% % This limitation si no longer present in mpiv.
+%
+% Shading is not a \METAPOST\ feature, which means that it has to be implemented
+% using so called specials, directives that end up in the output file.
+% Unfortunately these are not coupled to the specific path, which means that we
+% have to do a significant amount of internal bookkeeping. Also, in \PDF\ we have
+% to make sure that the graphics and their resources (being the shading functions)
+% are packaged together.
+%
+% Because of this implementation, shading may behave somewhat unexpected at times.
+% A rather normal case is the next one, where we place 5~shaded circles in a row.
+%
+% \startbuffer
+% path p ; p := fullcircle scaled 1cm ;
+% for i=0 step 2cm until 8cm :
+% circular_shade(p shifted (i,0),0,\MPcolor{a},\MPcolor{b}) ;
+% endfor ;
+% \stopbuffer
+%
+% \typebuffer
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% At first sight, in the next situation, we would expect something similar, because
+% we simply copy the same circle 5~times. However, due to the way we have
+% implemented shading in \CONTEXT, we do indeed copy the circles, but the shade
+% definition is frozen and the same one is used for all 5~circles. This means that
+% the center of the shading stays at the first circle.
+%
+% \startbuffer
+% circular_shade(fullcircle scaled 1cm,0,\MPcolor{a},\MPcolor{b}) ;
+% picture s ; s := currentpicture ; currentpicture := nullpicture ;
+% for i=0 step 2cm until 8cm :
+% addto currentpicture also s shifted (i,0) ;
+% endfor ;
+% \stopbuffer
+%
+% \typebuffer
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% Unlike \TEX, \METAPOST\ does not keep its specials attached to the current path,
+% and flushes them before the graphic data. Since we use these specials to register
+% shading information, it is rather hard to tightly connect a specific shade with a
+% certain fill, especially if an already performed fill is not accessible, which is
+% the case when we copy a picture.
+%
+% This may seem a disadvantage, but fortunately it also has its positive side. In
+% the next example we don't copy, but reuse an already defined shade. By storing
+% the reference to this shade, and referring to it by using \type {withshade}, we
+% can use a shade that operates on multiple shapes.
+
+\startbuffer
+sh := define_circular_shade
+ (origin,origin,0,8cm,\MPcolor{a},\MPcolor{b}) ;
+for i=0 step 2cm until 8cm :
+ fill fullcircle scaled 1cm shifted (i,0) withshade sh ;
+endfor ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The low level macro \type {define_circular_shade} is fed with two pairs (points),
+two radius, and two colors. The shade is distributed between the colors according
+to the radius.
+
+Shading can hardly be called an easy issue. The macros that we provide here are
+in fact simplifications, which means that at a lower level, one can do more
+advanced things. Here we limit ourselves to the more common cases. In the
+previous examples, we used an arrow to indicate the direction and magnitude of
+the shade. The next macro demonstrates the principles in a different way.
+
+\startbuffer[a]
+def test_shade (expr a, b, ra, rb) =
+ pickup pencircle scaled 1mm ;
+
+ color ca ; ca := \MPcolor{a} ;
+ color cb ; cb := \MPcolor{b} ;
+ color cc ; cc := \MPcolor{c} ;
+
+ path pa ; pa := fullcircle scaled 2ra shifted a ;
+ path pb ; pb := fullcircle scaled 2rb shifted b ;
+
+ sh := define_circular_shade(a,b,ra,rb,ca,cb) ;
+
+ fill pb withshade sh ;
+ draw pb withcolor cc ;
+ draw pa withcolor cc ;
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+The shade is distributed between two circles, each with a radius and center
+point. All four can be set, but as the next calls demonstrate, we can normally do
+with less, which is why we provided the macro with less parameters.
+
+\startbuffer[b]
+test_shade(origin, origin, 0cm, 1cm) ;
+\stopbuffer
+\startbuffer[c]
+test_shade(origin, origin, .25cm, 1cm) ;
+\stopbuffer
+\startbuffer[d]
+test_shade(origin, origin, .50cm, 1cm) ;
+\stopbuffer
+
+\startbuffer[f]
+\startlinecorrection[blank]
+\hbox
+ {\processMPbuffer[a,b]\quad
+ \processMPbuffer[a,c]\quad
+ \processMPbuffer[a,d]}
+\stoplinecorrection
+\stopbuffer
+
+\typebuffer[b,c,d] \getbuffer[f]
+
+\startbuffer[b]
+test_shade(origin, origin shifted (.25cm,0), 0cm, 1cm) ;
+\stopbuffer
+\startbuffer[c]
+test_shade(origin, origin shifted (.25cm,0), .25cm, 1cm) ;
+\stopbuffer
+\startbuffer[d]
+test_shade(origin, origin shifted (.25cm,0), .50cm, 1cm) ;
+\stopbuffer
+
+\typebuffer[b,c,d] \getbuffer[f]
+
+\startbuffer[b]
+test_shade(origin shifted (.25cm,0), origin, 0cm, 1cm) ;
+\stopbuffer
+\startbuffer[c]
+test_shade(origin shifted (.25cm,0), origin, .25cm, 1cm) ;
+\stopbuffer
+\startbuffer[d]
+test_shade(origin shifted (.25cm,0), origin, .50cm, 1cm) ;
+\stopbuffer
+
+\typebuffer[b,c,d] \getbuffer[f]
+
+\startbuffer[a]
+def test_shade (expr a, b) =
+ pickup pencircle scaled 1mm ;
+
+ color ca ; ca := \MPcolor{a} ;
+ color cb ; cb := \MPcolor{b} ;
+ color cc ; cc := \MPcolor{c} ;
+
+ sh := define_linear_shade(a,b,ca,cb) ;
+
+ fill fullsquare scaled 2cm withshade sh ;
+ draw a withcolor cc ;
+ draw b withcolor cc ;
+enddef ;
+\stopbuffer
+
+In a similar fashion, we can define a linear shade. This time we only pass two
+points and two colors.
+
+\typebuffer[a]
+
+Although one can control shading to a large extend, in practice only a few cases
+really make sense.
+
+\startbuffer[b]
+test_shade(origin, origin shifted (1cm,0)) ;
+\stopbuffer
+\startbuffer[c]
+test_shade(origin shifted (-1cm,0), origin shifted (1cm,0)) ;
+\stopbuffer
+\startbuffer[d]
+test_shade(origin shifted (-1cm,-1cm), origin shifted (1cm,1cm)) ;
+\stopbuffer
+
+\startbuffer[f]
+\startlinecorrection[blank]
+\hbox
+ {\processMPbuffer[a,b]\quad
+ \processMPbuffer[a,c]\quad
+ \processMPbuffer[a,d]}
+\stoplinecorrection
+\stopbuffer
+
+\typebuffer[b,c,d] \getbuffer[f]
+
+\stopsubsection
+
+\startsubsection[title=The new method]
+
+By now the shader macros are rather advanced and specifications are easier than
+before. Here we discuss the new method. An example is:
+
+\startbuffer
+fill fullsquare xyscaled (TextWidth,1cm)
+ withshademethod "linear"
+ withshadevector (1,0)
+ withshadecolors (darkred,darkgreen)
+;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+There are several properties that can be set:
+
+\starttabulate[|l|p|]
+\NC domain \NC The range over which the colors run, with a minimum of 0 and maximum of 1. \NC \NR
+\NC color \NC A color to start from and one to end with, we default from black to white. \NC \NR
+\NC type \NC The shading can be linear or circular. \NC \NR
+\NC center \NC The origin of the shade vector. \NC \NR
+\NC radius \NC The radius vector of a circular shade. \NC \NR
+\NC vector \NC Where we start and end the shading. \NC \NR
+\stoptabulate
+
+For a linear shade the centers are the lower left and upper right corners, for a
+circular shade it's the center of the path. For a circular shade the radius runs
+from zero to the maximum distance from the center as determined by the
+boundingbox.
+
+The vector is used as follows: the first coordinate (xpart) determines the point
+on the path where we start, the second coordinate (ypart) the point on the
+path where we end.
+
+\startbuffer[a]
+fill fullsquare xyscaled (TextWidth,1cm)
+ withshademethod "linear"
+ withshadevector (1,0)
+ withshadecolors (darkred,darkgreen)
+;
+\stopbuffer
+
+\startbuffer[b]
+draw fullsquare xyscaled (TextWidth,1cm)
+ shownshadevector (1,0)
+ withpen pencircle scaled 2
+ withcolor .5white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer[a,b]
+\stoplinecorrection
+
+In the end only the x coordinate matters, but using a point on the path sort of
+fits in \METAPOST. In the case of a rectangle we have 4 points while circle has 8
+points.
+
+\startbuffer[a]
+fill fullcircle xyscaled (TextWidth,1cm)
+ withshademethod "linear"
+ withshadevector (2,4)
+ withshadecolors (darkred,darkgreen)
+;
+\stopbuffer
+
+\startbuffer[b]
+draw fullcircle xyscaled (TextWidth,1cm)
+ shownshadevector (2,4)
+ withpen pencircle scaled 2
+ withcolor .5white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer[a,b]
+\stoplinecorrection
+
+A triangle has three points. Using 1 and 2 as second vector value gives the same
+results as do values in the range 0 upto 1 and 2 upto 3 (0 again).
+
+\startbuffer[a]
+fill fulltriangle xyscaled (TextWidth,1cm)
+ withshademethod "linear"
+ withshadevector (0.25,0.75)
+ withshadecolors (darkred,darkgreen)
+;
+\stopbuffer
+
+\startbuffer[b]
+draw fulltriangle xyscaled (TextWidth,1cm)
+ shownshadevector (0.25,0.75)
+ withpen pencircle scaled 2
+ withcolor .5white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer[a,b]
+\stoplinecorrection
+
+The shadevector relates to (the x coordinates of) points on the path. A variant is
+to use the boundingbox:
+
+\startbuffer[a]
+for i=1 upto 3 :
+ fill fulltriangle xyscaled (TextWidth,1cm)
+ shifted (0,-i*15mm)
+ withshademethod "linear"
+ withshadedirection (1,1-i/4)
+ withshadecolors (darkgreen,darkblue)
+ ;
+endfor ;
+\stopbuffer
+
+\startbuffer[b]
+for i=1 upto 3 :
+ draw fulltriangle xyscaled (TextWidth,1cm)
+ shifted (0,-i*15mm)
+ shownshadevector (1,1-i/4)
+ withpen pencircle scaled 2
+ withcolor .5white ;
+endfor ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startlinecorrection[blank]
+ \processMPbuffer[a,b]
+\stoplinecorrection
+
+So, where a vector is defined as going from {\em point xpart a of pth} to
+{\em point ypart a of pth}, a direction goes from {\em point xpart a of
+boundingbox pth} to {\em point ypart a of boundingbox pth}.
+
+To make life convenient we provide a few constants that indicate directions:
+
+\starttyping
+pair shadedup ; shadedup := (0.5,2.5) ;
+pair shadeddown ; shadeddown := (2.5,0.5) ;
+pair shadedleft ; shadedleft := (1.5,3.5) ;
+pair shadedright ; shadedright := (3.5,1.5) ;
+\stoptyping
+
+\startbuffer[a]
+for d = shadedup, shadeddown, shadedleft, shadedright :
+ fill fullsquare xyscaled (TextWidth,1cm)
+ withshademethod "linear"
+ withshadedirection d
+ withshadecolors (darkgreen,darkblue)
+ ;
+ currentpicture := currentpicture shifted (0,15mm) ;
+endfor ;
+\stopbuffer
+
+\startbuffer[b]
+currentpicture := currentpicture shifted (0,-60mm) ;
+for d = shadedup, shadeddown, shadedleft, shadedright :
+ draw fullsquare xyscaled (TextWidth,1cm)
+ shownshadedirection d
+ withpen pencircle scaled 2
+ withcolor .5white ;
+ currentpicture := currentpicture shifted (0,15mm) ;
+endfor ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startlinecorrection[blank]
+ \processMPbuffer[a,b]
+\stoplinecorrection
+
+In case of a circular shade another method comes in handy:
+
+\startbuffer[a]
+fill fullcircle xyscaled (TextWidth,4cm)
+ withshademethod "circular"
+ withshadecenter (.7,.9)
+ withshadecolors (darkblue,darkyellow)
+;
+\stopbuffer
+
+\startbuffer[b]
+draw fullcircle xyscaled (TextWidth,4cm)
+ shownshadecenter (.7,.9)
+ withpen pencircle scaled 2
+ withcolor .5white ;
+\stopbuffer
+
+\typebuffer
+
+Here the values relate to the center of path i.e.\ they shift the center by the
+given fraction of the width and height of the boundingbox devided by 2.
+
+\startlinecorrection[blank]
+ \processMPbuffer[a,b]
+\stoplinecorrection
+
+You can set a center directly i.e.\ unrelated to the center of the path as
+follows:
+
+\startbuffer[a]
+fill fullcircle xyscaled (TextWidth,4cm)
+ withshademethod "circular"
+ withshadeorigin (-30mm,-15mm)
+ withshadecolors (darkblue,darkyellow)
+;
+\stopbuffer
+
+\startbuffer[b]
+draw fullcircle xyscaled (TextWidth,4cm)
+ shownshadeorigin (-30mm,-15mm)
+ withpen pencircle scaled 2
+ withcolor .5white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer[a,b]
+\stoplinecorrection
+
+In a similar way you can set an explicit radius:
+
+\startbuffer[a]
+fill fullcircle xyscaled (TextWidth,1cm)
+ withshademethod "circular"
+ withshaderadius (10mm,50mm)
+ withshadecolors (darkblue,darkyellow)
+;
+currentpicture := currentpicture shifted (0,15mm) ;
+fill fullcircle xyscaled (TextWidth,1cm)
+ withshademethod "circular"
+ withshaderadius (50mm,10mm)
+ withshadecolors (darkgreen,darkred)
+;
+currentpicture := currentpicture shifted (0,15mm) ;
+fill fullcircle xyscaled (TextWidth,1cm)
+ withshademethod "circular"
+ withshaderadius (TextWidth/3,0mm)
+ withshadecolors (darkmagenta,darkcyan)
+;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer[a]
+\stoplinecorrection
+
+A more fancy feature is combined shades. This works as follows:
+
+\startbuffer[a]
+fill fullsquare xyscaled (TextWidth,1cm)
+ withshademethod "linear"
+ withshadevector (0,1)
+ withshadestep (
+ withshadefraction .3
+ withshadecolors (red,green)
+ )
+ withshadestep (
+ withshadefraction .5
+ withshadecolors (green,blue)
+ )
+ withshadestep (
+ withshadefraction .7
+ withshadecolors (blue,red)
+ )
+ withshadestep (
+ withshadefraction 1
+ withshadecolors (red,yellow)
+ )
+;
+\stopbuffer
+
+\typebuffer[a]
+
+By stepwise defining the colored bands you get:
+
+\startlinecorrection[blank]
+ \processMPbuffer[a]
+\stoplinecorrection
+
+Shades work well with colors and transparencies. This involves quite some
+resource managament in the backend but it's hidden by the interface.
+
+\startbuffer[a]
+fill fullsquare scaled 5cm
+ withshademethod "linear"
+ withshadefactor 1
+ withshadedomain (0,1)
+ withshadevector (0.5,2.75)
+ withshadecolors (red,green) ;
+
+fill fullcircle scaled 5cm
+ withshademethod "circular"
+ withshadefactor 1
+ withshadedomain (0,1)
+ withshadecenter (.25,.25)
+ withshadecolors (green,blue) ;
+
+fill fulltriangle scaled 5cm
+ withshademethod "circular"
+ withshadefactor 1
+ withshadedomain (0,1)
+ withshadecenter (.25,.25)
+ withshadecolors (blue,yellow) ;
+\stopbuffer
+
+\startbuffer[b]
+fill fullsquare scaled 5cm
+ withcolor white ;
+fill fullsquare scaled 5cm
+ withshademethod "linear"
+ withshadevector (0.5,2.75)
+ withshadecolors (red,green)
+ withtransparency (1,.5) ;
+
+fill fullcircle scaled 5cm
+ withcolor white ;
+fill fullcircle scaled 5cm
+ withshademethod "circular"
+ withshadecenter (.25,.25)
+ withshadecolors (green,blue)
+ withtransparency (1,.5) ;
+
+fill fulltriangle scaled 5cm
+ withcolor white ;
+fill fulltriangle scaled 5cm
+ withshademethod "circular"
+ withshadecenter (.25,.25)
+ withcolor blue shadedinto yellow
+ withtransparency (1,.5) ;
+\stopbuffer
+
+\startbuffer[c]
+fill fullsquare scaled 5cm
+ withshademethod "linear"
+ withshadevector (0.5,2.75)
+ withshadecolors (red,green)
+ withtransparency (1,.5) ;
+
+fill fullcircle scaled 5cm
+ withshademethod "circular"
+ withshadecenter (.25,.25)
+ withcolor green shadedinto blue
+ withtransparency (1,.5) ;
+
+fill fulltriangle scaled 5cm
+ withshademethod "circular"
+ withshadecenter (.25,.25)
+ withcolor blue shadedinto yellow
+ withtransparency (1,.5) ;
+\stopbuffer
+
+Here are some shades without transparency:
+
+\typebuffer[a]
+
+When the background is white, transparency is just a way to achieve soft colors.
+We leave out the defaults.
+
+\typebuffer[b]
+
+Real transparency will show op darker due to the accumulated colors. This time we
+demonstrate an alternative color specification.
+
+\typebuffer[c]
+
+\startplacefigure[reference=shades:transparency,title={Transparency applied to shades.}]
+ \startcombination[3*1]
+ {\processMPbuffer[a]} {no transparency}
+ {\processMPbuffer[b]} {transparency on white}
+ {\processMPbuffer[c]} {real transparency}
+ \stopcombination
+\stopplacefigure
+
+Within reasonable bounds you can move around and adapt shaded paths but you need
+to keep in mind that due to the fact that we are dealing with relatively complex
+data structures there are some limits. For instance it is possible to define a
+shade as (kind of) variable and reuse it. it's also possible then to overload
+some properties.
+
+% % still supported but not advertized:
+%
+% numeric n ; n = define_linear_shade (center fullcircle,center fullsquare,red,green) ;
+%
+% fill fullcircle randomized 1cm xyscaled(10cm,8cm) withshade n ;
+
+\startbuffer
+defineshade myshade
+ withshademethod "circular"
+ withshadefactor 1
+ withshadedomain (0,1)
+ withshadecolors (black,white)
+ withtransparency (1,.5)
+;
+
+for i=1 upto 5 :
+ fill fullcircle randomized 1 xyscaled(5cm,3cm)
+ shaded myshade ;
+endfor ;
+
+draw image (
+ for i=1 upto 5 :
+ fill fullcircle randomized 1
+ shaded myshade
+ withshadecolors (yellow,blue) ;
+ endfor ;
+) xyscaled(5cm,3cm) shifted (5cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+We get two groups of five overlayed shades here, one with a different color. The
+shade properties can only be applied to paths (see \in {figure}
+[fig:shades:defined]).
+
+\startplacefigure[reference=fig:shades:defined,title={Reusing defined shaded.}]
+ \processMPbuffer
+\stopplacefigure
+
+In older versions one could not reposition or scale a shaded path without losing
+or crippling the shade properties. Nowadays this is no longer a limitation, as we
+demonstrate in the following examples. You can disable this feature if wanted.
+The results are shown in \in {figure} [fig:shades:transform]. Without the
+transform the vectors and such are kept which might be useful in special cases.
+
+\startbuffer[a]
+fill fullsquare xyscaled (15mm, 15mm)
+ withshademethod "linear"
+ withshadedirection shadedright
+ withshadecolors (red,(1,1,1)) ;
+
+fill fullsquare xyscaled (10mm, 10mm)
+ withshademethod "circular"
+ withshadecolors (green,blue) ;
+
+currentpicture := currentpicture xysized (.4TextWidth,30mm) ;
+currentpicture := currentpicture shifted (5mm,5mm) ;
+\stopbuffer
+
+\typebuffer[a]
+
+The transform can be ignored with:
+
+\startbuffer[b]
+fill fullsquare xyscaled (15mm, 15mm)
+ withshademethod "linear"
+ withshadetransform "no"
+ withshadedirection shadedright
+ withshadecolors (red,(1,1,1)) ;
+
+fill fullsquare xyscaled (10mm, 10mm)
+ withshademethod "circular"
+ withshadetransform "no"
+ withshadecolors (green,blue) ;
+
+currentpicture := currentpicture xysized (.4TextWidth,30mm) ;
+currentpicture := currentpicture shifted (5mm,5mm) ;
+\stopbuffer
+
+\typebuffer[b]
+
+\startplacefigure[reference=fig:shades:transform,title={Shifting and scaling shades.}]
+ \startcombination
+ {\processMPbuffer[a]} {with transform}
+ {\processMPbuffer[b]} {without transform}
+ \stopcombination
+\stopplacefigure
+
+\stopsubsection
+
+\stopsection
+
+\startsection[title={Clipping}]
+
+\index{clipping}
+
+In this section we will use the graphic representation (although simplified) of a
+Dutch cow to demonstrate clipping.
+
+\startbuffer
+\placefigure
+ {A cow.}
+ {\externalfigure[cow-fun.mps][width=4cm]}
+\stopbuffer
+
+\getbuffer
+
+Since this cow is defined as a \METAPOST\ graphic, we use the suffix \type {mps}
+instead of \type {eps} or a number, although \CONTEXT\ will recognize each as
+being \METAPOST\ output. The placement of the cow is defined as:
+
+\typebuffer
+
+Clipping is combined with a matrix, as in \in {figure} [fig:clipped cow 1]. The
+content to be clipped is divided in \type {nx} by \type {ny} rectangles. For
+instance, \type {nx=5} and \type {ny=8} will produce a 40~cell grid with
+5~columns of 8~rows.
+
+\startbuffer
+\startbuffer
+\setupclipping[nx=3,ny=2]
+\startcombination
+ {\clip[x=1,y=1]{\externalfigure[cow-fun.mps][width=4cm]}} {1,1}
+ {\clip[x=3,y=1]{\externalfigure[cow-fun.mps][width=4cm]}} {3,1}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:clipped cow 1]
+ {A clipped cow.}{\getbuffer}
+\stopbuffer
+
+\getbuffer
+
+Here we have divided the cow in six cells, so that we can clip its head and tail.
+This kind of clipping enables you to zoom in or focus on a specific part of a
+graphic.
+
+\typebuffer
+
+Alternatively, we can specify a \type {width}, \type {height}, \type {hoffset}
+and \type {voffset}, as demonstrated in \in {figure} [fig:clipped cow 2].
+
+\startbuffer
+\placefigure
+ [here][fig:clipped cow 2]
+ {Another clipped cow.}
+ {\clip
+ [width=2cm,height=2cm,hoffset=0cm,voffset=0cm]
+ {\externalfigure[cow-fun.mps][width=4cm]}}
+\stopbuffer
+
+\getbuffer
+
+\typebuffer
+
+Because \METAPOST\ supports clipping, it will be no surprise that both techniques
+can be combined. In the next example we will zoom in on the head of the cow. We
+also use this opportunity to demonstrate how you can package a clip in a figure
+definition.
+
+\startbuffer
+\startMPclip{head clip}
+ w := \width ; h := \height ;
+ clip currentpicture to
+ ((0,h)--(w,h){down}..{left}(0,0)--cycle) ;
+\stopMPclip
+
+\placefigure
+ [here][fig:circular clipped cowhead]
+ {A quarter circle applied to a cows head.}
+ {\ruledhbox
+ {\clip
+ [nx=2,ny=2,x=1,y=1,mp=head clip]
+ {\externalfigure[cow-fun.mps][width=4cm]}}}
+\stopbuffer
+
+\typebuffer
+
+A more advanced clip is demonstrated in \in {figure} [fig:circular clipped
+cowhead]. We added \type {\ruledhbox} to demonstrate the dimensions of the
+resulting graphic. Putting something in such a ruled box is often a quick way to
+test spacing.
+
+\getbuffer
+
+Although a clip path definition can contain any \METAPOST\ command, even
+graphics, it must contain at least one clipping path. The first one encountered
+in the resulting graphic is used. In the example we used a path that is built out
+of three subpaths.
+
+\starttyping
+(0,h)--(w,h){down}..{left}(0,0)--cycle
+\stoptyping
+
+We start in the top left corner and draw a straight line. Next we draw a curve to
+the origin. Directives like \type {down} and \type {right} force the curve in a
+certain direction. With \type {cycle} we close the path. Because we use this path
+as a clipping path, we use \type {clip} instead of \type {draw} or \type {fill}.
+
+\startbuffer
+w := 4cm ; h := 2cm ;
+draw (0,h)--(w,h){down}..{left}(0,0)--cycle
+ withpen pencircle scaled 1mm withcolor .625red ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Clipping as such is not limited to graphics. Take for instance the text buffer:
+
+\startbuffer
+\startbuffer[sample]
+\framed
+ [align=middle,width=4cm,background=screen,frame=off]
+ {A \METAPOST\ clip is not the same as a video clip,
+ although we can use \METAPOST\ to produce a video clip.}
+\stopbuffer
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+We can call up such a buffer as if it were an external figure. \in {Figure}
+[fig:clipped text 1] shows the result. This time we use a different clip path:
+
+\startbuffer[a]
+\startMPclip{text clip}
+ clip currentpicture to fullcircle shifted (.5,.5)
+ xscaled \width yscaled \height ;
+\stopMPclip
+\stopbuffer
+
+\typebuffer[a]
+
+To load a buffer, we have to specify its name and type, as in:
+
+\startbuffer[b]
+\placefigure
+ [here][fig:clipped text 1]
+ {A clipped buffer (text).}
+ {\clip
+ [nx=1,ny=1,mp=text clip]
+ {\externalfigure[sample][type=buffer,width=4cm]}}
+\stopbuffer
+
+\typebuffer[b]
+
+\getbuffer[a,b]
+
+The next few lines demonstrate that we can combine techniques like backgrounds
+and clipping.
+
+\startbuffer
+\startuseMPgraphic{clip outline}
+ draw fullcircle
+ xscaled \overlaywidth yscaled \overlayheight
+ withpen pencircle scaled 4mm
+ withcolor .625red ;
+\stopuseMPgraphic
+
+\defineoverlay[clip outline][\useMPgraphic{clip outline}]
+
+\placefigure
+ [here][fig:clipped text 2]
+ {A clipped buffer (text).}
+ {\framed
+ [background=clip outline,offset=overlay,frame=off]
+ {\clip
+ [nx=1,ny=1,mp=text clip]
+ {\externalfigure[sample][type=buffer,width=4cm]}}}
+\stopbuffer
+
+\typebuffer
+
+We could have avoided the \type {\framed} here, by using the \typ{clip outline}
+overlay as a background of the sample. In that case, the resulting linewidth
+would have been 2.5~mm instead of 5~mm, since the clipping path goes through the
+center of the line.
+
+\getbuffer
+
+In most cases, the clip path will be a rather simple path and defining such a
+path every time you need it, can be annoying. \in {Figure} [fig:clipping paths]
+shows a collection of predefined clipping paths. These are available after
+loading the \METAPOST\ clipping library.
+
+\starttyping
+\useMPlibrary[clp]
+\stoptyping
+
+We already saw how the circular clipping path was defined. The diamond is defined
+in a similar way, using the predefined path \type {diamond}:
+
+\starttyping
+\startMPclip{diamond}
+ clip currentpicture to unitdiamond
+ xscaled \width yscaled \height ;
+\stopMPclip
+\stoptyping
+
+The definition of the negated ellipse (\type {negellipse}) uses the primary \type
+{peepholed}. This primary is defined in one of the \METAPOST\ modules that come
+with \CONTEXT.
+
+\starttyping
+\startMPclip{negellipse}
+ clip currentpicture to (unitcircle peepholed unitsquare)
+ xscaled \width yscaled \height ;
+\stopMPclip
+\stoptyping
+
+The definition of \type {peepholed} is rather dirty and using \type {peepholed}
+is restricted to well defined situations (like here). It's called a primary
+because it acts as an operator at the same level as \type {*} and \type {scaled}.
+
+\startbuffer
+\setupclipping [nx=1,ny=1,x=1,y=1]
+\setupblackrules[width=2cm,height=1cm]
+\startcombination[6*3]
+ {\clip[mp=urellipse] {\darkred\blackrule}} {urellipse}
+ {\clip[mp=ulellipse] {\darkred\blackrule}} {ulellipse}
+ {\clip[mp=llellipse] {\darkred\blackrule}} {llellipse}
+ {\clip[mp=lrellipse] {\darkred\blackrule}} {lrellipse}
+ {\clip[mp=ellipse] {\darkred\blackrule}} {ellipse}
+ {\clip[mp=negellipse]{\darkred\blackrule}} {negellipse}
+ {\clip[mp=tellipse] {\darkred\blackrule}} {tellipse}
+ {\clip[mp=bellipse] {\darkred\blackrule}} {bellipse}
+ {\clip[mp=lellipse] {\darkred\blackrule}} {lellipse}
+ {\clip[mp=rellipse] {\darkred\blackrule}} {rellipse}
+ {} {}
+ {} {}
+ {\clip[mp=urtriangle]{\darkred\blackrule}} {urtriangle}
+ {\clip[mp=ultriangle]{\darkred\blackrule}} {ultriangle}
+ {\clip[mp=lltriangle]{\darkred\blackrule}} {lltriangle}
+ {\clip[mp=lrtriangle]{\darkred\blackrule}} {lrtriangle}
+ {\clip[mp=diamond] {\darkred\blackrule}} {diamond}
+ {\clip[mp=negdiamond]{\darkred\blackrule}} {negdiamond}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:clipping paths]
+ {A collection of predefined clipping paths.}
+ {\getbuffer}
+
+\stopsection
+
+\startsection[title={Including graphics}]
+
+\index{graphics+including}
+
+This document demonstrates that it is no big problem to include \METAPOST\
+graphics in a \TEX\ document. But how about including graphics in a \METAPOST\
+picture? In this section we will explore a couple of macros that provide you this
+feature.
+
+Before we go into details, we introduce a very impressive program called
+\PSTOEDIT\ by Wolfgang Glunz. This program runs on top of \GHOSTSCRIPT\ and is
+able to convert \POSTSCRIPT\ code into other formats, among them \METAPOST\ (that
+part of the \PSTOEDIT\ code is due to Scott Pakin). Some of the graphics that we
+use in this section are produced that way. For us, the next call works well, but
+the exact call may differ per version or platform.
+
+\starttyping
+pstoedit -ssp -dt -f mpost yourfile.ps newfile.mp
+\stoptyping
+
+We have converted the Dutch cow that shows up in many \CONTEXT\ documents into
+\METAPOST\ using this program. The resulting \METAPOST\ file encapsulates the cow
+in \METAPOST\ figure~1: \type {beginfig(1)}. Of course you can process this file
+like any other, but more interesting is to use this code in an indirect way.
+
+\startbuffer
+loadfigure "mycow.mp" number 1 scaled .5 ;
+\stopbuffer
+
+\typebuffer
+
+This call will load figure~1 from the specified \METAPOST\ file, in such a way
+that there is no interference with the current (encapsulating) figure.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Because this graphic is the result from a conversion, there are only paths. If
+you want to import a more complex graphic, you need to make sure that the
+variables used in there do not conflict with the one currently in use.
+
+\METAPOST\ is good in drawing vector graphics, but lacks natural support for
+bitmaps, but the next macro offers a way out. This macro permits you to include
+graphics in \PNG, \PDF, and \JPG\ format, or more precise: those formats
+supported by \PDFTEX.\pagereference[hacker]
+
+\startbuffer
+draw externalfigure "hacker.png" scaled 5cm shifted (-6cm,0) ;
+draw externalfigure "hacker.png" scaled 5cm slanted .5 ;
+\stopbuffer
+
+\typebuffer
+
+You can apply the usual transformations, but only those applied directly will be
+taken into account. This means that you (currently) cannot store external figures
+in picture variables in order to transform them afterwards.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Although you are limited in what you can do with such graphics, you can include
+them multiple times with a minimum of overhead. Graphics are stored in objects
+and embedded only once.
+
+\startbuffer
+numeric s ; pair d, c ;
+for i := 1 upto 5 :
+ s := 3cm randomized 1cm ; % size of picture
+ c := .5(s,s) ; % center of picture
+ d := (2cm*i,.5cm) randomized .5cm ; % displacement
+ draw externalfigure "hacker.png"
+ scaled s rotatedaround (c,0 randomized 30) shifted d ;
+endfor ;
+\stopbuffer
+
+\typebuffer
+
+Because we cannot store the graphic in a picture and scale afterwards, we
+calculate the scale in advance, so that we can rotate around the center.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+As long as you don't mess around with a stored external figure, you're safe. The
+following example demonstrates how we can combine two special driven features:
+figure inclusion and shading.
+
+\startbuffer
+picture p ;
+p := externalfigure "hacker.png" scaled 150pt ;
+clip p to unitcircle scaled 150pt ;
+circular_shade(boundingbox p enlarged 10pt, 0, .2red, .9red) ;
+addto currentpicture also p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+We end this section with a few more words to \METAPOST\ inclusion. It may seem
+that in order to use the features discussed here, you need to use \CONTEXT\ as
+typesetting engine. This is not true. First of all, you can use the small \TEX\
+package \MPTOPDF\ (described in another manual) or you can make small \CONTEXT\
+files with one page graphics. The advantage of the last method is that you can
+manipulate graphics a bit.
+
+\starttyping
+\setupcolors[cmyk=yes,rgb=no,state=start]
+
+\starttext
+
+\startMPpage[offset=6pt]
+ loadfigure "niceone.mp" number 10 ;
+\stopMPpage
+
+\stoptext
+\stoptyping
+
+The resulting \PDF\ file can be included as any other graphic
+and has the advantage that it is self contained.
+
+\stopsection
+
+\startsection[reference=sec:conversion,title={Changing colors}]
+
+\index{color+manipulating}
+
+One of the advantages of \METAPOST\ graphics is that it is rather easy to force
+consistency in colors and line widths. You seldom can influence third party
+graphics that way, but we can use some \METAFUN\ trickery to get around this
+limitation.
+
+\startbuffer
+loadfigure "mycow.mp" number 1 scaled .35 ;
+refill currentpicture withcolor .625red ;
+\stopbuffer
+
+Say that we want a red cow instead of a black one. The following code does the
+trick:
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+In a similar way we can influence the width and colors of the lines.
+
+\startbuffer
+loadfigure "mycow.mp" number 1 scaled .35 ;
+refill currentpicture withcolor .625red ;
+redraw currentpicture withpen pencircle scaled 2pt withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Of course we can also use the more fancy features of \METAFUN, like transparency
+and shading.
+
+\startbuffer
+loadfigure "mycow.mp" number 1 scaled .35 ;
+numeric sh ; sh := define_linear_shade
+ (llcorner currentpicture,urcorner currentpicture,.625red, .625yellow) ;
+refill currentpicture withshade sh ;
+redraw currentpicture withpen pencircle scaled 2pt withcolor .5white;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Before we show a next trick, we draw a few circles.
+
+\startbuffer[a]
+fill fullcircle scaled 2cm withcolor yellow ;
+fill fullcircle scaled 2cm shifted (3cm,0) withcolor red ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+The yellow and red color do not match the main document colors, but this is no
+problem: we can remap them, without spoiling the original definition.
+
+\startbuffer[b]
+remapcolor(yellow,.625yellow) ;
+remapcolor(red ,.625red) ;
+recolor currentpicture ;
+resetcolormap ;
+\stopbuffer
+
+\typebuffer[a,b]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+We can combine the inclusion technique with remapping colors. This time using an
+artist impression of one of Hasselts Canals (gracht in Dutch)\pagereference
+[canal].
+
+\startbuffer[a]
+loadfigure "gracht.mp" number 1 scaled .5 ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+If you think that the sky is too bright in this picture, and given that you also
+know which color is used, you can fool the reader by remapping a few colors.
+
+\startbuffer[b]
+color skycolor ; skycolor := (0.8,0.90,1.0) ;
+color watercolor ; watercolor := (0.9,0.95,1.0) ;
+remapcolor(skycolor ,.8skycolor ) ;
+remapcolor(watercolor,.8watercolor) ;
+recolor currentpicture ;
+resetcolormap ;
+\stopbuffer
+
+\typebuffer[a,b]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+Including another \METAPOST\ graphic, refilling, redrawing, and recoloring are
+all relatively simple features that use no real tricks. Opposite to the next
+feature, which is implemented using the \METAPOST\ special driver that comes with
+\CONTEXT.
+
+\METAPOST\ is not really meant for manipulating graphics, but the previous
+examples demonstrated that we have some control over individual colors. In the
+next series of examples we will treat the picture as a whole. First we invert the
+colors using \type {inverted}.
+
+\startbuffer
+loadfigure "gracht.mp" number 1 scaled .5 ;
+addto currentpicture also
+ inverted currentpicture
+ shifted (bbwidth(currentpicture)+.5cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+This is a special case of \type {uncolored}. In the next example we explicitly
+specify the color.
+
+\startbuffer
+loadfigure "gracht.mp" number 1 scaled .5 ;
+addto currentpicture also
+ (currentpicture uncolored green)
+ shifted (bbwidth(currentpicture)+.5cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+You can also multiply each color using \type {softened}. In the next sample, the
+colors have 80\% of their value.
+
+\startbuffer
+loadfigure "gracht.mp" number 1 scaled .5 ;
+addto currentpicture also
+ (currentpicture softened .8)
+ shifted (bbwidth(currentpicture)+.5cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+You can also use this operator to harden colors, simply by
+providing a value larger than~1. Keep in mind that colors
+are clipped at~1 anyway.
+
+\startbuffer
+loadfigure "gracht.mp" number 1 scaled .5 ;
+addto currentpicture also
+ (currentpicture softened 1.2)
+ shifted (bbwidth(currentpicture)+.5cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+By providing a triplet, you can treat each color component
+independently.
+
+\startbuffer
+loadfigure "gracht.mp" number 1 scaled .5 ;
+addto currentpicture also
+ (currentpicture softened (.7,.8,.9))
+ shifted (bbwidth(currentpicture)+.5cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+After these examples your are probably sick of seeing this picture in color, so
+let's turn the colors into a weigthed grayscales (in a way similar to the way
+black and white television treated color).
+
+\startbuffer
+loadfigure "gracht.mp" number 1 scaled .5 ;
+addto currentpicture also
+ grayed currentpicture
+ shifted (bbwidth(currentpicture)+.5cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+\stopsection
+
+% \startsection[title={Outline fonts}]
+%
+% \index{text+outlines}
+% \index{outlines}
+%
+% Outline fonts don't belong to \METAPOST's repertoire of features. Nevertheless we
+% can simulate this in a reasonable way. We will not discuss all details here,
+% because most details are covered in the \MAKEMPY\ manual.
+%
+% The macro responsible for outline fonts is \type {graphictext}. The first
+% argument should be a string. This string is processed by \TEX. Additionally you
+% can provide transformation directives and color specifications. The next example
+% demonstrates this.
+%
+% \startbuffer
+% graphictext "\bf Fun" scaled 4 zscaled (1,1.5)
+% withdrawcolor blue
+% withfillcolor .5white
+% withpen pencircle scaled 5pt
+% \stopbuffer
+%
+% \typebuffer
+%
+% Once the text is typeset by \TEX, it is converted to \POSTSCRIPT\ and converted
+% into \METAPOST\ by the \PSTOEDIT\ program. The resulting graphic is imported,
+% analyzed, and processed conforming the specifications of \type {graphictext}.
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% By default the shapes are filled after they are drawn. This has the advantage
+% that in characters built out of pieces, disturbing lines fragments are covered.
+% The drawback is that you get only half the linewidth. You can reverse the drawing
+% order by adding the \type {reversefill} directive. The previous graphic then
+% comes out as:
+%
+% \startbuffer
+% graphictext "\bf Fun" scaled 4 zscaled (1,1.5)
+% reversefill
+% withdrawcolor blue
+% withfillcolor .5white
+% withpen pencircle scaled 5pt
+% \stopbuffer
+%
+% \typebuffer
+%
+% The \type {reversefill} directive can be countered by \type {outlinefill}.
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% The next example is taken from the \MAKEMPY\ manual. It demonstrates that you can
+% combine \TEX's powerful line breaking with \METAPOST's graphic capabilities.
+%
+% \startbuffer
+% \startuseMPgraphic{quotation}
+% picture one ; one := image ( graphictext
+% \MPstring{text}
+% scaled 1.5
+% withdrawcolor .625blue
+% withfillcolor .625white
+% withpen pencircle scaled 1pt ; ) ;
+% picture two ; two := image ( graphictext
+% \MPstring{author}
+% scaled 2
+% withdrawcolor .625red
+% withfillcolor .625white
+% withpen pencircle scaled 2pt ; ) ;
+% currentpicture := one ;
+% addto currentpicture also two
+% shifted lrcorner one
+% shifted - 1.125 lrcorner two
+% shifted (0, - 1.250 * ypart urcorner two) ;
+% setbounds currentpicture to boundingbox currentpicture enlarged 3pt ;
+% \stopuseMPgraphic
+% \stopbuffer
+%
+% \typebuffer \getbuffer
+%
+% In this graphic, we have two text fragments, the first one is a text, the second
+% one the name of the author. We combine the quotation and author into this graphic
+% using the following definitions:
+%
+% \startbuffer
+% \setMPtext{text} {\vbox{\hsize 8.5cm \input zapf }}
+% \setMPtext{author}{\hbox{\sl Hermann Zapf}}
+% \stopbuffer
+%
+% \typebuffer \getbuffer
+%
+% These definitions assume that the file \type {zapf.tex} is present on the system
+% (which is the case when you have installed \CONTEXT). The graphic can now be
+% typeset using the following call:
+%
+% \startbuffer
+% \placefigure
+% {A text does not need to be an outline in order to be
+% typeset in an outline font.}
+% {\useMPgraphic{quotation}}
+% \stopbuffer
+%
+% \typebuffer \getbuffer
+%
+% The quality of the output depends on how the glyphs are constructed. For
+% instance, in \TEX, math symbols are sometimes composed of glyph fragments and
+% rules.
+%
+% \startbuffer
+% graphictext
+% "$$\sqrt{1+x}$$"
+% scaled 8
+% withdrawcolor .625red
+% withpen pencircle scaled 1.5pt
+% \stopbuffer
+%
+% \typebuffer
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% This is not really a problem because we can also fill the shapes. It is the
+% reason why the fill is applied after the draw and in such case the effective line
+% width is half the size specified.
+%
+% \startbuffer
+% graphictext
+% "$$\left({{\sqrt{1+x}}\over{\sqrt{2+x^2}}}\right)$$"
+% scaled 4
+% dashed evenly
+% withdrawcolor .625red
+% withfillcolor .850white
+% withpen pencircle scaled 1.5pt
+% \stopbuffer
+%
+% \typebuffer
+%
+% In this example we also use a dashed line. Instead of normal colors, we could
+% have used shades or transparent colors.
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% Instead of supplying the text directly, you can use the indirect method. This
+% permits you to process rather complex data without messing up your \METAPOST\
+% code.
+%
+% \startbuffer
+% \setMPtext {some math}%
+% {\usemodule[mathml]
+% \xmlprocessdata
+% {main}
+% {<math xmlns='http://www.w3c.org/mathml' version='2.0'>
+% <apply> <log/>
+% <logbase> <cn> 2 </cn> </logbase>
+% <apply> <plus/>
+% <ci> x </ci>
+% <cn> 1 </cn>
+% </apply>
+% </apply>
+% </math>}
+% {}}
+% \stopbuffer
+%
+% \typebuffer \getbuffer
+%
+% Here we feed some \MATHML\ into \TEX, which in turn shows up as a \METAPOST\
+% graphic.
+%
+% \startbuffer
+% graphictext
+% \MPstring{some math}
+% scaled 4
+% withdrawcolor .625red
+% withfillcolor .625white
+% withpen pencircle scaled 1.5pt
+% \stopbuffer
+%
+% \typebuffer
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% \stopsection
+
+\startsection[title={Outline fonts}]
+
+\index{text+outlines}
+\index{outlines}
+
+Outline fonts don't belong to \METAPOST's repertoire of features. Nevertheless we
+can simulate this in a reasonable way. The current version of \METAFUN\ uses the
+outline subsystem of \CONTEXT\ \MKIV, but in earlier days we used an external
+process: a \PDF\ file is generated that has the snippet, that gets converted to
+\POSTSCRIPT, which in turn is converted to \METAPOST\ with \type {pstoedit} and
+from that result we filter the outlines. This method uses \type {graphictext} and
+is covered in the \MAKEMPY\ manual. Here we discuss the new method using \type
+{outlinetext}.
+
+\startbuffer
+draw outlinetext.b("\bf Funky")
+ (withcolor .5white)
+ (withcolor blue withpen pencircle scaled 1/5)
+ scaled 4 zscaled (1,0.5) ;
+\stopbuffer
+
+\typebuffer
+
+Once the text is typeset by \TEX, the result (a node list) is parsed and a
+\METAPOST\ representation is created. The glyphs are converted to outlines that
+are taken from the original font. For the moment this only works for \OPENTYPE\
+fonts.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\startbuffer[1]
+draw outlinetext ("\bf Funky")
+ scaled 3 ;
+\stopbuffer
+
+\startbuffer[2]
+draw outlinetext.d ("\bf Funky")
+ (withcolor red withpen pencircle scaled 1/5)
+ scaled 3 ;
+\stopbuffer
+
+\startbuffer[3]
+draw outlinetext.f ("\bf Funky")
+ (withcolor blue)
+ scaled 3 ;
+\stopbuffer
+
+\startbuffer[4]
+draw outlinetext.b ("\bf Funky")
+ (withcolor blue)
+ (withcolor red withpen pencircle scaled 1/5)
+ scaled 3 ;
+\stopbuffer
+
+\startbuffer[5]
+draw outlinetext.r ("\bf Funky")
+ (withcolor blue)
+ (withcolor red withpen pencircle scaled 1/5)
+ scaled 3 ;
+\stopbuffer
+
+\startplacetable[reference=tab:outlinetext,title={The four variants of \type {graphictext}.}]
+ \bTABLE[offset=1ex]
+ \dorecurse{5}{\bTR \bTD \processMPbuffer[#1] \eTD \bTD \typebuffer[#1] \eTD \eTR}
+ \eTABLE
+\stopplacetable
+
+The five variants of this command are shown in \in {table} [tab:outlinetext]: the
+suffix determines the number of arguments and rendering. The \type {r} suffix
+reverses the order: the fill comes over the draw. There is a \type {p} suffix
+that returns just the picture.
+
+The next example demonstrates that you can combine \TEX's powerful line breaking
+algorithm with \METAPOST's graphic capabilities.
+
+\startbuffer
+\startuseMPgraphic{quotation}
+ picture one ; one := image ( draw outlinetext.b
+ (\MPstring{text})
+ (withcolor .625white)
+ (withcolor .625blue withpen pencircle scaled 1/5)
+ scaled 1.5
+ ) ;
+ picture two ; two := image ( draw outlinetext.b
+ (\MPstring{author})
+ (withcolor .625white)
+ (withcolor .625red withpen pencircle scaled 1/5)
+ scaled 2
+ ) ;
+ currentpicture := one ;
+ addto currentpicture also two
+ shifted lrcorner one
+ shifted - 1.125 lrcorner two
+ shifted (0, - 2 * ypart urcorner two) ;
+ setbounds currentpicture to boundingbox currentpicture enlarged 3pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+In this graphic, we have two text fragments, the first one is a text, the second
+one the name of the author. We combine the quotation and author into this graphic
+using the following definitions:
+
+\startbuffer
+\setMPtext
+ {text}
+ {\vbox
+ {\setupalign[verytolerant,stretch]
+ \hsize 8.5cm
+ \input zapf }}
+\setMPtext
+ {author}
+ {\hbox
+ {\sl Hermann Zapf}}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+These definitions assume that the file \type {zapf.tex} is present on the system
+(which is the case when you have installed \CONTEXT). The graphic can now be
+typeset using the following call:
+
+\startbuffer
+\placefigure
+ [here]
+ [fig:zapf]
+ {A text does not need to be an outline in order to be
+ typeset in an outline font.}
+ {\useMPgraphic{quotation}}
+\stopbuffer
+
+\typebuffer
+
+The result is \in {figure} [fig:zapf]. The quality of the output depends on how
+the glyphs are constructed. For instance, in \TEX, math symbols are sometimes
+composed of glyph fragments and rules.
+
+\start
+ \def||{-}
+ \getbuffer
+\stop
+
+\startbuffer
+draw outlinetext.d
+ ("\mathematics{\sqrt{1+x}}")
+ (withcolor .625red withpen pencircle scaled 1/5)
+ scaled 8
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+This is not really a problem because we can also fill the shapes. It is the
+reason why the fill is applied after the draw and in such case the effective line
+width is half the size specified.
+
+\startbuffer
+draw outlinetext.b
+ ("\mathematics{\left({{\sqrt{1+x}}\over{\sqrt{2+x^2}}}\right)}")
+ (withcolor .850white)
+ (withcolor .625red
+ dashed evenly scaled .1
+ withpen pencircle scaled 1/5)
+ scaled 8
+\stopbuffer
+
+\typebuffer
+
+In this example (shown in \in {figure} [fig:dashedoutline]) we also use a dashed
+line.
+
+\placefigure
+ [here]
+ [fig:dashedoutline]
+ {A dashed outline text.}
+ {\processMPbuffer}
+
+Instead of supplying the text directly, you can use the indirect method. This
+permits you to process rather complex data without messing up your \METAPOST\
+code.
+
+\startbuffer
+\usemodule[mathml]
+
+\setMPtext {some math}%
+ {\xmlprocessdata
+ {main}
+ {<math xmlns='http://www.w3c.org/mathml' version='2.0'>
+ <apply> <log/>
+ <logbase> <cn> 2 </cn> </logbase>
+ <apply> <plus/>
+ <ci> x </ci>
+ <cn> 1 </cn>
+ </apply>
+ </apply>
+ </math>}
+ {}}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Here we feed some \MATHML\ into \TEX, which in turn shows up as a \METAPOST\
+graphic (\in {figure} [fig:mathml]).
+
+\startbuffer
+draw outlinetext.b
+ (\MPstring{some math})
+ (withcolor .625white)
+ (withcolor .625red withpen pencircle scaled 1/5)
+ scaled 8
+\stopbuffer
+
+\typebuffer
+
+\placefigure
+ [here]
+ [fig:mathml]
+ {A \MATHML\ snippet turned into outlines.}
+ {\processMPbuffer}
+
+Outlines are fun to look at. Here are a few ways to visualize a glyph:
+
+\startbuffer[1]
+\startcombination[3*1]
+ {\ruledhbox\bgroup
+ \showshape[character=(,alternative=text]%
+ \egroup} {}
+ {\ruledhbox\bgroup
+ \showshape[character=a,alternative=text]%
+ \egroup} {}
+ {\ruledhbox\bgroup
+ \showshape[character=x,alternative=text]%
+ \egroup} {}
+\stopcombination
+\stopbuffer
+
+\typebuffer[1]
+
+You can control the rendering a bit by setting \type {option}. Possible options
+are: \type {box}, \type {width}, \type {min}, \type {max} and \type {comment}.
+The \type {simple} option disables all. The simple results are shown in
+\in{figure} [fig:showshape].
+
+\startbuffer[2]
+\startcombination[3*1]
+ {\ruledhbox\bgroup
+ \showshape[character=(,alternative=text,option=simple]%
+ \egroup} {}
+ {\ruledhbox\bgroup
+ \showshape[character=a,alternative=text,option=simple]%
+ \egroup} {}
+ {\ruledhbox\bgroup
+ \showshape[character=x,alternative=text,option=simple]%
+ \egroup} {}
+\stopcombination
+\stopbuffer
+
+\typebuffer[2]
+
+\startplacefigure[reference=fig:showshape,title={Showing shapes.}]
+ \getbuffer[2]
+\stopplacefigure
+
+When you use this feature you need to be aware of the fact that fonts can have
+features, for instance ligatures and kerns between characters. In \in {figure}
+[fig:outlines:features] we see a few examples with and without features, one with
+Pagella (the Zapf quote) and one with Optima Nova (the Tufte quote).
+
+\startplacefigure[reference=fig:outlines:features,title={Pagela (\OPENTYPE) and Optima Nova (\TYPEONE)}]
+ \startcombination[1*4]
+ \bgroup
+ \def|#1|{-}%
+ \definedfont[texgyrepagella-regular.otf*none]%
+ \startMPcode
+ draw outlinetext.b
+ ("\framed[align=normal,width=max]{\input{zapf}}")
+ (withcolor .375white)
+ (withcolor .625red withpen pencircle scaled 1/10) ;
+ \stopMPcode
+ \egroup {pagella / no features}
+ \bgroup
+ \def|#1|{-}%
+ \definedfont[texgyrepagella-regular.otf*default]%
+ \startMPcode
+ draw outlinetext.b
+ ("\framed[align=normal,width=max]{\input{zapf}}")
+ (withcolor .375white)
+ (withcolor .625blue withpen pencircle scaled 1/10) ;
+ \stopMPcode
+ \egroup {pagella / default features}
+ \bgroup
+ \def|#1|{-}%
+ \definedfont[lt55476.afm*none]% optima nova
+ \startMPcode
+ draw outlinetext.b
+ ("\framed[align=normal,width=max]{\input{tufte}}")
+ (withcolor .375white)
+ (withcolor .625green withpen pencircle scaled 1/10) ;
+ \stopMPcode
+ \egroup {optima nova / no features}
+ \bgroup
+ \def|#1|{-}%
+ \definedfont[lt55476.afm*default]% optima nova
+ \startMPcode
+ draw outlinetext.b
+ ("\framed[align=normal,width=max]{\input{tufte}}")
+ (withcolor .375white)
+ (withcolor .625yellow withpen pencircle scaled 1/10) ;
+ \stopMPcode
+ \egroup {optima nova / default features}
+ \stopcombination
+\stopplacefigure
+
+Given that a shape has a path that is suitable for it, you can use special effects,
+like:
+
+\startbuffer
+ draw image (
+ draw outlinetext.d
+ ("Abracadabra")
+ (withpen pencircle scaled 1/10 dashed withdots scaled 1/20) ;
+ ) xsized TextWidth ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection
+ \processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=Transparency groups]
+
+The following feature is not that usefull but implemented anyway. The \PDF\ reference says:
+
+\startitemize
+ \startitem
+ A group may be isolated or non-isolated, which shall determine the
+ initial backdrop against which its stack is composited.
+ \stopitem
+ \startitem
+ A group may be knockout or non-knockout, which shall determine whether
+ the objects within its stack are composited with one another or only with
+ the group’s backdrop.
+ \stopitem
+\stopitemize
+
+and then carries on with a detailed explanation of groups. Here we stick to just
+mentioning how one can create a group in a picture. First we define a helper:
+
+\startbuffer
+\startMPdefinitions
+ def ShowGroup (expr clr) (text grouped) =
+ draw image (
+ drawarrow (10,0) -- (0,0)
+ withtransparency(1,.5)
+ withcolor clr ;
+ ) grouped ;
+ currentpicture := currentpicture xsized (TextWidth/8) ;
+ setbounds currentpicture to boundingbox currentpicture enlarged 2mm ;
+ addbackground withcolor .5white ;
+ enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+ \startcombination[5*1]
+ {\startMPcode ShowGroup(.5red) () \stopMPcode} {\tttf no group}
+ {\startMPcode ShowGroup(.5green) (asgroup "") \stopMPcode} {\tttf group}
+ {\startMPcode ShowGroup(.5blue) (asgroup "isolated") \stopMPcode} {\tttf isolated}
+ {\startMPcode ShowGroup(.5cyan) (asgroup "knockout") \stopMPcode} {\tttf knockout}
+ {\startMPcode ShowGroup(.5magenta)(asgroup "isolated,knockout") \stopMPcode} {\tttf isolated\crlf knockout}
+ \stopcombination
+\stoplinecorrection
+
+The syntax is:
+
+\starttyping
+draw somepicture|somepath grouped "[isolated|knockout] ;
+\stoptyping
+
+The group becomes an object and is no longer part of the stream of graphic
+operators but a reference. For what it's worth: I never needed this feature.
+
+\stopsection
+
+\startsection[title=Decorating]
+
+Although the \METAPOST\ language is quite powerful the number of data types is
+not that large and when it comes to drawing stuff there are only paths and
+pictures. A path is a list of points (with controlpoints) and a few properties,
+like the pen, linewidth, linecap, color and such. For a long time in \METAFUN\ we
+used so called specials to implement extensions (like shading). This was done by
+using special colors and associating these with entries in the special section at
+the top of the output.
+
+Nowadays we use the pre- and postscript properties of paths. The advantage is
+that we can add whatever we want, as long as the backend supports it and because
+the backend is written in \LUA\ there are no real limitations. So, instead of
+extending \METAPOST\ we extend the \METAFUN\ macros and backend.
+
+Most extensions use the prescripts. Think of this:
+
+\starttyping
+draw fullcircle
+ withprescript "do this"
+ withprescript "and that"
+ withprescript "and even more" ;
+\stoptyping
+
+Eventually this becomes a string:
+
+\starttyping
+and even more<newline>and that<newline>do this
+\stoptyping
+
+\typebuffer
+
+The prescripts get prepended, while the postscripts (that we use for text only)
+get appended. When we draw a picture with properties (like color) they get
+overwritten but not so (with good reason) for the pre- and postscripts: these
+just accumulate. We will now demonstrate how we can manipulate the picture
+(a bit).
+
+\startbuffer
+picture MyShape ; MyShape := image (
+ fill fullsquare xyscaled (4,1) withcolor .625red ;
+ fill fullsquare xyscaled (3,1) withcolor .625green ;
+ fill fullsquare xyscaled (2,1) withcolor .625blue ;
+ fill fullsquare xyscaled (1,1) withcolor .625yellow ;
+) xysized (TextWidth,1cm) ;
+
+draw MyShape;
+\stopbuffer
+
+\typebuffer
+
+We just draw the (natural) picture:
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+When we draw the picture with a new color, all its components get recolored:
+
+\startbuffer
+draw MyShape
+ withcolor .625magenta ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+However, when we add a transparency only the first component gets adapted because
+we use prescripts for this extension. (An extension using the postscripts would
+affect the last component.)
+
+\startbuffer
+draw MyShape
+ withcolor .625magenta
+ withtransparency (1,.5) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+The same logic applied to the \type {image}: prescripts get prepended to the
+first copmponent, postscripts to the last.
+
+\startbuffer
+draw image (draw MyShape)
+ withcolor .625cyan ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+\startbuffer
+draw image (draw MyShape)
+ withcolor .625cyan
+ withtransparency (1,.5) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+The \type {undecorated} macro ignores the properties. We can't reset the scripts as
+this could ruin the effects like shading.
+
+\startbuffer
+draw undecorated (draw MyShape)
+ withcolor .625white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+The \type {decorated} macro applies the properties to each component.
+
+\startbuffer
+draw decorated (draw MyShape)
+ withtransparency (1,.5) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+Here we kept the colors as they are but next we redo them:
+
+\startbuffer
+draw decorated (draw MyShape)
+ withcolor .625magenta
+ withtransparency (1,.5) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+The \type {redecorated} macro is the most intrusive as it resets the properties.
+This also means that you will loose texts, shades etc.
+
+\startbuffer
+draw redecorated (draw MyShape)
+ withtransparency (1,.5) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+Indeed we get no color (but black) but we can bring back some color:
+
+\startbuffer
+draw redecorated (draw MyShape)
+ withcolor .625yellow
+ withtransparency (1,.5) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=Properties]
+
+The (plain) \METAPOST\ macro \type {drawoptions} stored its arguments
+in a macro that gets expanded when something is drawn (or filled). So, when you say
+
+\starttyping
+drawoptions(withcolor red) ;
+draw somepath ;
+\stoptyping
+
+This effectively is:
+
+\starttyping
+draw somepath withcolor red ;
+\stoptyping
+
+A disadvantage is that there is not much control over where it gets applied,
+especially when you hide drawing operations in macros. It's the reason why
+personally I always prefer explicit options. If you want some abstraction
+you can use the properties feature:
+
+\startbuffer
+\startMPcode
+ property p[] ;
+ p1 = properties(withcolor "darkred") ;
+ p2 = properties(withcolor "darkblue") ;
+ p3 = properties(withcolor "darkgreen") ;
+ fill fullsquare xysized (TextWidth,12mm) withproperties p1 ;
+ fill fullsquare xysized (TextWidth, 8mm) withproperties p2 ;
+ fill fullsquare xysized (TextWidth, 4mm) withproperties p3 ;
+ fill fullsquare xysized (TextWidth, 2mm) withproperties p1 ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+We get:
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+Here we use an \quote {array} of properties but a single property is also possible:
+
+\startbuffer
+\startMPcode
+ property p ;
+ p = properties(withcolor "darkyellow") ;
+ fill fullsquare xysized (TextWidth,4mm) withproperties p ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+We get:
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-embedding.tex b/doc/context/sources/general/manuals/metafun/metafun-embedding.tex
new file mode 100644
index 000000000..10383fa3a
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-embedding.tex
@@ -0,0 +1,1208 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-embedding
+
+\environment metafun-environment
+
+\startchapter[reference=sec:embedding,title={Embedded graphics}]
+
+\startintro
+
+In addition to the \type {beginfig}||\type {endfig} method, there are other ways
+to define and include a \METAPOST\ graphic. Each method has its advantages and
+disadvantages.
+
+In the previous chapter we were still assuming that the graphic was defined in
+its own file. In this chapter we will introduce the interface between \CONTEXT\
+and \METAPOST\ and demonstrate how the definitions of the graphics can be
+embedded in the document source.
+
+\stopintro
+
+\startsection[title={Getting started}]
+
+\index{running}
+\index{processing}
+
+From now on, we will assume that you have \CONTEXT\ running on your platform.
+Since \PDF\ has full graphics support, we also assume that you use \LUATEX\ in
+combination with \CONTEXT\ \MKIV, although most will also work with other engines
+and \MKII. Since this document is not meant as a \CONTEXT\ tutorial, we will
+limit this introduction to the basics needed to run the examples.
+
+A simple document looks like:
+
+\starttyping
+\starttext
+ Some text.
+\stoptext
+\stoptyping
+
+You can process this document with the \LUA\ based command line interface to
+\CONTEXT. If the source code is embedded in the file \type {mytext.tex}, you can
+say:
+
+\starttyping
+context mytext
+\stoptyping
+
+We will use color, and in \MKIV\ color is enabled by default. If you don't want
+color you can tell \CONTEXT, so
+
+\starttyping
+\setupcolors[state=stop]
+\starttext
+ Some \color[blue]{text} and/or \color[green]{graphics}.
+\stoptext
+\stoptyping
+
+comes out in black and white.
+
+In later chapters we will occasionally see some more \CONTEXT\ commands show up.
+If you want to know more about what \CONTEXT\ can do for you, we recommend the
+beginners manual and the reference manual, as well as the wiki pages.
+
+\stopsection
+
+\startsection[title={External graphics}]
+
+\index {graphics+external}
+
+Since \TEX\ has no graphic capabilities built in, a graphic is referred to as an
+external figure. A \METAPOST\ graphic often has a number as suffix, so embedding
+such a graphic is done by:
+
+\starttyping
+\externalfigure[graphic.123][width=4cm]
+\stoptyping
+
+An alternative method is to separate the definition from the inclusion. An
+example of a definition is:
+
+\starttyping
+\useexternalfigure[pentastar][star.803][height=4cm]
+\useexternalfigure[octostar] [star.804][pentastar]
+\stoptyping
+
+Here, the second definition inherits the characteristics from the first one.
+These graphics can be summoned like:
+
+\starttyping
+\placefigure
+ {A five||point star drawn by \METAPOST.}
+ {\externalfigure[pentastar]}
+\stoptyping
+
+Here the stars are defined as stand||alone graphics, in a file called \type
+{star.mp}. Such a file can look like:
+
+\starttyping
+def star (expr size, n, pos) =
+ for a=0 step 360/n until round(360*(1-1/n)) :
+ draw (origin -- (size/2,0))
+ rotatedaround (origin,a) shifted pos ;
+ endfor ;
+enddef ;
+
+beginfig(803) ;
+ pickup pencircle scaled 2mm ; star(2cm,5,origin) ;
+endfig ;
+
+beginfig(804) ;
+ pickup pencircle scaled 1mm ; star(1cm,8,origin) ;
+ pickup pencircle scaled 2mm ; star(2cm,7,(3cm,0)) ;
+endfig ;
+
+end.
+\stoptyping
+
+This \type {star} macro will produce graphics like:
+
+\startbuffer
+def star (expr size, n, pos) =
+ for a=0 step 360/n until round(360*(1-1/n)) :
+ draw (origin -- (size/2,0))
+ rotatedaround (origin,a) shifted pos ;
+ endfor ;
+enddef ;
+
+for i=5 upto 10 :
+ drawoptions (withpen pencircle scaled 2mm withcolor .625red) ;
+ star(1cm,i,origin shifted (i*2cm,0)) ;
+endfor ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+But, now that we have instant \METAPOST\ available in \LUATEX, there is no need
+for external images and we can collect them in libraries, as we will see later
+on.
+
+\stopsection
+
+\startsection[title={Integrated graphics}]
+
+\index{graphics+embedded}
+
+An integrated graphic is defined in the document source or in a style definition
+file. The most primitive way of doing this is just inserting the code:
+
+\starttyping
+\startMPcode
+ fill fullcircle scaled 200pt withcolor .625white ;
+\stopMPcode
+\stoptyping
+
+Such a graphic is used once at the spot where it is defined. In this document we
+also generate graphics while we finish a page, so there is a good chance that
+when we have constructed a graphic which will be called on the next page, the
+wrong graphic is placed.
+
+For this reason there are are more convenient ways of defining and using
+graphics, which have the added advantage that you can predefine multiple
+graphics, thereby separating the definitions from the usage.
+
+The first alternative is a {\em usable} graphic. Such a graphic is calculated
+anew each time it is used. An example of a usable graphic is:
+
+\starttyping
+\startuseMPgraphic{name}
+ fill fullcircle scaled 200pt withcolor .625yellow ;
+\stopuseMPgraphic
+\stoptyping
+
+When you put this definition in the preamble of your document, you can place this
+graphic anywhere in the file, saying:
+
+\starttyping
+\useMPgraphic{name}
+\stoptyping
+
+As said, this graphic is calculated each time it is placed, which can be time
+consuming. Apart from the time aspect, this also means that the graphic itself is
+incorporated many times. Therefore, for graphics that don't change, \CONTEXT\
+provides {\em reusable} graphics:
+
+\starttyping
+\startreusableMPgraphic{name}
+ fill fullcircle scaled 200pt withcolor .625yellow;
+\stopreusableMPgraphic
+\stoptyping
+
+This definition is accompanied by:
+
+\starttyping
+\reuseMPgraphic{name}
+\stoptyping
+
+Imagine that we use a graphic as a background for a button. We can create a
+unique and reusable graphic by saying:
+
+\starttyping
+\def\MyGraphic
+ {\startreusableMPgraphic{name:\overlaywidth:\overlayheight}
+ path p ; p := unitsquare
+ xscaled OverlayWidth yscaled OverlayHeight ;
+ fill p withcolor .625yellow ;
+ draw p withcolor .625red ;
+ \stopreusableMPgraphic
+ \reuseMPgraphic{name:\overlaywidth:\overlayheight}}
+\stoptyping
+
+Notice the use of \type {OverlayWidth} and \type {OverlayHeight}. These variables
+are set for each call to \METAPOST. After this we can say:
+
+\starttyping
+\defineoverlay[my graphic][\MyGraphic]
+\button[background=my graphic,frame=off]{Go Home}[firstpage]
+\stoptyping
+
+Say that we have a 30pt by 20pt button, then the identifier will be \type
+{name:30pt:20pt}. Different dimensions will lead to other identifiers, so this
+sort of makes the graphics unique.
+
+We can bypass the ugly looking \type {\def} by using a third class of embedded
+graphics, the {\em unique} graphics.
+
+\starttyping
+\startuniqueMPgraphic{name}
+ path p ; p := unitsquare
+ xscaled OverlayWidth yscaled OverlayHeight ;
+ fill p withcolor .625yellow ;
+ draw p withcolor .625red ;
+\stopuniqueMPgraphic
+\stoptyping
+
+Now we can say:
+
+\starttyping
+\defineoverlay[my graphic][\uniqueMPgraphic{name}]
+\button[background=my graphic,frame=off]{Go Home}[firstpage]
+\stoptyping
+
+A shorter variant is:
+
+\starttyping
+\startuniqueMPgraphic{name}
+ fill OverlayBox withcolor .625yellow ;
+ draw OverlayBox withcolor .625red ;
+\stopuniqueMPgraphic
+\stoptyping
+
+You may wonder why unique graphics are needed when a single graphic might be used
+multiple times by scaling it to fit the situation. Since a unique graphic is
+calculated for each distinctive case, we can be sure that the current
+circumstances are taken into account. Also, scaling would result in incomparable
+graphics. Consider the following definition:
+
+\startbuffer[a]
+\startuseMPgraphic{demo}
+ draw unitsquare
+ xscaled 5cm yscaled 1cm
+ withpen pencircle scaled 2mm
+ withcolor .625red ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[a]
+
+Since we reuse the graphic, the dimensions are sort of fixed, and because the
+graphic is calculated once, scaling it will result in incompatible line widths.
+
+\startbuffer[b]
+\hbox \bgroup
+ \scale[width=5cm,height=1cm]{\useMPgraphic{demo}}\quad
+ \scale[width=8cm,height=1cm]{\useMPgraphic{demo}}%
+\egroup
+\stopbuffer
+
+\startlinecorrection[blank]
+\getbuffer[a,b]
+\stoplinecorrection
+
+These graphics were placed with:
+
+\typebuffer[b]
+
+Imagine what happens when we add some buttons to an interactive document without
+taking care of this side effect. All the frames would look different. Consider
+the following example.
+
+\startbuffer[a]
+\startuniqueMPgraphic{right or wrong}
+ pickup pencircle scaled .075 ;
+ fill unitsquare withcolor .8white ;
+ draw unitsquare withcolor .625red ;
+ currentpicture := currentpicture
+ xscaled OverlayWidth yscaled OverlayHeight ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\typebuffer[a]
+
+Let's define this graphic as a background to some buttons.
+
+\startbuffer[b]
+\defineoverlay[button][\uniqueMPgraphic{right or wrong}]
+\setupbuttons[background=button,frame=off]
+\stopbuffer
+
+\startbuffer[c]
+\hbox
+ {\button {previous} [previouspage]\quad
+ \button {next} [nextpage]\quad
+ \button {index} [index]\quad
+ \button {table of contents} [content]}
+\stopbuffer
+
+\typebuffer[b,c]
+
+The buttons will look like:
+
+\startlinecorrection[blank]
+\setupinteraction[state=start,color=,contrastcolor=]
+\getbuffer[a,b,c]
+\stoplinecorrection
+
+Compare these with:
+
+\startbuffer[a]
+\startuniqueMPgraphic{wrong or right}
+ pickup pencircle scaled 3pt ;
+ path p ; p := unitsquare
+ xscaled OverlayWidth yscaled OverlayHeight ;
+ fill p withcolor .8white ;
+ draw p withcolor .625red ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\startlinecorrection[blank]
+\getbuffer[a,b]
+\defineoverlay[button][\uniqueMPgraphic{wrong or right}]
+\setupinteraction[state=start,color=,contrastcolor=]
+\getbuffer[c]
+\stoplinecorrection
+
+Here the graphic was defined as:
+
+\typebuffer[a]
+
+The last class of embedded graphics are the {\em runtime} graphics. When a
+company logo is defined in a separate file \type {mylogos.mp}, you can run this
+file by saying:
+
+\starttyping
+\startMPrun
+ input mylogos ;
+\stopMPrun
+\stoptyping
+
+The source for the logo is stored in a file named \type {mylogos.mp}.
+
+\startbuffer
+beginfig(21) ;
+ draw fullsquare withcolor .625red ;
+ draw fullsquare rotated 45 withcolor .625red ;
+ picture cp ; cp := currentpicture ;
+ def copy = addto currentpicture also cp enddef ;
+ copy scaled .9 withcolor .625white ;
+ copy scaled .7 withcolor .625yellow ;
+ copy scaled .6 withcolor .625white ;
+ copy scaled .4 withcolor .625red ;
+ copy scaled .3 withcolor .625white ;
+ fill fullcircle scaled .2 withcolor .625yellow ;
+ currentpicture := currentpicture scaled 50 ;
+endfig ;
+end .
+\stopbuffer
+
+\typebuffer
+
+In this example the result is available in the virtual file \type {mprun.21}.
+This file can be included in the normal way, using:
+
+\starttyping
+\externalfigure[mprun.21][width=5cm]
+\stoptyping
+
+\startuseMPgraphic{dummy logo}
+ draw fullsquare withcolor .625red ;
+ draw fullsquare rotated 45 withcolor .625red ;
+ picture cp ; cp := currentpicture ;
+ def copy = addto currentpicture also cp enddef ;
+ copy scaled .9 withcolor .625white ;
+ copy scaled .7 withcolor .625yellow ;
+ copy scaled .6 withcolor .625white ;
+ copy scaled .4 withcolor .625red ;
+ copy scaled .3 withcolor .625white ;
+ fill fullcircle scaled .2 withcolor .625yellow ;
+ currentpicture := currentpicture scaled 3cm ;
+\stopuseMPgraphic
+
+\placefigure
+ {The logo is defined in the file \type {mylogos.mp} as
+ figure~21 and processed by means of the \type {mprun}
+ method.}
+ {\useMPgraphic{dummy logo}}
+
+Optionally you can specify a name and an instance. This has the advantage that
+the graphics don't interfere with the regular inline graphics. Here the instance
+used is \type {extrafun} and the name where the run is stored is \type {mydemo}.
+
+\startbuffer
+\startMPrun{extrafun::mydemo}
+ input mfun-mrun-demo.mp ;
+\stopMPrun
+
+\placefigure
+ {An external file can have multiple graphics. Here we show a few
+ images that we used to use on the \PRAGMA\ \CONTEXT\ website.}
+ {\startcombination[2*2]
+ {\externalfigure[mprun:extrafun::mydemo.1][height=6cm]} {downloads}
+ {\externalfigure[mprun:extrafun::mydemo.2][height=6cm]} {links}
+ {\externalfigure[mprun:extrafun::mydemo.3][height=6cm]} {mirrors}
+ {\externalfigure[mprun:extrafun::mydemo.4][height=6cm]} {team}
+ \stopcombination}
+\stopbuffer
+
+\typebuffer
+
+Keep in mind that the whole file will be processed (using the built in library)
+in order to get one graphic. Normally this is no big deal.
+
+\getbuffer
+
+\stopsection
+
+\startsection[title={Using \METAFUN\ but not \CONTEXT}]
+
+\index{graphics+standalone}
+
+If you don't want to use \CONTEXT\ but still want to use \METAFUN, a rather
+convenient method is the following. Create a file that
+
+\starttyping
+\startMPpage
+ % Your mp code goes here. You can use the textext
+ % macro as discussed later to deal with typeset text.
+\stopMPpage
+\stoptyping
+
+When you process that file with the \type {context} command you will get a \PDF\
+file that you can include in any application that can embed a \PDF\ image. In
+this case your exposure to \CONTEXT\ is minimal.
+
+\stopsection
+
+\startsection[title={Graphic buffers}]
+
+\index{graphics+buffers}
+\index{buffers}
+
+In addition to the macros defined in the previous section, you can use \CONTEXT's
+buffers to handle graphics. This can be handy when making documentation, so it
+makes sense to spend a few words on them.
+
+A buffer is a container for content that is to be (re|)|used later on. The main
+reason for their existence is that they were needed for typesetting manuals and
+articles on \TEX. By putting the code snippets in buffers, we don't have to key
+in the code twice, since we can either show the code of buffers verbatim, or
+process the code as part of the text flow. This means that the risk of mismatch
+between the code shown and the typeset text is minimized.
+
+\startbuffer[a]
+\startbuffer
+You are reading the \METAFUN\ manual.
+\stopbuffer
+\stopbuffer
+
+\typebuffer[a]
+
+This buffer can be typeset verbatim using \type {\typebuffer} and processed using
+\type {\getbuffer}, as we will do now:
+
+\blank \getbuffer[a] \blank
+
+An other advantage of using buffers, is that they help you keeping the document
+source clean. In many places in this manual we put table or figure definitions in
+a buffer and pass the buffer to another command, like:
+
+\starttyping
+\placefigure{A very big table}{\getbuffer}
+\stoptyping
+
+Sometimes it makes sense to collect buffers in separate files. In that case we
+give them names.
+
+\startbuffer
+\startbuffer[mfun]
+You are reading the \METAFUN\ manual.
+\stopbuffer
+\stopbuffer
+
+This time we should say \type {\typebuffer[mfun]} to typeset the code verbatim.
+Instead of \TEX\ code, we can put \METAPOST\ definitions in buffers.
+
+\startbuffer
+\startbuffer[graphic]
+draw fullcircle scaled 2cm ;
+\stopbuffer
+\stopbuffer
+
+Buffers can be used to stepwise build graphics. By putting code in multiple
+buffers, you can selectively process this code.
+
+\startbuffer
+\startbuffer[red]
+drawoptions(withcolor .625red) ;
+\stopbuffer
+
+\startbuffer[yellow]
+drawoptions(withcolor .625yellow) ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer
+
+We can now include the same graphic in two colors by simply using different
+buffers. This time we use the special command \type {\processMPbuffer}, since
+\type {\getbuffer} will typeset the code fragment, which is not what we want.
+
+\startbuffer
+\startlinecorrection[blank]
+\processMPbuffer[red,graphic]
+\stoplinecorrection
+\stopbuffer
+
+\typebuffer
+
+The line correction macros take care of proper spacing around the graphic. The
+\type {[blank]} directive tells \CONTEXT\ to add more space before and after the
+graphic.
+
+\startbuffer
+\startlinecorrection[blank]
+\processMPbuffer[yellow,graphic]
+\stoplinecorrection
+\stopbuffer
+
+\typebuffer
+
+Which mechanism you use, (multiple) buffers or (re|)|usable graphics, depends on
+your preferences. Buffers are slower but don't take memory, while (re|)|usable
+graphics are stored in memory which means that they are accessed faster.
+
+\stopsection
+
+\startsection[title={Communicating color}]
+
+\index{color}
+
+Now that color has moved to the desktop, even simple documents have become more
+colorful, so we need a way to consistently apply color to text as well as
+graphics. In \CONTEXT, colors are called by name.
+
+The next definitions demonstrate that we can define a color using different color
+models, \RGB\ or \CMYK. Depending on the configuration, \CONTEXT\ will convert
+one color system to the other, \RGB\ to \CMYK, or vice versa. The full repertoire
+of color components that can be set is as follows.
+
+\starttyping
+\definecolor[color one] [r=.1, g=.2, b=.3]
+\definecolor[color two] [c=.4, m=.5, y=.6, k=.7]
+\definecolor[color three][s=.8]
+\stoptyping
+
+The numbers are limited to the range $0\dots1$ and represent percentages. Black
+is represented by:
+
+\starttyping
+\definecolor[black 1] [r=0, g=0, b=0]
+\definecolor[black 2] [c=0, m=0, y=0, k=1]
+\definecolor[black 3] [s=0]
+\stoptyping
+
+Predefined colors are passed to \METAPOST\ graphics via the \type {\MPcolor}.
+First we define some colors.
+
+\starttyping
+\definecolor[darkyellow][y=.625] % a CMYK color
+\definecolor[darkred] [r=.625] % a RGB color
+\definecolor[darkgray] [s=.625] % a gray scale
+\stoptyping
+
+These are the colors we used in this document. The next example uses two of them.
+
+\startbuffer
+\startuseMPgraphic{color demo}
+ pickup pencircle scaled 1mm ;
+ path p ; p := fullcircle xscaled 10cm yscaled 1cm ;
+ fill p withcolor \MPcolor{darkgray} ;
+ draw p withcolor \MPcolor{darkred} ;
+\stopuseMPgraphic
+
+\useMPgraphic{color demo}
+\stopbuffer
+
+\typebuffer
+
+The previous example uses a pure \RGB\ red shade, combined with a gray fill.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+Originally \METAPOST\ only supported only the \RGB\ and gray color spaces. In \METAFUN\
+we also supported \CMYK\ and spot colors, using an extension mechanism that hooked into
+the backend. At some point \METAPOST\ got native support for \CMYK. When you use mixed
+color models you need to be aware of the fact that their related variables have different
+types:
+
+\starttabulate[||T|T|]
+\NC gray \NC numeric \NC s \NC \NR
+\NC rgb \NC color \NC (r,g,b) \NC \NR
+\NC cmyk \NC cmykcolor \NC (c,m,y,k) \NC \NR
+\stoptabulate
+
+Because in \METAFUN\ (\type {mpiv}) we hook deeply into the \CONTEXT\ color
+mechanisms we can use symbolic names instead. and these are just strings.
+
+There is a fundamental difference between a yellow as defined in \CONTEXT\ using
+\CMYK\ and a \RGB\ yellow.
+
+\startbuffer
+\definecolor[cmyyellow] [y=1]
+\definecolor[rgbyellow] [r=1,g=1]
+
+\definecolor[cmydarkyellow][y=.625]
+\definecolor[rgbdarkyellow][r=.625,g=.625]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\in {Figure} [fig:many yellows:pass] demonstrates what happens when we multiply
+colors by a factor. Since we are not dealing with real \CMYK\ colors,
+multiplication gives different results for \CMYK\ colors passed as \type
+{\MPcolor}. \in {Figure} [fig:many yellows:fetch] we show the same colors but
+this time we use a different method, one that avoids the \TEX\ macro. This method
+can be used in \MKIV. We will use both methods in examples.
+
+\def\TestColor#1%
+ {\startuseMPgraphic{yellow}
+ fill unitsquare xscaled (.30*\the\hsize) yscaled 1cm withcolor #1 ;
+ \stopuseMPgraphic
+ \useMPgraphic{yellow}}
+
+\startbuffer
+\setuptype[style=\ttx]%
+\startcombination[3*3]
+ {\TestColor{(0,0,1,0)}} {\type{(0,0,1,0)}}
+ {\TestColor{(1,1,0)}} {\type{(1,1,0)}}
+ {\TestColor{(.5,.5,0)}} {\type{(.5,.5,0)}}
+ {\TestColor{\MPcolor{rgbyellow}}} {\type{\MPcolor{rgbyellow}}}
+ {\TestColor{\MPcolor{rgbdarkyellow}}} {\type{\MPcolor{rgbdarkyellow}}}
+ {\TestColor{.5\MPcolor{rgbyellow}}} {\type{.5\MPcolor{rgbyellow}}}
+ {\TestColor{\MPcolor{cmyyellow}}} {\type{\MPcolor{cmyyellow}}}
+ {\TestColor{\MPcolor{cmydarkyellow}}} {\type{\MPcolor{cmydarkyellow}}}
+ {\TestColor{.5\MPcolor{cmyyellow}}} {\type{.5\MPcolor{cmyyellow}}}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:many yellows:pass]
+ {All kinds of yellow (passing valued from \TEX).}
+ {\getbuffer}
+
+\startbuffer
+\setuptype[style=\ttx]%
+\startcombination[3*3]
+ {\TestColor{(0,0,1,0)}} {\type{(0,0,1,0)}}
+ {\TestColor{(1,1,0)}} {\type{(1,1,0)}}
+ {\TestColor{(.5,.5,0)}} {\type{(.5,.5,0)}}
+ {\TestColor{"rgbyellow"}} {\type{"rgbyellow"}}
+ {\TestColor{"rgbdarkyellow"}} {\type{"rgbdarkyellow"}}
+ {\TestColor{.5namedcolor("rgbyellow")}} {\type{.5namedcolor("rgbyellow")}}
+ {\TestColor{"cmyyellow"}} {\type{"cmyyellow"}}
+ {\TestColor{"cmydarkyellow"}} {\type{"cmydarkyellow"}}
+ {\TestColor{.5namedcolor("cmyyellow")}} {\type{.5namedcolor("cmyyellow")}}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:many yellows:fetch]
+ {All kinds of yellow (fetching values from \TEX).}
+ {\getbuffer}
+
+So, \type {.625red} is the same as \type {[r=.5]}, but \type {.625yellow} is not
+the same as \type {[y=.5]}, but matches \type {[r=.5,g=.5]}. \in {Figure}
+[fig:some reds] shows the pure and half reds.
+
+\def\TestColor#1%
+ {\startMPcode
+ fill unitsquare xscaled (.30*\the\hsize) yscaled 1cm withcolor #1 ;
+ \stopMPcode}
+
+\startbuffer
+\setuptype[style=\ttx]\setupcolors[mpcmyk=no]
+\startcombination[3*2]
+ {\TestColor{red}} {\type{red}}
+ {\TestColor{(1,0,0)}} {\type{(1,0,0)}}
+ {\TestColor{(.625,0,0)}} {\type{(.625,0,0)}}
+ {\TestColor{"red"}} {\type{"red")}}
+ {\TestColor{"darkred"}} {\type{"darkred")}}
+ {\TestColor{.625namedcolor("red")}} {\type{.625namedcolor("red")}}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:some reds]
+ {Some kinds of red.}
+ {\getbuffer}
+
+In order to prevent problems, we advise you to stick to \RGB\ color
+when you create documents for screen and \CMYK\ when producing for print.
+
+In the \METAFUN\ macro collection there is a macro \type {cmyk} that takes four
+arguments, representing the cyan, magenta, yellow, and black component. Nowadays
+you don't need it as we have native \CMYK.
+
+\startbuffer
+fill unitsquare xyscaled (10cm, 5mm) withcolor cmyk(1,0,.3,.3) ;
+fill unitsquare xyscaled (10cm,-5mm) withcolor (1,.3,0,.3) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+If you take a close look at the numbers, you will notice that the cyan component
+results in a 100\% ink contribution. You will also notice that 30\% black ink is
+added. This means that we cannot safely convert this color to \RGB\ ($r=1-c-k<0$)
+without losing information. Nevertheless the previous blue bar is presented all
+right. This is due to the fact that in \METAFUN\ the \CMYK\ colors are handled as
+they should, even when \METAPOST\ does not support this color model.
+
+If you use this feature independent of \CONTEXT, you need to enable it by setting
+\type {cmykcolors} to \type {true}. You have to convert the resulting graphic to
+\PDF\ by using for instance the \type {mptopdf} suite.
+
+In \CONTEXT\ you can influence this conversion by changing parameters related to
+color handling:
+
+\starttyping
+\setupcolors[cmyk=yes,rgb=no]
+\stoptyping
+
+Unless you know what you are doing, you don't have to change the default settings
+(both \type {yes}). In the \CONTEXT\ reference manual you can also read how color
+reduction can be handled.
+
+Special care should be paid to gray scales. Combining equal quantities of the
+three color inks will not lead to a gray scale, but to a muddy brown shade.
+
+\startbuffer
+fill fullsquare xyscaled (10cm, 2cm) withcolor .5white ;
+fill fullsquare xyscaled ( 6cm,1.5cm) withcolor cmyk(.5,.5,.5,0) ;
+fill fullsquare xyscaled ( 2cm, 1cm) withcolor cmyk(0,0,0,.5) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+In \in {figure} [fig:cmyk 1] \in {and} [fig:cmyk 2] you can see some more colors
+defined in the \CMYK\ color space. When you display the screen version of this
+document, you will notice that the way colors are displayed can differ per
+viewer. This is typical for \CMYK\ colors and has to do with the fact that some
+assumptions are made with respect to the (print) medium.
+
+\startbuffer[mp]
+ fill fullcircle xyscaled (3cm,1cm) withcolor \MPcolor{test} ;
+\stopbuffer
+
+\startbuffer[cmyk]
+\startcombination[4*1]
+ {\definecolor[test][c=1,y=.3,k=.3] \processMPbuffer[mp]} {c=1 y=.3 k=.3}
+ {\definecolor[test][c=.9,y=.15] \processMPbuffer[mp]} {c=.9 y=.15}
+ {\definecolor[test][c=.25,y=.8] \processMPbuffer[mp]} {c=.25 y=.8}
+ {\definecolor[test][c=.45,y=.1] \processMPbuffer[mp]} {c=.45 y=.1}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:cmyk 1]
+ {\CMYK\ support enabled.}
+ {\getbuffer[cmyk]}
+
+\placefigure
+ [here][fig:cmyk 2]
+ {\CMYK\ support disabled, no support in \METAPOST.}
+ {\setupcolors[cmyk=no]\getbuffer[cmyk]\setupcolors[cmyk=yes]}
+
+\stopsection
+
+% \startsection[title={Common definitions}]
+%
+% \index{inclusions}
+% \index{common definitions}
+%
+% When using many graphics, there is a chance that they share common definitions.
+% Such shared components can be defined by:
+%
+% \starttyping
+% \startMPinclusions
+% color mycolor ; mycolor := .625red ;
+% \stopMPinclusions
+% \stoptyping
+%
+% {\em The following is only true for \CONTEXT\ \MKII ! Users of \MKIV\ can skip
+% this section.}
+%
+% All \METAPOST\ graphics defined in the document end up in the files \type
+% {mpgraph.mp} and \type {mprun.mp}. When processed, they produce (sometimes many)
+% graphic files. When you use \CONTEXT\ \MKII\ and \TEXEXEC\ to process documents,
+% these two files are processed automatically after a run so that in a next run,
+% the right graphics are available.
+%
+% When you are using the \type {web2c} distribution, \CONTEXT\ can call \METAPOST\
+% at runtime and thereby use the right graphics instantaneously. In order to use
+% this feature, you have to enable \type {\write18} in the file \type {texmf.cnf}.
+% Also, in the file \type {cont-sys.tex}, that holds local preferences, or in the
+% document source, you should say:
+%
+% \starttyping
+% \runMPgraphicstrue
+% \stoptyping
+%
+% This enables runtime generation of graphics using the low level \TEX\ command
+% \type {\write18}. First make sure that your local brand of \TEX\ supports this
+% feature. A simple test is making a \TEX\ file with the following line:
+%
+% \starttyping
+% \immediate\write18{echo It works}
+% \stoptyping
+%
+% If this fails, you should consult the manual that comes with your system, locate
+% an expert or ask around on the \CONTEXT\ mailing list. Of course you can also
+% decide to let \TEXEXEC\ take care of processing the graphics afterwards. This has
+% the advantage of being faster but has the disadvantage that you need additional
+% \TEX\ runs.
+%
+% If you generate the graphics at run time, you should consider to turn on graphic
+% slot recycling, which means that you often end up with fewer intermediate files:
+%
+% \starttyping
+% \recycleMPslotstrue
+% \stoptyping
+%
+% There are a few more low level switches and features, but these go beyond the
+% purpose of this manual. Some of these features, like the option to add tokens to
+% \type {\everyMPgraphic} are for experts only, and fooling around with them can
+% interfere with existing features.
+%
+% \stopsection
+
+\startsection[title={One page graphics}]
+
+An advantage of using \CONTEXT\ to make your \METAPOST\ graphics is you don't
+have to bother about specials, font inclusion and all those nasty things that can
+spoil a good day. An example of such a graphic is the file \type {mfun-800} that
+resides on the computer of the author.
+
+\typefile{mfun-800}
+
+Given that \CONTEXT\ is present on your system, you can process this file with:
+
+\starttyping
+context mfun-800
+\stoptyping
+
+You can define many graphics in one file. Later you can include individual pages
+from the resulting \PDF\ file in your document:
+
+\startbuffer
+\placefigure
+ {A silly figure, demonstrating that stand||alone||graphics
+ can be made.}
+ {\typesetfile[mfun-800.tex][page=1]}
+\stopbuffer
+
+\typebuffer
+
+In this case the \type {page=1} specification is not really needed. You can scale
+and manipulate the figure in any way supported by the macro package that you use.
+
+\getbuffer
+
+\stopsection
+
+\startsection[title={Managing resources}]
+
+A graphic consists of curves, either or not filled with a given color. A graphic
+can also include text, which means that fonts are used. Finally a graphic can
+have special effects, like a shaded fill. Colors, fonts and special effects go
+under the name resources, since they may demand special care or support from the
+viewing or printing device.
+
+% When fonts are used, a \METAPOST\ file is not self contained. This means that the
+% postprocessing program has to deal with the fonts. In \CONTEXT, the special
+% driver |<|and \PDFTEX\ support is considered as such|>| takes care of this.
+
+Special effects, like shading, are supported by dedicated \METAPOST\ modules.
+These are included in the \CONTEXT\ distribution and will be discussed later in
+\in {chapter} [sec:effects].
+
+Since \METAPOST\ supports color, an embedded graphic can be rather colorful.
+However, when color support is disabled or set up to convert colors to gray
+scales, \CONTEXT\ will convert the colors in the graphics to gray scales.
+
+\startbuffer[circle]
+ colorcircle(4cm,red,green,blue) ;
+\stopbuffer
+
+\startbuffer
+\startcombination[3*1]
+ {\setupcolors[state=start]\processMPbuffer[circle]} {full color}
+ {\setupcolors[state=stop]\processMPbuffer[circle]} {weighted gray}
+ {\setupcolors[state=stop,factor=no]\processMPbuffer[circle]} {linear gray}
+\stopcombination
+\stopbuffer
+
+You may wonder what the advantage is of weighted gray conversion. \in {Figure}
+[fig:color circles] shows the difference between natural colors, weighted gray
+scales and straightforward, non||weighted, gray scales.
+
+\placefigure
+ [here][fig:color circles]
+ {The advantage of weighted gray over linear gray.}
+ {\getbuffer\setupcolors[state=start,factor=yes]} % just to be sure
+
+When we convert color to gray, we use the following formula. This kind of
+conversion also takes place in black and white televisions.
+
+\placeformula [-]
+ \startformula
+ G = .30r + .59g + .11b
+ \stopformula
+
+\in {Section} [sec:conversion] introduces the \type {grayed} operation that you
+can use to convert a colored picture into a gray one. This macro uses the same
+conversion method as mentioned here.
+
+\stopsection
+
+\startsection[title={Instances}]
+
+There are a few instances predefined and if you want to isolate your own
+graphics from whatever \CONTEXT\ itself cooks up, you can define more as the
+extra overhead can be neglected.
+
+\starttabulate[|T|T|T|T|T|]
+\BC name \BC format \BC extensions \BC initializations \BC method \NC \NR
+\NC metafun \NC metafun \NC yes \NC yes \NC \NC \NR
+\NC extrafun \NC metafun \NC yes \NC yes \NC \NC \NR
+\NC lessfun \NC metafun \NC \NC \NC \NC \NR
+\NC doublefun \NC metafun \NC yes \NC yes \NC double \NC \NR
+\NC binaryfun \NC metafun \NC yes \NC yes \NC binary \NC \NR
+\NC decimalfun \NC metafun \NC yes \NC yes \NC decimal \NC \NR
+\stoptabulate
+
+According to this the \type {doublefun} instance is defined as:
+
+\starttyping
+\defineMPinstance
+ [doublefun]
+ [format=metafun,
+ extensions=yes,
+ initializations=yes,
+ method=double]
+\stoptyping
+
+The \type {extensions} key relates to:
+
+\starttyping
+\startMPextensions
+ % some code
+\stopMPextensions
+\stoptyping
+
+that are used to pass (common) extensions to the instance. The \type
+{initializations} key relates to:
+
+\starttyping
+\startMPinitializations
+ % some code
+\stopMPinitializations
+\stoptyping
+
+that are used to communicate \TEX\ properties to the instance (they are
+expanded each graphic). Instance bound definitions can be set with:
+
+\starttyping
+\startMPdefinitions{doublefun}
+ % some code
+\stopMPdefinitions
+\stoptyping
+
+We do have more instances, for instance for the chemical subsystem. If you load
+the \type {graph} module you get a double precision \type {graph} instance. We might
+use more private ones in the future.
+
+When you make graphic pages, you can do this:
+
+\starttyping
+\startMPpage[instance=doublefun]
+ % some code
+\stopMPpage
+\stoptyping
+
+When you use the other commands you can optionally specify an instance:
+
+\startbuffer[metafun]
+\startMPcode{metafun}
+ draw textext(decimal pi) scaled 2 withcolor .625red ;
+ draw boundingbox currentpicture enlarged 2pt ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[extrafun]
+\startMPcode{extrafun}
+ draw textext(decimal pi) scaled 2 withcolor .625green ;
+ draw boundingbox currentpicture enlarged 2pt ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[doublefun]
+\startMPcode{doublefun}
+ draw textext(decimal pi) scaled 2 withcolor .625blue ;
+ draw boundingbox currentpicture enlarged 2pt ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[binaryfun]
+\startMPcode{binaryfun}
+ draw textext(decimal pi) scaled 2 withcolor .625yellow ;
+ draw boundingbox currentpicture enlarged 2pt ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[decimalfun]
+\startMPcode{decimalfun}
+ draw textext(decimal pi) scaled 2 withcolor .375white ;
+ draw boundingbox currentpicture enlarged 2pt ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[metafun,extrafun,doublefun,binaryfun,decimalfun]
+
+The result is shown in \in {figure} [fig:instances] and as expected there
+is a different value for $\pi$ reported.
+
+\startplacefigure[reference=fig:instances,title={Instances can use different number systems.}]
+ \startcombination[1*5]
+ {\getbuffer[metafun]} {metafun}
+ {\getbuffer[extrafun]} {extrafun}
+ {\getbuffer[doublefun]} {doublefun}
+ {\getbuffer[binaryfun]} {binaryfun}
+ {\getbuffer[decimalfun]} {decimalfun}
+ \stopcombination
+\stopplacefigure
+
+You need to be aware of the fact that the results of a (for instance) double
+instance can differ from a scaled (the default) one. As long as graphics can be
+processed in both models (which is the case as long as the dimensions stay below
+4096 base points) the outcome is probably not that different. However, we've seen
+that the accuracy of for instance $\pi$ (just a variable) differs. I like to use
+random values and the random generators are definitely different: each of the
+number libraries has its own implementation. Let's look at that. We define two
+random graphic generators:
+
+\startbuffer
+\startuseMPgraphic{normaldeviate}
+ randomseed := 100 ;
+ draw fullsquare
+ withpen pencircle scaled 1/200
+ withcolor .5white ;
+ for i=1 upto 500 :
+ draw (normaldeviate,normaldeviate)
+ scaled 1/3
+ withpen pencircle scaled 1/30
+ withtransparency (1,.5) ;
+ endfor ;
+ setbounds currentpicture to
+ boundingbox fullcircle
+ enlarged 1/2 ;
+ currentpicture :=
+ currentpicture
+ xsized (2TextWidth/5) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+And:
+
+\startbuffer
+\startuseMPgraphic{uniformdeviate}
+ randomseed := 100 ;
+ draw fullsquare
+ withpen pencircle scaled 1/200
+ withcolor .5white ;
+ for i=1 upto 500 :
+ draw (-1/2 + uniformdeviate 1,-1/2 + uniformdeviate 1)
+ withpen pencircle scaled 1/30
+ withtransparency (1,.5) ;
+ endfor ;
+ setbounds currentpicture to
+ boundingbox fullcircle
+ enlarged 1/2 ;
+ currentpicture :=
+ currentpicture
+ xsized (2TextWidth/5) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We show the results for a normaldeviate in \in {figure} [fig:random:1] \in {upto}
+[fig:random:4] you see the randomizers per number system. In \in {figure}
+[fig:random:compared] we demonstrate that the scaled version has its own variant.
+
+\unexpanded\def\TestRandomFun#1#2#3%
+ {\startMPcode{#1}
+ draw image(\includeMPgraphic{#2})
+ withcolor #3 ;
+ \stopMPcode}
+
+\startplacefigure[reference=fig:random:1,title={The scaled randomizers.}]
+ \pushrandomseed
+ \startcombination
+ {\TestRandomFun{metafun} {normaldeviate} {darkred}} {normaldeviate}
+ {\TestRandomFun{metafun} {uniformdeviate}{darkred}} {uniformdeviate}
+ \stopcombination
+ \poprandomseed
+\stopplacefigure
+
+\startplacefigure[reference=fig:random:2,title={The double randomizers.}]
+ \pushrandomseed
+ \startcombination
+ {\TestRandomFun{doublefun} {normaldeviate} {darkgreen}} {normaldeviate}
+ {\TestRandomFun{doublefun} {uniformdeviate}{darkgreen}} {uniformdeviate}
+ \stopcombination
+ \poprandomseed
+\stopplacefigure
+
+\startplacefigure[reference=fig:random:3,title={The decimal randomizers.}]
+ \pushrandomseed
+ \startcombination
+ {\TestRandomFun{decimalfun}{normaldeviate} {darkblue}} {normaldeviate}
+ {\TestRandomFun{decimalfun}{uniformdeviate}{darkblue}} {uniformdeviate}
+ \stopcombination
+ \poprandomseed
+\stopplacefigure
+
+\startplacefigure[reference=fig:random:4,title={The binary randomizers.}]
+ \pushrandomseed
+ \startcombination
+ {\TestRandomFun{binaryfun} {normaldeviate} {darkyellow}} {normaldeviate}
+ {\TestRandomFun{binaryfun} {uniformdeviate}{darkyellow}} {uniformdeviate}
+ \stopcombination
+ \poprandomseed
+\stopplacefigure
+
+\startplacefigure[reference=fig:random:compared,title={Normaldeviate and uniformdeviate overlayed.}]
+ \pushrandomseed
+ \startcombination[2*1]
+ \bgroup
+ \startoverlay
+ {\TestRandomFun{metafun} {normaldeviate} {darkred}}
+ {\TestRandomFun{doublefun} {normaldeviate} {darkgreen}}
+ {\TestRandomFun{decimalfun}{normaldeviate} {darkblue}}
+ {\TestRandomFun{binaryfun} {normaldeviate} {darkyellow}}
+ \stopoverlay
+ \egroup {normaldeviate}
+ \bgroup
+ \startoverlay
+ {\TestRandomFun{metafun} {uniformdeviate}{darkred}}
+ {\TestRandomFun{doublefun} {uniformdeviate}{darkgreen}}
+ {\TestRandomFun{decimalfun}{uniformdeviate}{darkblue}}
+ {\TestRandomFun{binaryfun} {uniformdeviate}{darkyellow}}
+ \stopoverlay
+ \egroup {uniformdeviate}
+ \stopcombination
+ \poprandomseed
+\stopplacefigure
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-environment-layout.tex b/doc/context/sources/general/manuals/metafun/metafun-environment-layout.tex
new file mode 100644
index 000000000..409839cba
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-environment-layout.tex
@@ -0,0 +1,151 @@
+\startenvironment metafun-environment-layout
+
+\setupsystem
+ [random=big]
+
+\setupfootertexts
+ [section][] % [Preliminary Version \currentdate][]
+ [][section] % [][Preliminary Version \currentdate]
+
+\useMPlibrary
+ [clp,txt]
+
+\definepapersize
+ [mine]
+ [width=21cm,
+ height=28cm]
+
+\setuppapersize
+ [mine]
+ [A4]
+
+\setuplayout
+ [topspace=1cm,
+ backspace=3cm,
+ cutspace=3cm,
+ leftmargin=.75cm,
+ leftmargindistance=.5cm,
+ rightmargin=1.25cm,
+ rightmargindistance=1cm,
+ header=1cm,
+ headerdistance=1cm,
+ footer=1cm,
+ footerdistance=1cm,
+ width=middle,
+ height=middle,
+ % marking=on,
+ location=middle]
+
+\startmode[book]
+
+ % \definepapersize
+ % [mine]
+ % [width=21cm,
+ % height=24cm]
+ %
+ % \setuppapersize
+ % [mine]
+ % [oversized]
+ %
+ % \setuplayout
+ % [backspace=2.5cm,
+ % cutspace=3.5cm]
+
+ \setuplayout
+ [marking=on,
+ scale=\luaexpr{24/28}]
+
+\stopmode
+
+\startmode[print]
+
+ \setuppapersize
+ [mine]
+ [mine]
+
+\stopmode
+
+\setupcolumns
+ [distance=1cm]
+
+\setuppagenumbering
+ [alternative=doublesided]
+
+\definetypeface [metafunbodyfont] [rm] [serif] [pagella] [default]
+\definetypeface [metafunbodyfont] [ss] [sans] [modern] [default]
+\definetypeface [metafunbodyfont] [tt] [mono] [modern] [default]
+\definetypeface [metafunbodyfont] [mm] [math] [palatino] [default]
+
+\setupbodyfont [metafunbodyfont,10pt] % 11 pt and 12pt -> errors due to intersection mess
+
+\definefont[RotFont][RegularBold*default]
+
+% \setupindenting
+% [medium,yes]
+
+\setupwhitespace
+ [medium]
+
+\setuptyping
+ [margin=standard,
+ blank=halfline]
+
+\definecolor [darkred] [r=.625]
+\definecolor [darkyellow] [r=.625,g=.625] % not: [y=.625]
+\definecolor [darkgray] [s=.625]
+\definecolor [lightgray] [s=.875]
+
+\definecolor [metafun] [darkred]
+
+\startMPinclusions
+ color darkred ; darkred := \MPcolor{darkred} ;
+ color darkyellow ; darkyellow := \MPcolor{darkyellow} ;
+ color darkgray ; darkgray := \MPcolor{darkgray} ;
+ color lightgray ; lightgray := \MPcolor{lightgray} ;
+\stopMPinclusions
+
+\setupinteraction % otherwise funny page dimensions due to
+ [state=start, % grouping half way the file in demo text
+ style=,
+ color=,
+ contrastcolor=]
+
+% \enabledirectives[refences.linkmethod=page]
+
+% \setupstructure % needs \startchapter
+% [state=start]
+
+\placebookmarks
+ [chapter,title,section]
+ [all]
+ [force=yes]
+
+\setuptolerance
+ [verytolerant]
+
+\definestartstop
+ [intro]
+ [style=slanted,
+ after=\blank]
+
+\setupquote
+ [before=\blank\startnarrower,
+ after=\stopnarrower\blank]
+
+\setuplist
+ [chapter]
+ [after={\blank[line]}]
+
+\setupcombinedlist
+ [content]
+ [aligntitle=yes,
+ alternative=c,
+ interaction=all]
+
+\setuptabulate
+ [rulecolor=darkyellow,
+ rulethickness=1pt]
+
+\setuplist[chapter][style=bold]
+
+\stopenvironment
diff --git a/doc/context/sources/general/manuals/metafun/metafun-environment-samples.tex b/doc/context/sources/general/manuals/metafun/metafun-environment-samples.tex
new file mode 100644
index 000000000..5991a61d5
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-environment-samples.tex
@@ -0,0 +1,321 @@
+\startenvironment metafun-environment-sample
+
+\startuseMPgraphic{sample setup}
+ numeric Scale ; Scale := 2cm ;
+ numeric Size ; Size := 2.5mm/Scale ;
+ numeric Pen ; Pen := .25mm/Scale ;
+ path Path ;
+ pickup pencircle scaled (4Pen) ;
+ def InRed = withcolor .625red enddef ;
+ def InYellow = withcolor .625yellow enddef ;
+ def InGray = withpen pencircle scaled Pen withcolor .625white enddef ;
+ def InBetween= withpen pencircle scaled (4Pen) withcolor .800white enddef ;
+ def InBlack = withpen pencircle scaled Pen enddef ;
+ def InWhite = withpen pencircle scaled Pen withcolor white enddef ;
+ def DrawArrow text t =
+ draw t ; Path := boundingbox currentpicture ;
+ drawarrow t ; setbounds currentpicture to Path ;
+ enddef ;
+ def ColorCircle =
+ fill llcircle withcolor .625red ;
+ fill lrcircle withcolor .625green ;
+ fill urcircle withcolor .625blue ;
+ fill ulcircle withcolor .625yellow ;
+ enddef ;
+ evenly := dashpattern(on (3mm/Scale) off (3mm/Scale)) ;
+ withdots := dashpattern(off (2.5mm/Scale) on 0 off (2.5mm/Scale)) ;
+ ahlength := 4mm/Scale ; ahangle := 30 ;
+ draw (origin shifted (0,Size)--origin shifted (0,-Size)) ;
+ draw (origin shifted (Size,0)--origin shifted (-Size,0)) ;
+ picture Origin ; Origin := currentpicture ;
+ setbounds Origin to origin--cycle ;
+ currentpicture := nullpicture ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{sample finish}
+ draw boundingbox currentpicture InBlack ;
+ draw Origin InGray ;
+ currentpicture := currentpicture scaled Scale ;
+\stopuseMPgraphic
+
+% fm = metafun macro
+% fv = metafun variable
+% mc = metapost concept
+% mm = metapost macro
+% mp = metapost primitive
+% mv = metapost variable
+
+\starttexdefinition unexpanded DoDoSampleHead#1#2#3
+ \setbox\scratchbox\vbox {
+ \tabskip\zeropoint
+ \tt\tfx
+ \halign {
+ \strut\hss##\unskip\unskip
+ \cr#3\cr#1\cr
+ }
+ }
+ \ht\scratchbox\ht\strutbox
+ \dp\scratchbox\dp\strutbox
+ \noligature{#2}\black
+ \hfill
+ \box\scratchbox
+ \ignorespaces
+\stoptexdefinition
+
+\starttexdefinition unexpanded DoSampleHead #1#2#3
+ \processaction
+ [#1]
+ [fm=>\DoDoSampleHead{metafun macro}{#2}{#3},
+ fv=>\DoDoSampleHead{metafun variable}{#2}{#3},
+ mc=>\DoDoSampleHead{metapost concept}{#2}{#3},
+ mm=>\DoDoSampleHead{metapost macro}{#2}{#3},
+ mp=>\DoDoSampleHead{metapost primitive}{#2}{#3},
+ mv=>\DoDoSampleHead{metapost variable}{#2}{#3}]
+\stoptexdefinition
+
+\starttexdefinition unexpanded SampleHead #1#2#3
+ \expanded{\extrosubject{\DoSampleHead{#1}{#2}{\detokenize{#3}}}}
+\stoptexdefinition
+
+\starttexdefinition unexpanded StartSample
+ \doquintuplegroupempty\doStartSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded StopSample
+ % dummy
+\stoptexdefinition
+
+\starttexdefinition unexpanded doStartSample #1#2#3#4#5#6 StopSample
+ \bgroup
+ \SampleHead{#1}{#2}{#3}
+ \startuseMPgraphic{dummy}
+ \includeMPgraphic{sample setup}
+ #6
+ \includeMPgraphic{sample finish}
+ \stopuseMPgraphic
+ \blank[samepage]
+ \startlinecorrection[blank]
+ \useMPgraphic{dummy}
+ \stoplinecorrection
+ \egroup
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleZ #1#2#3
+ \bgroup
+ \SampleHead{#1}{#2}{}
+ \blank[samepage]
+ #3
+ \par
+ \egroup
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleA #1#2#3
+ \StartSample{#1}{#2}{#3}
+ path p ; p := #3 ; % freeze randomized
+ if length(p)>0 :
+ DrawArrow p InRed ;
+ fi ;
+ drawpoints p InBetween ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleB #1#2#3#4
+ \StartSample{#1}{#2}{#4}
+ DrawArrow (#3) InRed ;
+ DrawArrow (#4) InYellow ;
+ drawpoints (#3) InBetween ;
+ drawpoints (#4) InBetween ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleC #1#2#3#4
+ \StartSample{#1}{#2}{#4}
+ path bb ; bb := boundingbox #3 ;
+ DrawArrow #3 InRed ;
+ draw #4 withpen pencircle scaled .15 InYellow ;
+ setbounds currentpicture to bb ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleD #1#2#3#4
+ \StartSample{#1}{#2}{#4}
+ DrawArrow #3 InRed ;
+ setbounds currentpicture to #4 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleDD #1#2#3#4
+ \StartSample{#1}{#2}{#4}
+ DrawArrow #3 InRed ;
+ DrawArrow #4 InYellow ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleE #1#2#3#4
+ \StartSample{#1}{#2}{#4}
+ fill fullcircle scaled 1cm InRed ;
+ currentpicture := currentpicture #3 ;
+ Scale := 1 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleF #1#2#3#4
+ \StartSample{#1}{#2}{#4}
+ DrawArrow #3 InRed ;
+ drawdot #4 InYellow ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleG #1#2#3#4
+ \StartSample{#1}{#2}{#4}
+ draw #3 InRed ;
+ drawdot #4 InYellow ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleH #1#2#3#4#5
+ \StartSample{#1}{#2}{#5}
+ DrawArrow #3 InRed ;
+ DrawArrow #4 InYellow ;
+ drawdot #5 InWhite ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleHH #1#2#3
+ \StartSample{#1}{#2}{#3}
+ draw #3 InRed ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleI #1#2#3
+ \StartSample{#1}{#2}{#3}
+ draw fullcircle InRed #3 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleII #1#2#3
+ \StartSample{#1}{#2}{#3}
+ draw fullcircle #3 InRed ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleJ #1#2#3
+ \StartSample{#1}{withpen #2}{withpen #3 scaled 2mm}
+ draw fullcircle xscaled 2 withpen #3 scaled Pen InRed ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleK #1#2#3
+ \StartSample{#1}{withpen #2}{withpen #3}
+ draw fullcircle xscaled 2 withpen #3 InRed ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleL #1#2#3
+ \StartSample{#1}{#2}{#2 #3}
+ #2 #3 InRed;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleM #1#2#3
+ \StartSample{#1}{#2}{#2 #3}
+ fill boundingbox (#3--cycle) InRed ;
+ #2 #3 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleN #1#2#3#4
+ \StartSample{#1}{#2}{#3}
+ #3 ;
+ draw #4 withpen pencircle scaled 25Pen InRed ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleO #1#2#3
+ \StartSample{#1}{#2}{#3}
+ drawdot origin InRed ;
+ #3 scaled (2.5/Scale) InYellow ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleP #1#2#3
+ \StartSample{#1}{#2}{#3}
+ drawdot origin InRed ;
+ #3 scaled (2.5/Scale) InYellow ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleQ #1#2#3
+ \StartSample{#1}{#2}{#3}
+ #2 #3 withpen pencircle scaled 25Pen InRed ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleQQ #1#2#3
+ \StartSample{#1}{#2}{#3}
+ #3 scaled (2.5/Scale) withpen pencircle scaled Pen InYellow ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleQQQ #1#2#3
+ \StartSample{#1}{#2}{#3}
+ #3 scaled (2.5/Scale) withpen pencircle scaled Pen ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleR #1#2#3
+ \StartSample{#1}{#2}{#3}
+ ColorCircle ;
+ addto currentpicture also (#3) shifted (bbwidth(currentpicture)+.1,0) ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleS #1#2#3
+ \StartSample{#1}{#2}{#3}
+ Pen := Pen * Scale ; Scale := 1 ; #3 ;%
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleT #1#2#3#4
+ \StartSample{#1}{#2}{#3}
+ #4 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleU #1#2#3
+ \StartSample{#1}{#2}{#3}
+ Scale := Scale / 5 ;
+ #3 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleUU #1#2#3
+ \StartSample{#1}{#2}{#3}
+ Scale := Scale / 10 ;
+ #3 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleV #1#2#3#4
+ \StartSample{#1}{#2}{#3}
+ Scale := Scale / 5 ;
+ Pen := Pen * 20 ;
+ #4 ;
+ Pen := Pen / 20 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleW #1#2#3#4
+ \StartSample{#1}{#2}{#3}
+ Scale := 1 ;
+ #4 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleX #1#2#3
+ \StartSample{#1}{#2}{#3}
+ #3 InRed ;
+ \StopSample
+\stoptexdefinition
+
+\stopenvironment
diff --git a/doc/context/sources/general/manuals/metafun/metafun-environment-screen.tex b/doc/context/sources/general/manuals/metafun/metafun-environment-screen.tex
new file mode 100644
index 000000000..afeea7008
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-environment-screen.tex
@@ -0,0 +1,139 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startenvironment mfun-environment-screen
+
+\enablemode[screen]
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [backspace=60pt,
+ topspace=60pt,
+ cutspace=0pt,
+ header=0pt,
+ footer=0pt,
+ bottom=20pt,
+ bottomdistance=40pt,
+ top=20pt,
+ topdistance=40pt,
+ leftmargin=30pt,
+ leftmargindistance=25pt,
+ rightmargin=0pt,
+ edge=0pt,
+ width=middle,
+ height=middle]
+
+\setupbodyfont
+ [9pt]
+
+\setuppagenumbering
+ [alternative=singlesided]
+
+\setupinteraction
+ [state=start,
+ style=bold,
+ color=darkred,
+ contrastcolor=darkred,
+ symbolset=navigation 3,
+ menu=on]
+
+\setupsymbolset
+ [navigation 3]
+
+\setupinteractionscreen
+ [option=max]
+
+\setupinteractionmenu
+ [bottom]
+ [unknownreference=yes,
+ state=start]
+
+\setuptoptexts
+ []
+ [{\lightgray \bf Page \pagenumber
+ \doifcontent\quad{}{}\hbox{\getmarking[section]}}]
+
+\startinteractionmenu[bottom]
+ \txt \bf \lightgray \getmarking[chapter] \\
+ \hfill
+ \bgroup
+ \setupinteraction[color=white,contrastcolor=white]
+ \got [CloseDocument] exit \\
+ \egroup
+ \got [content] content \\
+ \got [index] index \\
+% \got [commands] commands \\
+ \got [reference] reference \\
+ \setupinteraction[color=white,contrastcolor=white]
+ \got [PreviousJump] \symbol[PreviousJump] \\
+ \got [previouspage] \symbol[previouspage] \\
+ \got [nextpage] \symbol[nextpage] \\
+ \got [NextJump] \symbol[NextJump] \\
+\stopinteractionmenu
+
+\starttexdefinition unexpanded ChapterCommand #1#2
+ \framed [
+ background=titled,
+ frame=off
+ ] {
+ #1
+ \quad
+ #2
+ }
+\stoptexdefinition
+
+\startuseMPgraphic{PageFrame}
+ StartPage ;
+ save p, q, ranx, rany, minx, miny, maxx, maxy ;
+ pickup pencircle scaled 4pt ;
+ pair p[] ; path q[] ; numeric ranx, rany, minx, miny, maxx, maxy ;
+ minx := BackSpace/2 ; maxx := PaperWidth -minx ; ranx := minx/2 ;
+ miny := TopSpace /2 ; maxy := PaperHeight-miny ; rany := miny/2 ;
+ p[0] := llcorner Page ;
+ p[1] := (minx,0) randomshifted (ranx,0) ;
+ p[2] := (maxx,0) randomshifted (ranx,0) ;
+ p[3] := lrcorner Page ;
+ p[4] := (PaperWidth,miny) randomshifted (0,rany) ;
+ p[5] := (PaperWidth,maxy) randomshifted (0,rany) ;
+ p[6] := urcorner Page ;
+ p[7] := (maxx,PaperHeight) randomshifted (ranx,0) ;
+ p[8] := (minx,PaperHeight) randomshifted (ranx,0) ;
+ p[9] := ulcorner Page ;
+ p[10] := (0,maxy) randomshifted (0,rany) ;
+ p[11] := (0,miny) randomshifted (0,rany) ;
+ def page_color = (.4+uniformdeviate.3)*white enddef ;
+ fill Page withcolor \MPcolor{lightgray} ;
+ q[1] := p[9]--p[6]--p[ 5]--p[10]--cycle ;
+ q[2] := p[6]--p[3]--p[ 2]--p[ 7]--cycle ;
+ q[3] := p[3]--p[0]--p[11]--p[ 4]--cycle ;
+ q[4] := p[0]--p[9]--p[ 8]--p[ 1]--cycle ;
+ for i=1 upto 4: fill q[i] withcolor page_color ; endfor ;
+ q[1] := p[9]--p[8]--((p[8]--p[ 1]) intersectionpoint (p[10]--p[ 5]))--p[10]--cycle ;
+ q[2] := p[6]--p[5]--((p[5]--p[10]) intersectionpoint (p[ 2]--p[ 7]))--p[ 7]--cycle ;
+ q[3] := p[3]--p[4]--((p[4]--p[11]) intersectionpoint (p[ 7]--p[ 2]))--p[ 2]--cycle ;
+ q[4] := p[0]--p[1]--((p[1]--p[ 8]) intersectionpoint (p[ 4]--p[11]))--p[11]--cycle ;
+ for i=1 upto 4: fill q[i] withcolor page_color ; endfor ;
+ q[1] := p[ 8]--p[1] ;
+ q[2] := p[ 7]--p[2] ;
+ q[3] := p[10]--p[5] ;
+ q[4] := p[11]--p[4] ;
+ for i=1 upto 4: draw q[i] withcolor \MPcolor{darkred} ; endfor ;
+ StopPage ;
+\stopuseMPgraphic
+
+% \setupbackgrounds[page][background=PageFrame]
+
+\setupbackgrounds
+ [page]
+ [background={PageFrame,backgraphics,foreground,foregraphics}]
+
+\defineoverlay[PageFrame][\useMPgraphic{PageFrame}]
+
+\startMPinclusions
+ background := \MPcolor{lightgray} ;
+\stopMPinclusions
+
+\stopenvironment
diff --git a/doc/context/sources/general/manuals/metafun/metafun-environment.tex b/doc/context/sources/general/manuals/metafun/metafun-environment.tex
new file mode 100644
index 000000000..ca9fc24b3
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-environment.tex
@@ -0,0 +1,595 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startenvironment metafun-environment
+
+\environment metafun-environment-layout
+
+\usemodule[abr-01,syntax]
+
+\startuseMPgraphic{cover page}
+
+ numeric w ; w := PaperWidth -eps ; % or clip
+ numeric h ; h := PaperHeight-eps ; % or clip
+
+ for i=0cm step 1cm until w :
+ for j=0cm step 1cm until h :
+ fill unitsquare scaled 1cm shifted (i,j) withcolor (.6+uniformdeviate.35)*white ;
+ endfor ;
+ endfor ;
+
+ % clip currentpicture to unitsquare xyscaled (w,h) ;
+
+ for i=0cm step 1cm until w+.5cm :
+ draw (i,0) -- (i,h) withpen pensquare scaled .5mm withcolor .625yellow ;
+ endfor ;
+
+ for i=0cm step 1cm until h+.5cm :
+ draw (0,i) -- (w,i) withpen pensquare scaled .5mm withcolor .625yellow ;
+ endfor ;
+
+\stopuseMPgraphic
+
+\startuseMPgraphic{title page}
+
+ StartPage ;
+
+ \includeMPgraphic{cover page}
+
+ picture p ; p := image (draw rawtextext("\darkred\definedfont[Sans]metafun" )) ;
+ picture q ; q := image (draw rawtextext("\darkred\definedfont[Sans]Hans Hagen")) ;
+ % picture r ; r := image (draw rawtextext("\darkred\definedfont[Sans]\doifnotmode{book}{context mkiv}")) ;
+ picture r ; r := image (draw rawtextext("\darkred\definedfont[Sans]context mkiv")) ;
+
+ p := p xsized(PaperHeight - 2cm) ;
+ q := q xsized(PaperWidth - 8cm) ;
+ r := r xsized(6cm) ;
+
+ p := p rotated 90 ;
+ r := r rotated 90 ;
+
+ draw p shifted (urcorner Page - urcorner p - (1cm,1cm) - (-1mm,0) ) ;
+ draw q shifted (1cm, 1cm) ;
+ draw r shifted (urcorner Page - urcorner r - (5cm,2cm) ) ;
+
+ StopPage ;
+
+ setbounds currentpicture to Page ;
+
+\stopuseMPgraphic
+
+\startuseMPgraphic{back page}
+
+ \includeMPgraphic{cover page}
+
+\stopuseMPgraphic
+
+\startuseMPgraphic{small grid}
+
+ numeric w ; w := \overlaywidth ;
+ numeric h ; h := \overlayheight ;
+ numeric d ; d := .25cm ;
+
+ drawoptions(withcolor (.6+uniformdeviate.35)*white) ;
+
+ for i=0cm step d until w :
+ for j=0cm step d until h :
+ fill unitsquare scaled d shifted (i,j) ;
+ endfor ;
+ endfor ;
+
+ drawoptions(withpen pencircle scaled .125mm withcolor .625yellow) ;
+
+ for i=0 step d until w+d : draw (i,0) -- (i,h) ; endfor ;
+ for i=0 step d until h+d : draw (0,i) -- (w,i) ; endfor ;
+
+\stopuseMPgraphic
+
+\defineoverlay[title page][\useMPgraphic{title page}]
+
+\startnotmode[proof]
+ \defineoverlay[back page][\useMPgraphic{back page}]
+ \defineoverlay[small grid][\useMPgraphic{small grid}]
+\stopnotmode
+
+% could be all in mp
+
+\starttexdefinition unexpanded OnGrid#1
+ \hbox to \hsize \bgroup
+ \ifodd\realpageno
+ \hss
+ \fi
+ \setbox\scratchbox=\hbox {
+ \color[darkred]{#1}
+ }
+ \scratchoffset.25cm
+ \scratchwidth\wd\scratchbox
+ \ifdim\scratchwidth>\zeropoint
+ \advance \scratchwidth by .5\scratchoffset
+ \divide \scratchwidth by \scratchoffset
+ \multiply\scratchwidth by \scratchoffset
+ \advance \scratchwidth by 2\scratchoffset
+ \else
+ \scratchwidth8\scratchoffset
+ \fi
+ \dp\scratchbox \scratchoffset
+ \ht\scratchbox 2\scratchoffset
+ \framed [
+ background=small grid,
+ frame=off,
+ offset=overlay
+ ] {
+ \hbox to \scratchwidth {
+ \hss
+ \box\scratchbox
+ \hss
+ }
+ }
+ \unless \ifodd\realpageno
+ \hss
+ \fi
+ \egroup
+\stoptexdefinition
+
+\setupfootertexts
+ [margin]
+ []
+ [\OnGrid{\doifelsetext{\getmarking[chapter]}{\getmarking[chapter]}{\getmarking[title]}}]
+
+\startuseMPgraphic{circled}
+ pickup pencircle scaled 1mm ;
+ drawoptions(withcolor (.6+uniformdeviate.35)*white) ;
+ fill fullcircle xscaled 1.5cm yscaled 1cm ;
+ drawoptions(withcolor .625yellow) ;
+ draw fullcircle xscaled 1.5cm yscaled 1cm ;
+\stopuseMPgraphic
+
+\startnotmode[proof]
+ \defineoverlay[circled][\useMPgraphic{circled}]
+\stopnotmode
+
+\starttexdefinition unexpanded Circled #1
+ \framed [
+ background=circled,
+ frame=off,
+ offset=overlay
+ ] {
+ \color[darkred]{#1}
+ }
+\stoptexdefinition
+
+\setuppagenumbering
+ [location=]
+
+\setupheadertexts
+ [margin]
+ [][\hbox to \hsize{\hss\Circled\pagenumber\hss}]
+
+\setupheader
+ [style=bold]
+
+\setupfooter
+ [style=bold]
+
+\startuniqueMPgraphic{titled}
+ path p ; p := unitsquare xscaled OverlayWidth yscaled OverlayHeight ;
+ pickup pencircle scaled 1mm ;
+ drawoptions(withcolor .625yellow) ;
+ draw llcorner p -- lrcorner p ;
+ setbounds currentpicture to p ;
+\stopuniqueMPgraphic
+
+\defineoverlay[titled][\uniqueMPgraphic{titled}]
+
+\starttexdefinition unexpanded ChapterCommand #1#2
+ \ifconditional\headshownumber
+ \ifdim\leftmarginwidth<\rightmarginwidth
+ \donetrue
+ \else
+ \donefalse
+ \fi
+ \hskip-\ifdone\leftmargintotal\else\rightmargintotal\fi
+ \framed [
+ background=titled,
+ frame=off,
+ offset=0pt
+ ] {
+ \hbox to \ifdone\leftmarginwidth\else\rightmarginwidth\fi {
+ #1
+ \hss
+ }
+ \hskip\ifdone\leftmargindistance\else\rightmargindistance\fi
+ #2
+ }
+ \else
+ \framed [
+ background=titled,
+ frame=off,
+ offset=0pt
+ ] {
+ #2
+ }
+ \fi
+\stoptexdefinition
+
+\starttexdefinition unexpanded TitleCommand #1#2
+ \framed [
+ background=titled,
+ frame=off,
+ offset=0pt
+ ] {
+ #2
+ }
+\stoptexdefinition
+
+\starttexdefinition unexpanded IntroTitleCommand #1#2
+ \framed [
+ background=titled,
+ frame=off,
+ offset=0pt,
+ width=\textwidth
+ ] {
+ \hfill
+ #2
+ }
+\stoptexdefinition
+
+\starttexdefinition unexpanded ExtroTitleCommand #1#2
+ \framed [
+ background=titled,
+ frame=off,
+ offset=0pt,
+ width=\textwidth
+ ] {
+ \hss
+ #2
+ \hss
+ }
+\stoptexdefinition
+
+\setuphead
+ [chapter,section,subsection,subsubsection]
+ [color=darkred]
+
+\setuphead
+ [chapter]
+ [style=\bfc]
+
+\setuphead
+ [section]
+ [style=\bfa]
+
+\setuphead
+ [subsection]
+ [style=\bf]
+
+\setuphead
+ [subsubsection]
+ [style=\bf]
+
+\setuphead
+ [chapter,section,subsection,subsubsection]
+ [command=\ChapterCommand]
+
+\setuphead
+ [title,subject,subsubject,subsubsubject]
+ [command=\TitleCommand]
+
+
+\definehead [introsubject] [subsubject]
+\definehead [extrosubject] [subsubject]
+
+\setuphead [introsubject] [command=\IntroTitleCommand]
+\setuphead [extrosubject] [command=\ExtroTitleCommand]
+
+\setuphead
+ [subsection,subsubject]
+ [before=\blank,
+ after=\blank]
+
+% charts
+
+\usemodule[chart]
+
+\setupFLOWcharts
+ [offset=0pt,
+ width=6\bodyfontsize,
+ height=3\bodyfontsize,
+ dx=\bodyfontsize,
+ dy=\bodyfontsize]
+
+\setupFLOWshapes
+ [framecolor=darkred]
+
+\setupFLOWlines
+ [color=darkyellow]
+
+% hm, slows down the whole doc
+
+\setupbackgrounds
+ [page]
+ [background={backgraphics,foreground,foregraphics}]
+
+\defineoverlay [backgraphics] [\positionoverlay{backgraphics}]
+\defineoverlay [foregraphics] [\positionoverlay{foregraphics}]
+
+\startbuffer[shape-a]
+\startuniqueMPgraphic{meta:hash}{linewidth,linecolor,angle,gap}
+ if unknown context_back : input mp-back ; fi ;
+ some_hash ( OverlayWidth, OverlayHeight ,
+ \MPvar{linewidth}, \MPvar{linecolor} ,
+ \MPvar{angle}, \MPvar{gap} ) ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\startbuffer[shape-b]
+\setupMPvariables
+ [meta:hash]
+ [gap=.25\bodyfontsize,
+ angle=45,
+ linewidth=\overlaylinewidth,
+ linecolor=\overlaylinecolor]
+\stopbuffer
+
+\startbuffer[shape-c]
+\def\metahashoverlay#1{\uniqueMPgraphic{meta:hash}{angle=#1}}
+
+\defineoverlay[meta:hash:right] [\metahashoverlay{ +45}]
+\defineoverlay[meta:hash:left] [\metahashoverlay{ -45}]
+\defineoverlay[meta:hash:horizontal][\metahashoverlay{+180}]
+\defineoverlay[meta:hash:vertical] [\metahashoverlay{ -90}]
+\stopbuffer
+
+\startbuffer[symb-a]
+\startuniqueMPgraphic{meta:button}{type,size,linecolor,fillcolor}
+ if unknown context_butt : input mp-butt ; fi ;
+ some_button ( \MPvar{type},
+ \MPvar{size},
+ \MPvar{linecolor},
+ \MPvar{fillcolor} ) ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\startbuffer[symb-b]
+\setupMPvariables
+ [meta:button]
+ [type=1,
+ size=2\bodyfontsize,
+ fillcolor=gray,
+ linecolor=darkred]
+\stopbuffer
+
+\startbuffer[symb-c]
+\def\metabuttonsymbol#1{\uniqueMPgraphic{meta:button}{type=#1}}
+
+\definesymbol[menu:left] [\metabuttonsymbol{101}]
+\definesymbol[menu:right] [\metabuttonsymbol{102}]
+\definesymbol[menu:list] [\metabuttonsymbol{103}]
+\definesymbol[menu:index] [\metabuttonsymbol{104}]
+\definesymbol[menu:person][\metabuttonsymbol{105}]
+\definesymbol[menu:stop] [\metabuttonsymbol{106}]
+\definesymbol[menu:info] [\metabuttonsymbol{107}]
+\definesymbol[menu:down] [\metabuttonsymbol{108}]
+\definesymbol[menu:up] [\metabuttonsymbol{109}]
+\definesymbol[menu:print] [\metabuttonsymbol{110}]
+\stopbuffer
+
+\hyphenation{tool-kit}
+
+\startbuffer[pagetext]
+\subject{Edward R. Tufte} \input tufte \par
+\subject{Donald E. Knuth} \input knuth \par
+\subject{Douglas R. Hostadter} \input douglas \page
+\stopbuffer
+
+\startbuffer[back-0]
+\defineoverlay[page][\useMPgraphic{page}]
+\setupbackgrounds[page][background=page]
+\stopbuffer
+
+\startbuffer[back-1]
+\startuseMPgraphic{page}
+ StartPage ;
+ path Main ;
+ if OnRightPage :
+ Main := lrcorner Field[OuterMargin][Text] --
+ llcorner Field[Text] [Text] --
+ ulcorner Field[Text] [Text] --
+ urcorner Field[OuterMargin][Text] -- cycle ;
+ else :
+ Main := llcorner Field[OuterMargin][Text] --
+ lrcorner Field[Text] [Text] --
+ urcorner Field[Text] [Text] --
+ ulcorner Field[OuterMargin][Text] -- cycle ;
+ fi ;
+ Main := Main enlarged 6pt ;
+ pickup pencircle scaled 2pt ;
+ fill Page withcolor .625white ;
+ fill Main withcolor .850white ;
+ draw Main withcolor .625red ;
+ StopPage ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[back-2]
+\startuseMPgraphic{page}
+ StartPage ;
+ pickup pencircle scaled 2pt ;
+ fill Page withcolor .625white ;
+ fill Field[OuterMargin][Text] withcolor .850white ;
+ fill Field[Text] [Text] withcolor .850white ;
+ draw Field[OuterMargin][Text] withcolor .625red ;
+ draw Field[Text] [Text] withcolor .625red ;
+ StopPage ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[back-3]
+\startuseMPgraphic{page}
+ StartPage ;
+ pickup pencircle scaled 2pt ;
+ fill Page withcolor .625white ;
+ fill Field[Text][Text] enlarged .5cm withcolor .850white ;
+ draw Field[Text][Text] enlarged .5cm withcolor .625red ;
+ StopPage ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[back-4]
+\startuseMPgraphic{page}
+ StartPage ;
+ def somewhere =
+ (uniformdeviate 1cm,uniformdeviate 1cm)
+ enddef ;
+ path Main ;
+ Main := Field[Text][Text] lrmoved somewhere --
+ Field[Text][Text] llmoved somewhere --
+ Field[Text][Text] ulmoved somewhere --
+ Field[Text][Text] urmoved somewhere -- cycle ;
+ pickup pencircle scaled 2pt ;
+ fill Page withcolor .625white ;
+ fill Main withcolor .850white ;
+ draw Main withcolor .625red ;
+ StopPage ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[back-4x]
+\startuseMPgraphic{page}
+ StartPage ;
+ path Main ; Main := Field[Text][Text] randomized 1cm ;
+ pickup pencircle scaled 2pt ;
+ fill Page withcolor .625white ;
+ fill Main withcolor .850white ;
+ draw Main withcolor .625red ;
+ StopPage ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[back-5]
+\startuseMPgraphic{page}
+ StartPage
+ for i=Top,Header,Text,Footer,Bottom :
+ for j=LeftEdge,LeftMargin,Text,RightMargin,RightEdge :
+ draw Field[i][j] withpen pencircle scaled 2pt withcolor .625red ;
+ endfor ;
+ endfor ;
+ StopPage
+\stopuseMPgraphic
+\stopbuffer
+
+\starttexdefinition unexpanded Literature #1#2#3
+ \blank
+ \noindentation
+ #1
+ \space
+ \begingroup
+ \bf
+ #2
+ \endgroup
+ \space
+ #3
+ \blank
+\stoptexdefinition
+
+\environment metafun-environment-samples
+
+\startbuffer[handwrit]
+
+\usetypescript[serif][chorus]
+
+\definefont[SomeHandwriting][TeXGyreChorus-MediumItalic*default at 12pt]
+
+\start \SomeHandwriting\setstrut
+
+\startMPpage
+ StartPage ;
+ numeric l, n ; path p ;
+ l := 1.5LineHeight ;
+ n := 0 ;
+ p := origin shifted (l,0) -- origin shifted (PaperWidth-l,0) ;
+ for i=PaperHeight-l step -l until l :
+ n := n + 1 ;
+ fill p shifted (0,i+StrutHeight) --
+ reverse p shifted (0,i-StrutDepth ) -- cycle
+ withcolor .85white ;
+ draw p shifted (0,i)
+ withpen pencircle scaled .25pt
+ withcolor .5white ;
+ draw p shifted (0,i+ExHeight)
+ withpen pencircle scaled .25pt
+ withcolor .5white ;
+ draw textext.origin("\strut How are those penalty lines called
+ in english? I may not steal candies ..." & decimal n)
+ shifted (l,i)
+ shifted (0,-StrutDepth) ;
+ endfor ;
+ StopPage ;
+\stopMPpage
+\stop
+\stopbuffer
+
+\startbuffer[gridpage]
+\startMPpage
+ StartPage ;
+ width := PaperWidth ; height := PaperHeight ; unit := cm ;
+ drawoptions(withpen pencircle scaled .2pt withcolor .8white) ;
+ draw vlingrid(0, width /unit, 1/10, width, height) ;
+ draw hlingrid(0, height/unit, 1/10, height, width ) ;
+ drawoptions(withpen pencircle scaled .5pt withcolor .4white) ;
+ draw vlingrid(0, width /unit, 1, width, height) ;
+ draw hlingrid(0, height/unit, 1, height, width ) ;
+ StopPage ;
+\stopMPpage
+\stopbuffer
+
+% needed to get white backgrounds
+
+\startmode[screen]
+
+\startbuffer[wipe]
+picture savedpicture ;
+savedpicture := currentpicture ;
+currentpicture := nullpicture ;
+draw savedpicture withcolor black ;
+draw savedpicture ;
+\stopbuffer
+
+\stopmode
+
+\startnotmode[screen]
+
+\startbuffer[wipe]
+ % nothing to whipe
+\stopbuffer
+
+\stopnotmode
+
+\startbuffer[backtext]
+
+ This document introduces you in the world of the graphic programming language
+ \MetaPost. Not only the language itself is covered in detail, but also the way to
+ interface with the typographic language \TeX. We also present the collection of
+ \MetaPost\ extensions that come with the \ConTeXt\ typesetting system. This
+ collection goes under the name \MetaFun.
+
+ \blank
+
+ All aspects of the \MetaPost\ language are covered. The first chapters focus on
+ the language itself, later chapters cover aspects like color, graphic
+ inclusions, adding labels, and stepwise constructing graphics. We finish with a
+ graphical overview of commands.
+
+\stopbuffer
+
+\startbuffer[backbanner]
+
+ \WidthSpanningText
+ {PRAGMA Advanced Document Engineering, Hasselt NL, \currentdate[year]}
+ {\hsize}
+ {RegularBold}
+
+\stopbuffer
+
+\stopenvironment
diff --git a/doc/context/sources/general/manuals/metafun/metafun-examples.tex b/doc/context/sources/general/manuals/metafun/metafun-examples.tex
new file mode 100644
index 000000000..4e5e0eed3
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-examples.tex
@@ -0,0 +1,3269 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-examples
+
+\environment metafun-environment
+
+\startchapter[title={A few applications}]
+
+\startintro
+
+For those who need to be inspired, we will demonstrate how \METAPOST\ can be used
+to enhance your document with simple graphics. In these examples we will try to
+be not too clever, simply because we lack the experience to be that clever. The
+real tricks can be found in the files that come with \METAPOST.
+
+\stopintro
+
+\startsection[reference={sec:coils,sec:springs},title={Simple drawings}]
+
+In the words of John Hobby, the creator of \METAPOST, \quotation {\METAPOST\ is
+particularly well||suited for generating figures for technical documents where
+some aspects of a picture may be controlled by mathematical or geometrical
+constraints that are best expressed symbolically. In other words, \METAPOST\ is
+not meant to take the place of a freehand drawing tool or even an interactive
+graphics editor}.
+
+An example of such a picture is the following one, which is dedicated to David
+Arnold, who asked me once how to draw a spring. So, imagine that we want to draw
+a schematic view of a system of four springs.
+
+\startbuffer[a]
+def spring (expr a, b, w, h, n) =
+ ( ( (0,0) -- (0,h) --
+ for i=1 upto n-1: (if odd(i) : - fi w/2,i+h) -- endfor
+ (0,n+h) -- (0,n+2h) )
+ yscaled ((xpart (b-a) ++ ypart (b-a))/(n+2h))
+ rotatedaround(origin,-90+angle(b-a))
+ shifted a )
+enddef ;
+\stopbuffer
+
+\startbuffer[b]
+vardef spring (expr a, b, w, h, n) =
+ pair vec ; path pat ; numeric len ; numeric ang ;
+ vec := (b-a) ;
+ pat := for i=1 upto n-1: (if odd(i):-fi w/2,i)--endfor (0,n) ;
+ pat := (0,0)--(0,h)-- pat shifted (0,h)--(0,n+h)--(0,n+2h) ;
+ len := (xpart vec ++ ypart vec)/(n+2h) ;
+ ang := -90+angle(vec) ;
+ ( pat yscaled len rotatedaround(origin,ang) shifted a )
+enddef ;
+\stopbuffer
+
+\startbuffer[c]
+path p ; p :=
+ (0,0)--spring((.5cm,0),(2.5cm,0),.5cm,0,10)--(3cm,0) ;
+
+draw p withpen pencircle scaled 2pt ;
+draw p withpen pencircle scaled 1pt withcolor .8white;
+\stopbuffer
+
+\startbuffer[d]
+z1 = (+2cm,0) ; z2 = (0,+2cm) ;
+z3 = (-2cm,0) ; z4 = (0,-2cm) ;
+
+pickup pencircle scaled 1.5pt ;
+
+drawoptions (withcolor .625red) ;
+
+draw spring (z1, z2, .75cm, 2, 10) ; draw z1 -- 1.5 z1 ;
+draw spring (z2, z3, .75cm, 2, 9) ; draw z2 -- 1.1 z2 ;
+draw spring (z3, z4, .75cm, 2, 8) ; draw z3 -- 1.5 z3 ;
+draw spring (z4, z1, .75cm, 2, 7) ; draw z4 -- 1.1 z4 ;
+\stopbuffer
+
+\startbuffer[e]
+drawarrow
+ (0,0)--spring((.5cm,0),(2.5cm,0),.5cm,0,10)--(3cm,0)
+ withpen pencircle scaled 2pt withcolor .625red ;
+\stopbuffer
+
+\startbuffer[f]
+numeric u ; u := 1mm ; pickup pencircle scaled (u/2) ;
+drawoptions (withcolor .625red) ;
+draw (0,0)--spring((5u,0),(25u,0),5u,0,10)--(30u,0) ;
+drawoptions (dashed evenly withcolor .5white) ;
+draw (0,0)--spring((5u,0),(35u,0),(25/35)*5u,0,10)--(40u,0) ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,d]
+\stoplinecorrection
+
+A rather natural way to define such a system is:
+
+\typebuffer[d]
+
+Here, the macro \type {spring} takes 5~arguments: two points, the width of the
+winding, the length of the connecting pieces, and the number of elements (half
+windings). The definition of \type {spring} is less complicated than readable.
+
+\typebuffer[a]
+
+First we build a path starting in the origin, going left or right depending on
+the counter being an odd number.
+
+\starttyping
+pat := (0,0) ;
+for i=1 upto n-1:
+ if odd(i) :
+ pat := pat -- (-w/2,i) ;
+ else :
+ pat := pat -- (+w/2,i) ;
+ fi ;
+endfor ;
+pat := pat -- (0,n) ;
+\stoptyping
+
+Once you are accustomed to the way \METAPOST\ interprets (specialists may say
+expand) the source code, you will start using \type {if} and \type {for}
+statements in assignments. The previous code can be converted in a one liner,
+using the pattern:
+
+\starttyping
+pat := for i=1 upto n-1: (x,y)-- endfor (0,n) ;
+\stoptyping
+
+The loop splits out a series of \type {(x,y)--} but the last point is added
+outside the loop. Otherwise \type {pat} would have ended with a dangling \type
+{--}. Of course we need to replace \type {(x,y)} by something meaningful, so we
+get:
+
+\starttyping
+pat := for i=1 upto n-1: (if odd(i):-fi w/2,i)--endfor (0,n) ;
+\stoptyping
+
+We scale this path to the length needed. The expression $b-a$ calculates a
+vector, starting at $a$ and ending at $b$. In \METAPOST, the expression \type
+{a++b} is identical to $\sqrt{a^2+b^2}$. Thus, the expression \typ {xpart (b-a)
+++ ypart (b-a)} calculates the length of the vector $b-a$. Because the unscaled
+spring has length $n+2h$, scaling by the expression \typ {((xpart (b-a) ++ ypart
+(b-a)) / (n+2h))} gives the spring the same length as the vector $b-a$.
+
+Because we have drawn our spring in the vertical position, we first rotate it 90
+degrees clockwise to a horizontal position, and then rotate it through an angle
+equal to the angle in which the vector $b-a$ is pointing. After that, we shift it
+to the first point. The main complications are that we also want to draw
+connecting lines at the beginning and end, as well as support springs that
+connect arbitrary points. Since no check is done on the parameters, you should be
+careful in using this macro.
+
+When we want to improve the readability, we have to use intermediate variables.
+Since the macro is expected to return a path, we must make sure that the content
+matches this expectation.
+
+\typebuffer[b]
+
+If you use \type {vardef}, then the last statement is the return value. Here,
+when \typ {p := spring (z1, z2, .75cm, 2, 10)} is being parsed, the macro is
+expanded, the variables are kept invisible for the assignment, and the path at
+the end is considered to be the return value. In a \type {def} the whole body of
+the macro is \quote {pasted} in the text, while in a \type {vardef} only the last
+line is visible. We will demonstrate this with a simple example.
+
+\starttyping
+def one = (n,n) ; n := n+1 ; enddef ;
+def two = n := n + 1 ; (n,n) enddef ;
+\stoptyping
+
+Now, when we say:
+
+\starttyping
+pair a, b ; numeric n ; n= 10 ; a := one ; b := two ;
+\stoptyping
+
+we definitely get an error message. This is because, when macro \type {two} is
+expanded, \METAPOST\ sees something:
+
+\starttyping
+b := n := n + 1 ;
+\stoptyping
+
+By changing the second definition in
+
+\starttyping
+vardef two = n := n + 1 ; (n,n) enddef ;
+\stoptyping
+
+the increment is expanded out of sight for \type {b :=} and the pair \type
+{(n,n)} is returned.
+
+We can draw a slightly better looking spring by drawing twice with a different
+pen. The following commands use the spring macro implemented by the \type
+{vardef}.
+
+\typebuffer[c]
+
+This time we get:
+
+\startlinecorrection[blank]
+\processMPbuffer[a,c]
+\stoplinecorrection
+
+Since the \type {spring} macro returns a path, you can do whatever is possible
+with a path, like drawing an arrow:
+
+\startlinecorrection[blank]
+\processMPbuffer[a,e]
+\stoplinecorrection
+
+Or even (watch how we use the neutral unit \type {u} to specify the dimensions):
+
+\startlinecorrection[blank]
+\processMPbuffer[a,f]
+\stoplinecorrection
+
+This was keyed in as:
+
+\typebuffer[e]
+
+and:
+
+\typebuffer[f]
+
+\stopsection
+
+\startsection[reference=sec:free labels,title={Free labels}]
+
+\index {labels}
+
+The \METAPOST\ label macro enables you to position text at certain points. This
+macro is kind of special, because it also enables you to influence the
+positioning. For that purpose it uses a special kind of syntax which we will not
+discuss here in detail.
+
+\startbuffer[a]
+pickup pencircle scaled 1mm ;
+path p ; p := fullcircle scaled 3cm ;
+draw p withcolor .625yellow ;
+dotlabel.rt ("right" , point 0 of p) ;
+dotlabel.urt ("upper right" , point 1 of p) ;
+dotlabel.top ("top" , point 2 of p) ;
+dotlabel.ulft ("upper left" , point 3 of p) ;
+dotlabel.lft ("left" , point 4 of p) ;
+dotlabel.llft ("lower left" , point 5 of p) ;
+dotlabel.bot ("bottom" , point 6 of p) ;
+dotlabel.lrt ("lower right" , point 7 of p) ;
+\stopbuffer
+
+\typebuffer[a]
+
+The \type {label} command just typesets a text, while \type {dotlabel} also draws
+a dot at the position of the label. The \type {thelabel} (not shown here) command
+returns a picture.
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+There is a numeric constant \type {labeloffset} that can be set to influence the
+distance between the point given and the content of the label. When we set the
+offset to zero, we get the following output.
+
+\startbuffer[x]
+interim labeloffset := 0pt ; % local assignment
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a]
+\stoplinecorrection
+
+This kind of positioning works well as long as we know where we want the label to
+be placed. However, when we place labels automatically, for instance in a macro,
+we have to apply a few clever tricks. There are for sure many ways to accomplish
+this goal, but here we will follow the mathless method.
+
+\startbuffer[a]
+pickup pencircle scaled 1mm ;
+path p ; p := fullcircle scaled 3cm ;
+draw p withcolor .625yellow ;
+vardef do (expr str) =
+ save currentpicture ; picture currentpicture ;
+ currentpicture := thelabel(str,origin) ;
+ draw boundingbox currentpicture withpen pencircle scaled .5pt ;
+ currentpicture
+enddef ;
+\stopbuffer
+
+\startbuffer[b]
+dotlabel.rt (do("right") , point 0 of p) ;
+dotlabel.urt (do("upper right") , point 1 of p) ;
+dotlabel.top (do("top") , point 2 of p) ;
+dotlabel.ulft (do("upper left") , point 3 of p) ;
+dotlabel.lft (do("left") , point 4 of p) ;
+dotlabel.llft (do("lower left") , point 5 of p) ;
+dotlabel.bot (do("bottom") , point 6 of p) ;
+dotlabel.lrt (do("lower right") , point 7 of p) ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+The previous graphic visualizes the bounding box of the labels. This bounding box
+is rather tight and therefore the placement of labels will always be suboptimal.
+Compare the alignment of the left- and rightmost labels. The \type {btex}||\type
+{etex} method is better, since then we can add struts, like:
+
+\starttyping
+btex \strut right etex
+\stoptyping
+
+to force labels with uniform depths and heights. The next graphic demonstrates
+that this looks better indeed. Also, as \TEX\ does the typesetting we get the
+current text font instead of the label font and the content will be properly
+typeset; for instance kerning will be applied when applicable. Spending some time
+on such details pays back in better graphics.
+
+\startbuffer[b]
+dotlabel.rt (do(btex \strut right etex) , point 0 of p) ;
+dotlabel.urt (do(btex \strut upper right etex) , point 1 of p) ;
+dotlabel.top (do(btex \strut top etex) , point 2 of p) ;
+dotlabel.ulft (do(btex \strut upper left etex) , point 3 of p) ;
+dotlabel.lft (do(btex \strut left etex) , point 4 of p) ;
+dotlabel.llft (do(btex \strut lower left etex) , point 5 of p) ;
+dotlabel.bot (do(btex \strut bottom etex) , point 6 of p) ;
+dotlabel.lrt (do(btex \strut lower right etex) , point 7 of p) ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+Now, what happens when we want to place labels in other positions? In the worst
+case, given that we place the labels manually, we end up in vague arguments in
+favour for one or the other placement.
+
+\startbuffer[y]
+p := p rotatedaround(center p, 22.5) ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,y,b]
+\stoplinecorrection
+
+Although any automatic mechanism will be sub||optimal, we can give it a try to
+write a macro that deals with arbitrary locations. This macro will accept three
+arguments and return a picture.
+
+\starttyping
+thefreelabel("some string or picture",a position,the origin)
+\stoptyping
+
+Our testcase is just a simple \type {for} loop that places a series of labels.
+The \type {freedotlabel} macro is derived from \type {thefreelabel}.
+
+\startbuffer[c]
+pickup pencircle scaled 1mm ;
+path p ; p := fullcircle scaled 3cm ;
+draw p withcolor .625yellow ;
+for i=0 step .5 until 7.5 :
+ freedotlabel ("text" , point i of p, center p) ;
+endfor ;
+\stopbuffer
+
+\typebuffer[c]
+
+As a first step we will simply place the labels without any correction. We also
+visualize the bounding box.
+
+\startbuffer[b]
+vardef freedotlabel (expr str, loc, ori) =
+ drawdot loc ; draw thefreelabel(str,loc,ori) ;
+enddef ;
+
+vardef freelabel (expr str, loc, ori) =
+ draw thefreelabel(str,loc,ori) ;
+enddef ;
+\stopbuffer
+
+\startbuffer[a]
+vardef thefreelabel (expr str, loc, ori) =
+ save s ; picture s ; s := thelabel(str,loc) ;
+ draw boundingbox s withpen pencircle scaled .5pt ;
+ s
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+To make our lives more easy, we also define a macro that draws the dot as well as
+a macro that draws the label.
+
+\typebuffer[b]
+
+Now we get:
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b,c]
+\stoplinecorrection
+
+The original label macros permits us to align the label at positions, 4~corners
+and 4~points halfway the sides. It happens that circles are also composed of
+8~points. Because in most cases the label is to be positioned in the direction of
+the center of a curve and the point at hand, it makes sense to take circles as
+the starting points for positioning the labels.
+
+To help us in positioning, we define a special square path, \type {freesquare}.
+This path is constructed out of 8~points that match the positions that are used
+to align labels.
+
+\startbuffer[d]
+path freesquare ;
+
+freesquare := ((-1,0)--(-1,-1)--(0,-1)--(+1,-1)--
+ (+1,0)--(+1,+1)--(0,+1)--(-1,+1)--cycle) scaled .5 ;
+\stopbuffer
+
+\typebuffer[d]
+
+We now show this free path together with a circle, using the following
+definitions:
+
+\startbuffer[e]
+drawpath fullcircle scaled 3cm ;
+drawpoints fullcircle scaled 3cm ;
+drawpointlabels fullcircle scaled 3cm ;
+currentpicture := currentpicture shifted (5cm,0) ;
+drawpath freesquare scaled 3cm ;
+drawpoints freesquare scaled 3cm ;
+drawpointlabels freesquare scaled 3cm ;
+\stopbuffer
+
+\typebuffer[e]
+
+We use two drawing macros that are part of the suite of visual debugging macros.
+
+\startlinecorrection[blank]
+\processMPbuffer[x,d,e]
+\stoplinecorrection
+
+As you can see, point~1 is the corner point that suits best for alignment when a
+label is put at point~1 of the circle. We will now rewrite \type {thefreelabel}
+in such a way that the appropriate point of the associated \type {freesquare} is
+found.
+
+\startbuffer[a]
+vardef thefreelabel (expr str, loc, ori) =
+ save s, p, q, l ; picture s ; path p, q ; pair l ;
+ s := thelabel(str,loc) ;
+ p := fullcircle scaled (2*length(loc-ori)) shifted ori ;
+ q := freesquare xyscaled (urcorner s - llcorner s) ;
+ l := point (xpart (p intersectiontimes (ori--loc))) of q ;
+ draw q shifted loc withpen pencircle scaled .5pt ;
+ draw l shifted loc withcolor .625yellow ;
+ draw loc withcolor .625red ;
+ s
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+The macro xyscaled is part of \METAFUN\ and scales in two directions at once. The
+\METAPOST\ primitive \type {intersectiontimes} returns a pair of time values of
+the point where two paths intersect. The first part of the pair concerns the
+first path.
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b,c]
+\stoplinecorrection
+
+We are now a small step from the exact placement. If we change the last line of
+the macro into:
+
+\starttyping
+(s shifted -l)
+\stoptyping
+
+we get the displacement we want. Although the final look and feel is also
+determined by the text itself, the average result is quite acceptable.
+
+\startbuffer[a]
+vardef thefreelabel (expr str, loc, ori) =
+ save s, p, q, l ; picture s ; path p, q ; pair l ;
+ s := thelabel(str,loc) ;
+ p := fullcircle scaled (2*length(loc-ori)) shifted ori ;
+ q := freesquare xyscaled (urcorner s - llcorner s) ;
+ l := point (xpart (p intersectiontimes (ori--loc))) of q ;
+ draw q shifted loc withpen pencircle scaled .5pt ;
+ draw l shifted loc withcolor .625yellow ;
+ draw loc withcolor .625red ;
+ (s shifted -l)
+enddef ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b,c]
+\stoplinecorrection
+
+Because we also want to pass pictures, and add a bit of offset too, the final
+implementation is slightly more complicated. The picture is handled with an
+additional condition, and the offset with the \METAFUN\ macro \type {enlarged}.
+
+\startbuffer[a]
+newinternal freelabeloffset ; freelabeloffset := 3pt ;
+
+vardef thefreelabel (expr str, loc, ori) =
+ save s, p, q, l ; picture s ; path p, q ; pair l ;
+ interim labeloffset := freelabeloffset ;
+ s := if string str : thelabel(str,loc)
+ else : str shifted -center str shifted loc fi ;
+ setbounds s to boundingbox s enlarged freelabeloffset ;
+ p := fullcircle scaled (2*length(loc-ori)) shifted ori ;
+ q := freesquare xyscaled (urcorner s - llcorner s) ;
+ l := point (xpart (p intersectiontimes (ori--loc))) of q ;
+ setbounds s to boundingbox s enlarged -freelabeloffset ;
+ (s shifted -l)
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+Watch how we temporarily enlarge the bounding box of the typeset label text. We
+will now test this macro on a slightly rotated circle, using labels typeset by
+\TEX. The \type {reverse} is there purely for cosmetic reasons, to suit the label
+texts.
+
+\startbuffer[b]
+pickup pencircle scaled 1mm ;
+path p ; p := reverse fullcircle rotated -25 scaled 3cm ;
+draw p withcolor .625yellow ; pair cp ; cp := center p ;
+freedotlabel (btex \strut We can etex, point 0 of p, cp) ;
+freedotlabel (btex \strut go on etex, point 1 of p, cp) ;
+freedotlabel (btex \strut and on etex, point 2 of p, cp) ;
+freedotlabel (btex \strut in etex, point 3 of p, cp) ;
+freedotlabel (btex \strut defining etex, point 4 of p, cp) ;
+freedotlabel (btex \strut funny etex, point 5 of p, cp) ;
+freedotlabel (btex \strut macros. etex, point 6 of p, cp) ;
+freedotlabel (btex \strut Can't we? etex, point 7 of p, cp) ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+\typebuffer[b]
+
+Unfortunately we can run into problems due to rounding errors. Therefore we use a
+less readable but more safe expression for calculating the intersection points.
+Instead of using point \type {loc} as endpoint we use \type {loc} shifted over a
+very small distance into the direction \type {loc} from \type{ori}. In the
+assignment to~\type {l} we replace \type {loc} by:
+
+\starttyping
+ ( (1+eps) * arclength(ori--loc) * unitvector(loc-ori) )
+\stoptyping
+
+\stopsection
+
+\startsection[title={Marking angles}]
+
+\index{angles}
+
+A convenient \METAPOST\ macro is \type {unitvector}. When we draw a line segment
+from the origin to the point returned by this macro, the segment has a length of
+1~base point. This macro has a wide range of applications, but some basic
+knowledge of vector algebra is handy. The following lines of \METAPOST\ code
+demonstrate the basics behind unitvectors.
+
+\startbuffer
+pair uv ; pickup pencircle scaled 1mm ; autoarrows := true ;
+draw fullcircle scaled 2cm withcolor .625red ;
+for i=(10,35), (-40,-20), (85,-15) :
+ draw origin--i dashed evenly withcolor .625white ;
+ drawarrow origin--unitvector(i) scaled 1cm withcolor .625yellow ;
+endfor ;
+draw origin withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+The circle has a radius of 1cm, and the three line segments are drawn from the
+origin in the direction of the points that are passed as arguments. Because the
+vector has length of~1, we scale it to the radius to let it touch the circle. By
+setting \type {autoarrows} we make sure that the arrowheads are scaled
+proportionally to the linewidth of 1~mm.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+An application of this macro is drawing the angle between two lines. In the
+\METAPOST\ manual you can find two macros for drawing angles: \type {mark_angle}
+and \type {mark_rt_angle}. You may want to take a look at their definitions
+before we start developing our own alternatives.
+
+\startbuffer[x]
+pickup pencircle scaled 1mm ; autoarrows := true ;
+drawoptions(withcolor .625white) ;
+\stopbuffer
+
+\startbuffer[a]
+def anglebetween (expr a, b) =
+ (unitvector(a){a rotated 90} .. unitvector(b))
+enddef ;
+\stopbuffer
+
+\startbuffer[b]
+pair a, b ; a := (2cm,-1cm) ; b := (3cm,1cm) ;
+drawarrow origin--a ; drawarrow origin--b ;
+drawarrow anglebetween(a,b) scaled 1cm withcolor .625red ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+The previous graphic demonstrates what we want to accomplish: a circular curve
+indicating the angle between two straight lines. The lines and curve are drawn
+with the code:
+
+\typebuffer[b]
+
+where \type {anglebetween} is defined as:
+
+\typebuffer[a]
+
+Both unitvectors return just a point on the line positioned 1~unit (later scaled
+to 1cm) from the origin. We connect these points by a curve that starts in the
+direction at the first point. If we omit the \type {a rotated 90} direction
+specifier, we get:
+
+\startbuffer[a]
+def anglebetween (expr a, b) =
+ (unitvector(a) .. unitvector(b))
+enddef ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+These definitions of \type {anglebetween} are far from perfect. If we don't start
+in the origin, we get the curve in the wrong place and when we swap both points,
+we get the wrong curve.
+
+\startbuffer[a]
+def anglebetween (expr endofa, endofb, common, length) =
+ (unitvector (endofa-common){(endofa-common) rotated 90} ..
+ unitvector (endofb-common)) scaled length shifted common
+enddef ;
+\stopbuffer
+
+\startbuffer[b]
+pair a, b, c ; a := (2cm,-1cm) ; b := (3cm,1cm) ; c := (-1cm,.5cm) ;
+drawarrow c--a ; drawarrow c--b ;
+drawarrow anglebetween(a,b,c,1cm) withcolor .625red ;
+\stopbuffer
+
+The solution for the displacement is given in the \METAPOST\ manual and looks
+like this (we package the macro a bit different):
+
+\typebuffer[a]
+
+As you can see, we compensate for the origin of both vectors. This macro is
+called with a few more parameters. We need to pass the length, since we want to
+add the shift to the macro and the shift takes place after the scaling.
+
+\typebuffer[b]
+
+That the results are indeed correct, is demonstrated by the output of following
+example:
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+However, when we swap the points, we get:
+
+\startbuffer[a]
+def anglebetween (expr endofb, endofa, common, length) =
+ (unitvector (endofa-common){(endofa-common) rotated 90} ..
+ unitvector (endofb-common)) scaled length shifted common
+enddef ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+This means that instead of rotating over $90$ degrees, we have to rotate over
+$-90$ or $270$ degrees. That way the arrow will also point in the other
+direction. There are undoubtedly more ways to determine the direction, but the
+following method also demonstrates the use of \type {turningnumber}, which
+reports the direction of a path. For this purpose we compose a dummy cyclic path.
+
+\startbuffer[a]
+vardef anglebetween (expr endofa, endofb, common, length) =
+ save tn ; tn := turningnumber(common--endofa--endofb--cycle) ;
+show tn ;
+ (unitvector(endofa-common){(endofa-common) rotated (tn*90)} ..
+ unitvector(endofb-common)) scaled length shifted common
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+Because we use an intermediate variable, just to keep things readable, we have to
+use \type {vardef} to hide the assignment for the outside world. We demonstrate
+this macro using the following code:
+
+\startbuffer[b]
+pair a, b, c ; a := (2cm,-1cm) ; b := (3cm,1cm) ; c := (-1cm,.5cm) ;
+drawarrow c--a ; drawarrow c--b ;
+drawarrow anglebetween(a,b,c,0.75cm) withcolor .625red ;
+drawarrow anglebetween(b,a,c,1.50cm) withcolor .625red ;
+\stopbuffer
+
+\typebuffer[b]
+
+Watch how both arrows point in the direction of the line that is determined by
+the second point.
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+We now have the framework of an angle drawing macro ready and can start working
+placing the label.
+
+\startbuffer[a]
+vardef anglebetween (expr endofa, endofb, common, length, str) =
+ save curve, where ; path curve ; numeric where ;
+ where := turningnumber (common--endofa--endofb--cycle) ;
+ curve := (unitvector(endofa-common){(endofa-common) rotated (where*90)}
+ .. unitvector(endofb-common)) scaled length shifted common ;
+ draw thefreelabel(str,point .5 of curve,common) withcolor black ;
+ curve
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+The macro \type {thefreelabel} is part of \METAFUN\ and is explained in detail in
+\in {section} [sec:free labels]. This macro tries to place the label as good as
+possible without user interference.
+
+\startbuffer[b]
+pair a ; a := (2cm,-1cm) ; drawarrow origin--a ;
+pair b ; b := (3cm, 1cm) ; drawarrow origin--b ;
+drawarrow
+ anglebetween(a,b,origin,1cm,btex $\alpha$ etex)
+ withcolor .625red ;
+\stopbuffer
+
+\typebuffer[b]
+
+Instead of a picture we may also pass a string, but using \TEX\ by means of \type
+{btex}||\type {etex} often leads to better results.
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+Because in most cases we want the length to be consistent between figures and
+because passing two paths is more convenient than passing three points, the final
+definition looks slightly different.
+
+\startbuffer[a]
+numeric anglelength ; anglelength := 20pt ;
+
+vardef anglebetween (expr a, b, str) = % path path string
+ save endofa, endofb, common, curve, where ;
+ pair endofa, endofb, common ; path curve ; numeric where ;
+ endofa := point length(a) of a ;
+ endofb := point length(b) of b ;
+ if round point 0 of a = round point 0 of b :
+ common := point 0 of a ;
+ else :
+ common := a intersectionpoint b ;
+ fi ;
+ where := turningnumber (common--endofa--endofb--cycle) ;
+ curve := (unitvector (endofa-common){(endofa-common) rotated (where*90)} ..
+ unitvector (endofb-common)) scaled anglelength shifted common ;
+ draw thefreelabel(str,point .5 of curve,common) withcolor black ;
+ curve
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+This macro has a few more \type {if}'s than its predecessor. First we test if the
+label is a string, and if so, we calculate the picture ourselves, otherwise we
+leave this to the user.
+
+\startbuffer[b]
+path a, b, c, d, e, f ;
+a := origin--( 2cm, 1cm) ; b := origin--( 1cm, 2cm) ;
+c := origin--(-2cm, 2cm) ; d := origin--(-2cm,-1cm) ;
+e := origin--(-1cm,-2cm) ; f := origin--( 1cm,-2cm) ;
+for i=a, b, c, d, e, f : drawarrow i ; endfor ;
+anglelength := 1.0cm ; drawoptions(withcolor .625red) ;
+drawarrow anglebetween(a,b,btex $\alpha $ etex) ;
+drawarrow anglebetween(c,d,btex $\gamma $ etex) ;
+drawarrow anglebetween(e,f,btex $\epsilon$ etex) ;
+anglelength := 1.5cm ; drawoptions(withcolor .625yellow) ;
+drawdblarrow anglebetween(b,c,btex $\beta $ etex) ;
+drawarrow reverse anglebetween(d,e,btex $\delta $ etex) ;
+drawarrow anglebetween(a,f,btex $\zeta $ etex) ;
+\stopbuffer
+
+\typebuffer[b]
+
+Because \type {anglebetween} returns a path, you can apply transformations to it,
+like reversing. Close reading of the previous code learns that the macro handles
+both directions.
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+Multiples of 90 degrees are often identified by a rectangular symbol. We will now
+extend the previously defined macro in such a way that more types can be drawn.
+
+\startbuffer[a]
+numeric anglelength ; anglelength := 20pt ;
+numeric anglemethod ; anglemethod := 1 ;
+
+vardef anglebetween (expr a, b, str) = % path path string
+ save pointa, pointb, common, middle, offset ;
+ pair pointa, pointb, common, middle, offset ;
+ save curve ; path curve ;
+ save where ; numeric where ;
+ if round point 0 of a = round point 0 of b :
+ common := point 0 of a ;
+ else :
+ common := a intersectionpoint b ;
+ fi ;
+ pointa := point anglelength on a ;
+ pointb := point anglelength on b ;
+ where := turningnumber (common--pointa--pointb--cycle) ;
+ middle := ((common--pointa) rotatedaround (pointa,-where*90))
+ intersectionpoint
+ ((common--pointb) rotatedaround (pointb, where*90)) ;
+ if anglemethod = 1 :
+ curve := pointa{unitvector(middle-pointa)}.. pointb;
+ middle := point .5 along curve ;
+ elseif anglemethod = 2 :
+ middle := common rotatedaround(.5[pointa,pointb],180) ;
+ curve := pointa--middle--pointb ;
+ elseif anglemethod = 3 :
+ curve := pointa--middle--pointb ;
+ elseif anglemethod = 4 :
+ curve := pointa..controls middle..pointb ;
+ middle := point .5 along curve ;
+ fi ;
+ draw thefreelabel(str, middle, common) withcolor black ;
+ curve
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startbuffer[p]
+anglemethod := 1 ;
+\stopbuffer
+
+\startbuffer[q]
+anglemethod := 2 ;
+\stopbuffer
+
+\startbuffer[r]
+anglemethod := 3 ;
+\stopbuffer
+
+\startbuffer
+\startcombination[3*1]
+ {\processMPbuffer[x,a,p,b]} {method 1}
+ {\processMPbuffer[x,a,q,b]} {method 2}
+ {\processMPbuffer[x,a,r,b]} {method 3}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:three methods]
+ {Three ways of marking angles.}
+ {\getbuffer}
+
+\in {Figure} [fig:three methods] shows the first three alternative methods
+implemented here. Instead of using \typ {unitvectors}, we now calculate the
+points using the \typ {arctime} and \typ {arclength} primitives. Instead of
+complicated expressions, we use the \METAFUN\ operators \type {along} and \type
+{on}. The following expressions are equivalent.
+
+\starttyping
+pointa := point anglelength on a ;
+middle := point .5 along curve ;
+
+pointa := point (arctime anglelength of a) of a ;
+middle := arctime (.5(arclength curve)) of curve) of curve ;
+\stoptyping
+
+The third method can be implemented in different, more math intensive ways, but
+the current implementation suits rather well and is understood by the author.
+
+\stopsection
+
+\startsection[reference=sec:color circles,title={Color circles}]
+
+\index{color}
+
+In \in {chapter} [sec:embedding] we showed a few color circles. Drawing such a
+graphic can be done in several ways, and here we will show a few methods. First
+we will demonstrate how you can apply \type {cutafter} and \type {cutbefore},
+next we will show how the \METAPOST\ macro \type {buildpath} can be used, and
+finally we will present a clean solution using \type {subpath}. We will assume
+that the circle is called with the macro:
+
+\starttyping
+colorcircle (4cm, red, green, blue) ;
+\stoptyping
+
+\startbuffer[circle]
+vardef colorcircle (expr size, red, green, blue) =
+ save r, g, b, rr, gg, bb, cc, mm, yy ;
+ save b_r, b_g, g_r, g_b ;
+ save radius ;
+
+ path r, g, b, rr, bb, gg, cc, mm, yy ;
+ pair b_r, b_g, g_r, g_b ;
+
+ numeric radius ; radius := 3cm ;
+
+ pickup pencircle scaled (radius/20) ;
+
+ r := g := b := fullcircle scaled radius shifted (0,radius/4);
+
+ r := r rotatedaround(origin, 15) ; % drawarrow r withcolor red ;
+ g := g rotatedaround(origin,135) ; % drawarrow g withcolor green ;
+ b := b rotatedaround(origin,255) ; % drawarrow b withcolor blue ;
+
+ b_r := b intersectionpoint r ; % draw b_r ;
+ b_g := b intersectionpoint g ; % draw b_g ;
+ g_r := reverse g intersectionpoint r ; % draw g_r ;
+ g_b := reverse g intersectionpoint b ; % draw g_b ;
+
+ bb := b cutafter b_r ; bb := bb cutbefore b_g ; % drawarrow bb ;
+ gg := g cutbefore b_g ; gg := gg cutafter g_r ; % drawarrow gg ;
+ rr := r cutbefore g_r & r cutafter b_r ; % drawarrow rr ;
+
+ cc := b cutbefore b_r ; cc := cc cutafter g_b ; % drawarrow br ;
+ yy := g cutbefore g_r ; yy := yy cutafter g_b ; % drawarrow rg ;
+ mm := r cutbefore g_r & r cutafter b_r ; % drawarrow gb ;
+
+ bb := gg -- rr -- reverse bb -- cycle ;
+ gg := bb rotatedaround(origin,120) ;
+ rr := bb rotatedaround(origin,240) ;
+
+ cc := mm -- cc -- reverse yy -- cycle ;
+ yy := cc rotatedaround(origin,120) ;
+ mm := cc rotatedaround(origin,240) ;
+
+ fill fullcircle scaled radius withcolor white ;
+
+ fill rr withcolor red ; fill cc withcolor white-red ;
+ fill gg withcolor green ; fill mm withcolor white-green ;
+ fill bb withcolor blue ; fill yy withcolor white-blue ;
+
+ for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ;
+
+ currentpicture := currentpicture xsized size ;
+enddef ;
+\stopbuffer
+
+We need to calculate seven paths. The first implementation does all the handywork
+itself and thereby is rather long, complicated and unreadable. It does not really
+use the strength of \METAPOST\ yet.
+
+\typebuffer[circle]
+
+In determining the right intersection points, you need to know where the path
+starts and in what direction it moves. In case of doubt, drawing the path as an
+arrow helps. If you want to see the small paths used, you need to comment the
+lines with the \type {fill}'s and uncomment the lines with \type {draw}'s. Due to
+the symmetry and the fact that we keep the figure centered around the origin, we
+only need to calculate two paths since we can rotate them.
+
+There are for sure more (efficient) ways to draw such a figure, but this one
+demonstrates a few new tricks, like grouping. We use grouping here because we
+want to use \type {mm} to indicate the magenta path, and \type {mm} normally
+means millimeter. Within a group, you can save variables. These get their old
+values when the group is left.
+
+With \type {for} we process multiple paths after each other. In this case it
+hardly saves tokens, but it looks more clever.
+
+One of the more efficient methods is using the \type {buildcycle} macro. This
+macro takes two or more paths and calculates the combined path. Although this is
+a rather clever macro, you should be prepared to help it a bit when paths have
+multiple intersection points. Again, we could follow a more secure mathematical
+method, but the next one took only a few minutes of trial and error. To save some
+memory, we redefine the \type {colors} graphic.
+
+\startbuffer[demo]
+colorcircle(4cm, red, green, blue) ;
+\stopbuffer
+
+When we call this macro as:
+
+\typebuffer[demo]
+
+we get:
+
+\startlinecorrection[blank]
+\processMPbuffer[circle,demo]
+\stoplinecorrection
+
+Of course this macro is only used for demonstration purposes and has no real use.
+
+\startbuffer[circle]
+vardef colorcircle (expr size, red, green, blue) =
+ save r, g, b, rr, gg, bb, cc, mm, yy ; save radius ;
+ path r, g, b, rr, bb, gg, cc, mm, yy ; numeric radius ;
+
+ radius := 5cm ; pickup pencircle scaled (radius/25) ;
+
+ r := g := b := fullcircle scaled radius shifted (0,radius/4) ;
+
+ r := r rotatedaround (origin, 15) ;
+ g := g rotatedaround (origin,135) ;
+ b := b rotatedaround (origin,255) ;
+
+ r := r rotatedaround(center r,-90) ;
+ g := g rotatedaround(center g, 90) ;
+
+ gg := buildcycle(buildcycle(reverse r,b),g) ;
+ cc := buildcycle(buildcycle(b,reverse g),r) ;
+
+ rr := gg rotatedaround(origin,120) ;
+ bb := gg rotatedaround(origin,240) ;
+
+ yy := cc rotatedaround(origin,120) ;
+ mm := cc rotatedaround(origin,240) ;
+
+ fill fullcircle scaled radius withcolor white ;
+
+ fill rr withcolor red ; fill cc withcolor white-red ;
+ fill gg withcolor green ; fill mm withcolor white-green ;
+ fill bb withcolor blue ; fill yy withcolor white-blue ;
+
+ for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ;
+
+ currentpicture := currentpicture xsized size ;
+enddef ;
+\stopbuffer
+
+\typebuffer [circle]
+
+Since we don't want to duplicate a graphic, this time we show the dark
+alternatives.
+
+\startbuffer[demo]
+colorcircle(4cm, .5red, .5green, .5blue) ;
+\stopbuffer
+
+\typebuffer[demo]
+
+This kind of unsafe path calculations are very sensitive to breaking. Changing
+the \type {radius/4} into something else demonstrates this but we will not
+challenge this macro that much. Therefore, the 50\% color circle shows up as:
+
+\startlinecorrection[blank]
+\processMPbuffer[circle,demo]
+\stoplinecorrection
+
+This command is part of \METAFUN\ and can be used to determine nice color
+combinations by also looking at their complementary colors.
+
+\startbuffer[demo]
+colorcircle (4cm, .7red, .5green, .3blue) ;
+\stopbuffer
+
+\typebuffer[demo]
+
+\startlinecorrection[blank]
+\processMPbuffer[circle,demo]
+\stoplinecorrection
+
+The next circle that we draw shows the three main colors used in this document.
+This circle is not that beautiful.
+
+\startbuffer[demo]
+colorcircle(4cm,.625red,.625yellow,.625white) ;
+\stopbuffer
+
+\typebuffer[demo]
+
+\startlinecorrection[blank]
+\processMPbuffer[circle,demo]
+\stoplinecorrection
+
+This definition can be cleaned up a bit by using \type {transform}, but the fuzzy
+\type {buildcycle}'s remain.
+
+\startbuffer[circle]
+vardef colorcircle (expr size, red, green, blue) =
+ save r, g, b, rr, gg, bb, cc, mm, yy ; save radius ;
+ path r, g, b, rr, bb, gg, cc, mm, yy ; numeric radius ;
+
+ radius := 5cm ; pickup pencircle scaled (radius/25) ;
+
+ transform t ; t := identity rotatedaround(origin,120) ;
+
+ r := fullcircle scaled radius
+ shifted (0,radius/4) rotatedaround(origin,15) ;
+
+ g := r transformed t ; b := g transformed t ;
+
+ r := r rotatedaround(center r,-90) ;
+ g := g rotatedaround(center g, 90) ;
+
+ gg := buildcycle(buildcycle(reverse r,b),g) ;
+ cc := buildcycle(buildcycle(b,reverse g),r) ;
+
+ rr := gg transformed t ; bb := rr transformed t ;
+ yy := cc transformed t ; mm := yy transformed t ;
+
+ fill fullcircle scaled radius withcolor white ;
+
+ fill rr withcolor red ; fill cc withcolor white-red ;
+ fill gg withcolor green ; fill mm withcolor white-green ;
+ fill bb withcolor blue ; fill yy withcolor white-blue ;
+
+ for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ;
+
+ currentpicture := currentpicture xsized size ;
+enddef ;
+\stopbuffer
+
+\typebuffer [circle]
+
+\startbuffer[demo]
+colorcircle(4cm,(.4,.6,.8),(.8,.4,.6),(.6,.8,.4));
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[circle,demo]
+\stoplinecorrection
+
+This rather nice circle is defined as:
+
+\typebuffer[demo]
+
+The final implementation, which is part of \METAFUN, is slightly more efficient.
+
+\startbuffer[circle]
+vardef colorcircle (expr size, red, green, blue) =
+ save r, g, b, c, m, y, w ; save radius ;
+ path r, g, b, c, m, y, w ; numeric radius ;
+
+ radius := 5cm ; pickup pencircle scaled (radius/25) ;
+
+ transform t ; t := identity rotatedaround(origin,120) ;
+
+ r := fullcircle rotated 90 scaled radius
+ shifted (0,radius/4) rotatedaround(origin,135) ;
+
+ b := r transformed t ; g := b transformed t ;
+
+ c := buildcycle(subpath(1,7) of g, subpath(1,7) of b) ;
+ y := c transformed t ; m := y transformed t ;
+
+ w := buildcycle(subpath(3,5) of r,
+ subpath(3,5) of g, subpath(3,5) of b) ;
+
+ pushcurrentpicture ;
+
+ fill r withcolor red ;
+ fill g withcolor green ;
+ fill b withcolor blue ;
+ fill c withcolor white-red ;
+ fill m withcolor white-green ;
+ fill y withcolor white-blue ;
+ fill w withcolor white ;
+
+ for i = r,g,b,c,m,y : draw i withcolor .5white ; endfor ;
+
+ currentpicture := currentpicture xsized size ;
+
+ popcurrentpicture ;
+enddef ;
+\stopbuffer
+
+\typebuffer [circle]
+
+Here, we first fill the primary circles, next we fill the secondary ones. These
+also cover the center, which is why finally we fill the center with white.
+
+\startbuffer[demo]
+colorcircle(4cm,(.2,.5,.8),(.8,.2,.5),(.5,.8,.2));
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[circle,demo]
+\stoplinecorrection
+
+The circle uses the following colors:
+
+\typebuffer[demo]
+
+The next graphic demonstrates how the subpaths look that build the shapes.
+
+\startbuffer[circle]
+vardef colorcircle (expr size, red, green, blue) =
+ save r, g, b, c, m, y, w ; save radius ;
+ path r, g, b, c, m, y, w ; numeric radius ;
+
+ radius := 5cm ; pickup pencircle scaled (radius/25) ;
+
+ transform t ; t := identity rotatedaround(origin,120) ;
+
+ r := fullcircle rotated 90 scaled radius
+ shifted (0,radius/4) rotatedaround(origin,135) ;
+
+ b := r transformed t ; g := b transformed t ;
+
+ c := buildcycle(subpath(1,7) of g,subpath(1,7) of b) ;
+ y := c transformed t ; m := y transformed t ;
+
+ w := buildcycle(subpath(3,5) of r,
+ subpath(3,5) of g, subpath(3,5) of b) ;
+
+ pushcurrentpicture ;
+
+ def do_it =
+ fill r withcolor red ;
+ fill g withcolor green ;
+ fill b withcolor blue ;
+ fill c withcolor white-red ;
+ fill m withcolor white-green ;
+ fill y withcolor white-blue ;
+ fill w withcolor white ;
+ for i = r,g,b,c,m,y : draw i withcolor .5white ; endfor ;
+ enddef ;
+
+ autoarrows := true ;
+
+ do_it ;
+ for i=r,g,b : drawarrow i withcolor black ; endfor ;
+ currentpicture := currentpicture shifted (-2radius,0) ;
+
+ do_it ;
+ for i=r,g,b : drawarrow subpath(1,7) of i withcolor black ; endfor ;
+ currentpicture := currentpicture shifted (-2radius,0) ;
+
+ do_it ;
+ for i=r,g,b : drawarrow subpath(3,5) of i withcolor black ; endfor ;
+ currentpicture := currentpicture shifted (+4radius,2radius) ;
+
+ drawarrow r withpen pencircle scaled (radius/10) withcolor red ;
+ drawarrow g withpen pencircle scaled (radius/20) withcolor green ;
+ drawarrow b withpen pencircle scaled (radius/40) withcolor blue ;
+ currentpicture := currentpicture shifted (-2radius,0) ;
+
+ drawarrow c withpen pencircle scaled (radius/10) withcolor white-red ;
+ drawarrow m withpen pencircle scaled (radius/20) withcolor white-green ;
+ drawarrow y withpen pencircle scaled (radius/40) withcolor white-blue ;
+ currentpicture := currentpicture shifted (-2radius,0) ;
+
+ drawarrow w withcolor black ;
+
+ currentpicture := currentpicture xsized 3size ;
+
+ popcurrentpicture ;
+enddef ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[circle,demo]
+\stoplinecorrection
+
+We did not mention what the push and pop commands are responsible for. Scaling
+the current picture is well defined as long as we deal with one graphic. However,
+if the current picture already has some content, this content is also scaled. The
+push and pop commands let us add content to the current picture as well as
+manipulating the picture as a whole without any side effects. The final result is
+put on top of the already drawn content. Instead of the sequence:
+
+\starttyping
+pushcurrentpicture ;
+ ...
+ currentpicture := currentpicture ... transformations ... ;
+popcurrentpicture ;
+\stoptyping
+
+you can say:
+
+\starttyping
+pushcurrentpicture ;
+ ...
+popcurrentpicture ... transformations ... ;
+\stoptyping
+
+Both are equivalent to:
+
+\starttyping
+draw image ( ... ) ... transformations ... ;
+\stoptyping
+
+For larger sequences of commands, the push||pop alternative gives a bit more more
+readable code.
+
+\stopsection
+
+\startsection[title={Fool yourself}]
+
+When doing a literature search on the human perception of black||white edges, I
+ran into several articles with graphics that I remember having seen before in
+books on psychology, physiology and|/|or ergonomics. One of the articles was by
+Edward H.~Adelson of MIT and we will use a few of his example graphics in our
+exploration to what extend \METAPOST\ can be of help in those disciplines. Since
+such graphics normally occur in typeset documents, we will define them in the
+document source.
+
+\startbuffer[a]
+\startbuffer
+interim linecap := butt ; numeric u ; u := 1cm ;
+pickup pencircle scaled .5u ;
+for i=1u step u until 5u :
+ draw (0,i) -- (5u,i) ;
+endfor ;
+for i=2u step u until 4u :
+ draw (u,i) -- (2u,i) withcolor .5white ;
+ draw ((3u,i) -- (4u,i)) shifted (0,-.5u) withcolor .5white ;
+endfor ;
+\stopbuffer
+\stopbuffer
+
+\startbuffer[b]
+\placefigure
+ [here][fig:tricked 1]
+ {White's illusion.}
+ {\processMPbuffer}
+\stopbuffer
+
+\getbuffer[a,b]
+
+Unless you belong to the happy few whose visual capabilities are not distorted by
+neural optimizations, in \in {figure} [fig:tricked 1] the gray rectangles at the
+left look lighter than those on the right. Alas, you can fool yourself, but
+\METAPOST\ does not cheat. This graphic, referred to as White's illusion, is
+defined as follows.
+
+\typebuffer[a]
+
+Watch how we include the code directly. We have packaged this graphic in a buffer
+which we include as a floating figure.
+
+\typebuffer[b]
+
+When passed to \METAPOST, this code is encapsulated in its \type {beginfig} and
+\type {endfig} macros and thereby grouped. But any change to a variable that is
+not explicitly saved, migrates to the outer level. In order to prevent all
+successive graphics to have butt'd linecaps, we have to change this line
+characteristic locally. Because \type {linecap} is defined as an internal
+variable, we have to use \type {interim} to overload its value. Because \type {u}
+is a rather commonly used scratch variable, we don't save its value.
+
+Watch how we use \type {u} as the loop step. In spite of what your eyes tell you,
+this graphic only has two explicit color directives, both being 50\% black. In
+the next example we will use some real colors.
+
+\startbuffer[a]
+\startuseMPgraphic{first}
+ numeric size, delta ;
+ size := 2.5cm ; delta := size/3 ;
+ color mainshade, topshade, bottomshade, centershade ;
+ mainshade := \MPcolor{funcolor} ;
+ topshade := .9mainshade ; bottomshade := .5mainshade ;
+ centershade := .5[topshade,bottomshade] ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[b]
+\startuseMPgraphic{second}
+ \includeMPgraphic{first}
+ fill fullsquare scaled size withcolor topshade ;
+ fill fullsquare scaled delta withcolor centershade ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[c]
+\startuseMPgraphic{third}
+ \includeMPgraphic{first}
+ fill fullsquare scaled size withcolor bottomshade ;
+ fill fullsquare scaled delta withcolor centershade ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer[a,b,c]
+
+\startbuffer[d]
+\startcombination[5*2]
+ {\definecolor[funcolor][red] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][green] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][blue] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][yellow]\useMPgraphic{second}} {}
+ {\definecolor[funcolor][white] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][red] \useMPgraphic{third}} {}
+ {\definecolor[funcolor][green] \useMPgraphic{third}} {}
+ {\definecolor[funcolor][blue] \useMPgraphic{third}} {}
+ {\definecolor[funcolor][yellow]\useMPgraphic{third}} {}
+ {\definecolor[funcolor][white] \useMPgraphic{third}} {}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:tricked 2]
+ {The simultaneous contrast effect.}
+ {\getbuffer[d]}
+
+In \in {figure} [fig:tricked 2] the small squares in the center of each colored
+pair of big squares have the same shade, but the way we perceive them are
+influenced by their surroundings. Both sets of squares are defined using usable
+graphics. The top squares are defined as:
+
+\typebuffer[b]
+
+and the bottom squares are coded as:
+
+\typebuffer[c]
+
+Because both graphics share code, we have defined that code as a separate
+graphic, that we include. The only point of interest in this definition is the
+fact that we let \METAPOST\ interpolate between the two colors using \type {.5[
+]}.
+
+\typebuffer[a]
+
+The color \type {funcolor} is provided by \CONTEXT, and since we want to use this
+graphic with different colors, this kind of mapping is quite convenient. The
+bunch of graphics is packaged in a combination with empty captions. Note how we
+set the color before we include the graphic.
+
+\typebuffer[d]
+
+We use a similar arrangement for the following graphic, where we have replaced
+the definitions of \type {first}, \type {second} and \type {third} by new
+definitions.
+
+\startbuffer[a]
+\startuseMPgraphic{first}
+ numeric height, width, radius, gap ; gap := 1mm ;
+ height = 2.5cm ; width := height/2 ; radius := height/2.5 ;
+ color mainshade, leftshade, rightshade, centershade ;
+ mainshade := \MPcolor{funcolor} ;
+ leftshade := .9mainshade ; rightshade := .5mainshade ;
+ centershade := .5[leftshade,rightshade] ;
+ fill unitsquare xyscaled ( width,height) withcolor leftshade ;
+ fill unitsquare xyscaled (-width,height) withcolor rightshade ;
+ draw (fullcircle scaled radius) shifted (0,height/2)
+ withpen pencircle scaled (radius/2) withcolor centershade ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[b]
+\startuseMPgraphic{second}
+ \includeMPgraphic{first}
+ interim linecap := butt ; pickup pencircle scaled gap ;
+ draw (0,0) -- (0,height) withcolor white ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[c]
+\startuseMPgraphic{third}
+ \includeMPgraphic{first}
+ picture p, q ; p := q := currentpicture ;
+ clip p to unitsquare xscaled width yscaled height ;
+ clip q to unitsquare xscaled -width yscaled height ;
+ currentpicture := p ;
+ addto currentpicture also q shifted (0,radius/2) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer[a,b,c]
+
+\startbuffer[d]
+\startcombination[5*3]
+ {\definecolor[funcolor][red] \useMPgraphic{first}} {}
+ {\definecolor[funcolor][green] \useMPgraphic{first}} {}
+ {\definecolor[funcolor][blue] \useMPgraphic{first}} {}
+ {\definecolor[funcolor][yellow]\useMPgraphic{first}} {}
+ {\definecolor[funcolor][white] \useMPgraphic{first}} {}
+ {\definecolor[funcolor][red] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][green] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][blue] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][yellow]\useMPgraphic{second}} {}
+ {\definecolor[funcolor][white] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][red] \useMPgraphic{third}} {}
+ {\definecolor[funcolor][green] \useMPgraphic{third}} {}
+ {\definecolor[funcolor][blue] \useMPgraphic{third}} {}
+ {\definecolor[funcolor][yellow]\useMPgraphic{third}} {}
+ {\definecolor[funcolor][white] \useMPgraphic{third}} {}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:tricked 3]
+ {Koffka's examples of manipulating contrast by changing
+ the spatial configuration.}
+ {\getbuffer[d]}
+
+The definition of the first row of \in {figure} [fig:tricked 3] is used in the
+second and third and therefore is the most complicated. We use quite some scratch
+variables to reach a high level of abstraction. The \type {xyscaled} operator is
+a \METAFUN\ macro.
+
+\typebuffer[a]
+
+The graphics of the second row extends those of the first by drawing a white line
+through the middle. In this example setting the linecap is not really needed,
+because rounded top and bottoms in white are invisible and the part that extends
+beyond the points does not count in calculating the bounding box.
+
+\typebuffer[b]
+
+The third row graphics again extend the first graphic. First we copy the picture
+constructed so far. Watch the double assignment. Next we clip the pictures in
+half, and shift the right half down over the width of the circle.
+
+\typebuffer[c]
+
+\stopsection
+
+% \startsection[title={Puzzles}]
+%
+% {\em Maybe.}
+%
+% \stopsection
+%
+% \startsection[title={Flow charts}]
+%
+% {\em Instead of starting anew every time, you can use predefined macros, like
+% those in the flow chart module. Let's see how we can influence the \METAPOST\
+% code. Maybe not here.}
+%
+% \stopsection
+%
+% \startsection[title={Chemistry}]
+%
+% {\em \METAPOST\ can do it's work unseen, as in the chemistry module that comes
+% with \CONTEXT. There, \METAPOST\ is used as one of the graphical plug||ins. It
+% demonstrates that we can put \METAPOST\ to work without seeing any code.}
+%
+% \stopsection
+
+\startsection[title={Growing graphics}]
+
+Although \METAPOST\ is not really suited as a simulation engine, it is possible
+to build graphics that are built and displayed incrementally with a sequence of
+mouse clicks. The following example is the result of an email discussion David
+Arnold and the author had while \METAFUN\ evolved.
+
+Instead of defining the graphics in a separate \METAPOST\ file, we will
+incorporate them in the document source in which they are used. We can use
+several methods.
+
+\startitemize[n]
+\startitem
+ Define macros and figures in a separate file and include the graphics as
+ external graphics.
+\stopitem
+\startitem
+ Define everything in the document source as usable graphics and include the
+ graphics using \type {\useMPgraphic}.
+\stopitem
+\startitem
+ Package the graphic components in buffers and paste those together as
+ graphics that can be processed at run time.
+\stopitem
+\stopitemize
+
+The first method is the most independent one, which has its advantages if we want
+to use the graphics in other applications too. The second method works well in
+graphics where parts of the definitions change between invocations of the
+graphic. This method follows the template:
+
+\starttyping
+\startuseMPgraphic{whatever}
+ ...
+\stopuseMPgraphic
+
+\startuseMPgraphic{result}
+ ...
+ \includeMPgraphic{whatever}
+ ...
+\stopuseMPgraphic
+
+\useMPgraphic{result}
+\stoptyping
+
+The disadvantage of this method is that it cannot be combined with \type
+{btex}||\type {etex} since it is nearly impossible to determine when, how, and to
+what extent the content of a graphic should be expanded before writing it to the
+temporary \METAPOST\ file.
+
+Therefore, we will demonstrate how buffers can be used. This third method closely
+parallels the first way of defining graphics. A nice side effect is that we can
+easily typeset these buffers verbatim, which we did to typeset this document.
+
+We are going to do a classic compass and straightedge construction, the bisection
+of a line segment joining two arbitrary points. We will construct five graphics,
+where each one displays one step of the construction. We will embed each graphic
+in a start||stop command. Later we will see the advantage of this strategy.
+
+\startbuffer
+\startbuffer[a]
+def start_everything = enddef ;
+def stop_everything = enddef ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startbuffer[b]
+numeric u, w ; u := .5cm ; w := 1pt ;
+
+pickup pencircle scaled w ;
+
+def draw_dot expr p =
+ draw p withpen pencircle scaled 3w ;
+enddef ;
+
+def stand_out =
+ drawoptions(withcolor .625red) ;
+enddef ;
+\stopbuffer
+\stopbuffer
+
+We are going to draw a few dots, and to force consistency we first define a macro
+\type {draw_dot}. The current step will be highlighted in red using \type
+{stand_out}.
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startbuffer[c]
+def draw_basics =
+ pair pointA, pointB ; path lineAB ;
+ pointA := origin ; pointB := pointA shifted (5u,0) ;
+ lineAB := pointA -- pointB ;
+ draw lineAB ;
+ draw_dot pointA ; label.lft(btex A etex, pointA) ;
+ draw_dot pointB ; label.rt (btex B etex, pointB) ;
+enddef ;
+\stopbuffer
+\stopbuffer
+
+First, we construct the macro that will plot two points $A$ and $B$ and connect
+them with a line segment.
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startbuffer[1]
+start_everything ;
+ stand_out ; draw_basics ;
+stop_everything ;
+\stopbuffer
+\stopbuffer
+
+The code in this buffer executes the preceding macros. The \type {..._everything}
+commands are still undefined, but later we can use these hooks for special
+purposes.
+
+\typebuffer \getbuffer
+
+This graphic can now be embedded by the \CONTEXT\ command
+\type {\processMPbuffer}. This command, like the ordinary
+buffer inclusion commands, accepts a list of buffers.
+
+\startbuffer
+\startlinecorrection[blank]
+\ruledhbox{\processMPbuffer[a,b,c,1]}
+\stoplinecorrection
+\stopbuffer
+
+\typebuffer
+
+We use \type {\ruledhbox} to show the tight bounding box of the graphic. The line
+correction takes care of proper spacing around non textual content, like
+graphics. \footnote {These spacing commands try to get the spacing around the
+content visually compatible, and take the height and depth of the preceding and
+following text into account.} This is only needed when the graphic is part of the
+text flow!
+
+\getbuffer
+
+Next, we draw two circles of equal radius, one centered at point $A$, the other
+at point $B$.
+
+\startbuffer
+\startbuffer[d]
+def draw_circles =
+ path circleA, circleB ; numeric radius, distance ;
+ distance := (xpart pointB) - (xpart pointA) ;
+ radius := 2/3 * distance ;
+ circleA := fullcircle scaled (2*radius) ;
+ circleB := circleA shifted pointB ;
+ draw circleA ;
+ draw circleB ;
+enddef ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startbuffer[2]
+start_everything ;
+ draw_basics ; stand_out ; draw_circles ;
+stop_everything ;
+\stopbuffer
+\stopbuffer
+
+As you can see, we move down the \type {stand_out} macro so that only the
+additions are colored red.
+
+\typebuffer \getbuffer
+
+We now use \type{\processMPbuffer[a,b,c,d,2]} to include the latest step.
+
+\startlinecorrection[blank]
+\ruledhbox{\processMPbuffer[a,b,c,d,2]}
+\stoplinecorrection
+
+The next step in the construction of the perpendicular bisector requires that we
+find and label the points of intersection of the two circles centered at points
+$A$ and $B$. The intersection points are calculated as follows. Watch the \type
+{reverse} operation, which makes sure that we get the second intersection point.
+
+\startbuffer
+\startbuffer[e]
+def draw_intersection =
+ pair pointC, pointD ;
+ pointC := circleA intersectionpoint circleB ;
+ pointD := (reverse circleA) intersectionpoint (reverse circleB) ;
+ draw_dot pointC ; label.lft(btex C etex, pointC shifted (-2w,0)) ;
+ draw_dot pointD ; label.lft(btex D etex, pointD shifted (-2w,0)) ;
+enddef ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startbuffer[3]
+start_everything ;
+ draw_basics ; draw_circles ; stand_out ; draw_intersection ;
+stop_everything ;
+\stopbuffer
+\stopbuffer
+
+In placing the label, we must make sure that the text runs free of the lines and
+curves. Again, move the \type {stand_out} macro just prior to \type
+{draw_intersection} macro, so that this step is highlighted in the drawing color,
+while prior steps are drawn in the default color (in this case black).
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\ruledhbox{\processMPbuffer[a,b,c,d,e,3]}
+\stoplinecorrection
+
+The line drawn through points $C$ and $D$ will be the perpendicular bisector of
+the line segment connecting points $A$ and $B$. In the next step we will draw a
+line using the plain \METAPOST\ \type {drawdblarrow} macro that draws arrowheads
+at each end of a path.
+
+\startbuffer
+\startbuffer[f]
+def draw_bisector =
+ path lineCD ;
+ lineCD := origin -- origin shifted (2*distance,0) ;
+ lineCD := lineCD rotated 90 shifted 0.5[pointA,pointB] ;
+ lineCD := lineCD shifted (0,-distance) ;
+ drawdblarrow lineCD ;
+enddef ;
+\stopbuffer
+
+\startbuffer[4]
+start_everything ;
+ draw_basics ; draw_circles ; draw_intersection ; stand_out ;
+ draw_bisector ;
+stop_everything ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\ruledhbox{\processMPbuffer[a,b,c,d,e,f,4]}
+\stoplinecorrection
+
+The following code draws the intersection of line $C-D$ and line segment $A-B$,
+which can be shown to be the midpoint of segment $A-B$.
+
+\startbuffer
+\startbuffer[g]
+def draw_midpoint =
+ pair pointM ;
+ pointM := lineCD intersectionpoint lineAB ;
+ draw_dot pointM ; label.llft(btex M etex, pointM) ;
+enddef ;
+\stopbuffer
+
+\startbuffer[5]
+start_everything ;
+ draw_basics ; draw_circles ; draw_intersection ; draw_bisector ;
+ stand_out ; draw_midpoint ;
+stop_everything ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\ruledhbox{\processMPbuffer[a,b,c,d,e,f,g,5]}
+\stoplinecorrection
+
+As long as we place the graphics as individual insertions in our document,
+everything is fine. However, if we wish to place them all at once, or as we shall
+see later, place them on top of one another in a fieldstack, it makes sense to
+give them all the same bounding box. We can do this by completing the \type
+{start_everything} and \type {stop_everything} commands.
+
+\startbuffer
+\startbuffer[a]
+def start_everything =
+ path bb ;
+ draw_basics ;
+ draw_circles ;
+ draw_intersection ;
+ draw_bisector ;
+ draw_midpoint ;
+ bb := boundingbox currentpicture ;
+ currentpicture := nullpicture ;
+enddef ;
+
+def stop_everything =
+ setbounds currentpicture to bb ;
+enddef ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer \getbuffer
+
+In \in {figure} [fig:1 till 5] we demonstrate the effect of this redefinition.
+For this purpose we scale down the graphic to a comfortable 40\%, of course by
+using an additional buffer. We also visualize the bounding box.
+
+\startbuffer
+\startbuffer[h]
+def stop_everything =
+ setbounds currentpicture to bb ;
+ draw bb withpen pencircle scaled .5pt withcolor .625yellow ;
+ currentpicture := currentpicture scaled .4 ;
+enddef ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The graphic itself is defined as follows. Watch how we use the default buffer to
+keep the definitions readable.
+
+\startbuffer
+\startbuffer
+\startcombination[5*1]
+ {\processMPbuffer[a,b,c,h,d,e,f,g,1]} {step 1}
+ {\processMPbuffer[a,b,c,h,d,e,f,g,2]} {step 2}
+ {\processMPbuffer[a,b,c,h,d,e,f,g,3]} {step 3}
+ {\processMPbuffer[a,b,c,h,d,e,f,g,4]} {step 4}
+ {\processMPbuffer[a,b,c,h,d,e,f,g,5]} {step 5}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:1 till 5]
+ {The five graphics, each with the same bounding box.}
+ {\getbuffer}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+As the original purpose of these graphics was not to show them side by side, but
+to present them as field stack in a document to be viewed at the computer screen.
+For this purpose we have to define the graphics as symbols.
+
+\startbuffer
+\definesymbol[step 1][{\processMPbuffer[a,b,c,d,e,f,g,1]}]
+\definesymbol[step 2][{\processMPbuffer[a,b,c,d,e,f,g,2]}]
+\definesymbol[step 3][{\processMPbuffer[a,b,c,d,e,f,g,3]}]
+\definesymbol[step 4][{\processMPbuffer[a,b,c,d,e,f,g,4]}]
+\definesymbol[step 5][{\processMPbuffer[a,b,c,d,e,f,g,5]}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+A field stack is a sequence of overlayed graphics. We will arrange these to cycle
+manually, with clicks of the mouse, through the sequence of graphs depicting the
+construction of the midpoint of segment $A-B$. So, in fact we are dealing with a
+manual simulation. The definition of such a stack is as follows:
+
+\startbuffer
+\definefieldstack
+ [midpoint construction]
+ [step 1, step 2, step 3, step 4, step 5]
+ [frame=on,offset=3pt,framecolor=darkyellow,rulethickness=1pt]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The first argument is to be a unique identifier, the second argument takes a list
+of symbols, while the third argument accepts settings. More on this command can
+be found in the \CONTEXT\ manuals.
+
+The stack is shown as \in {figure} [fig:steps]. Its caption provides a button,
+which enables the reader to cycle through the stack. We call this a stack because
+the graphics are positioned on top of each other. Only one of them is visible at
+any time.
+
+\startbuffer
+\placefigure
+ [here][fig:steps]
+ {Bisecting a line segment with compass and straightedge? Just
+ click \goto {here} [JS(Walk_Field{midpoint construction})] to
+ walk through the construction! (This stack is only visible
+ in a \PDF\ viewer that supports widgets.)}
+ {\framed{\startoverlay
+ {\symbol[step 1]}
+ {\fieldstack[midpoint construction]}
+ \stopoverlay}}
+\stopbuffer
+
+\typebuffer
+
+We cheat a bit and overlay the stack over the first symbol because otherwise
+nothing shows up in print (nowadays I mostly use sumatrapdf).
+
+{\setupinteraction[color=darkred,contrastcolor=darkred]\getbuffer}
+
+At the start of this section, we mentioned three methods. When we use the first
+method of putting all the graphics in an external \METAPOST\ file, the following
+framework suits. We assume that the file is called \type {step.mp} and that it is
+kept by the user along with his document source. We start with the definitions of
+the graphic steps. These are the same as the ones shown previously.
+
+\starttyping
+def draw_basics = ... enddef ;
+def draw_circles = ... enddef ;
+def draw_intersection = ... enddef ;
+def draw_bisector = ... enddef ;
+def draw_midpoint = ... enddef ;
+def stand_out = ... enddef ;
+\stoptyping
+
+We can safe some code by letting the \type {..._everything} take care of the
+\type {beginfig} and \type {endfig} macros.
+
+\starttyping
+def start_everything (expr n) = beginfig(n) ; ... enddef ;
+def stop_everything = ... ; endfig ; enddef ;
+\stoptyping
+
+The five graphics now become:
+
+\starttyping
+start_everything (1) ;
+ stand_out ; draw_basics ;
+stop_everything ;
+
+start_everything (2) ;
+ draw_basics ; stand_out ; draw_circles ;
+stop_everything ;
+
+start_everything (3) ;
+ draw_basics ; draw_circles ; stand_out ; draw_intersection ;
+stop_everything ;
+
+start_everything (4) ;
+ draw_basics ; draw_circles ; draw_intersection ; stand_out ;
+ draw_bisector ;
+stop_everything ;
+
+start_everything (5) ;
+ draw_basics ; draw_circles ; draw_intersection ; draw_bisector ;
+ stand_out ; draw_midpoint ;
+stop_everything ;
+\stoptyping
+
+The definitions of the symbols now refer to an external
+figure.
+
+\starttyping
+\definesymbol[step 1][{\externalfigure[step.1]}]
+\definesymbol[step 2][{\externalfigure[step.2]}]
+\definesymbol[step 3][{\externalfigure[step.3]}]
+\definesymbol[step 4][{\externalfigure[step.4]}]
+\definesymbol[step 5][{\externalfigure[step.5]}]
+\stoptyping
+
+Which method is used, depends on the way the graphics are used. In this example
+we wanted to change the definition of \type {..._everything}, so here the third
+method was quite useful.
+
+\stopsection
+
+\startsection[title={Simple Logos}]
+
+\startbuffer[ns]
+numeric width, height, line, delta ;
+width = 5cm ; height = width/2 ; line = height/4 ; delta = line ;
+
+linejoin := mitered ; pickup pencircle scaled line ;
+
+color nsblue ; nsblue := (0,0,1) ;
+color nsyellow ; nsyellow := (1,1,0) ;
+
+z1 = (0, height/2) ;
+z2 = (width/2-height/4, y1) ;
+z3 = (width/2+height/4, y4) ;
+z4 = (width, 0) ;
+
+z5 = (x4+height/2, y1) ;
+z6 = (x4, 2y1) ;
+z7 = 1.5[z5,z6] ;
+
+path p ; p := z1--z2--z3--z4 ; path q ; q := z3--z4--z5--z7 ;
+
+numeric d, lx, ly, ux, uy ; d = line/2 ;
+
+lx = -3d - d/3 ; ly = -d ; ux = rt x5 + d/3 ; uy = top y6 ;
+
+path r ; r := (lx,ly)--(ux,ly)--(ux,uy)--(lx,uy)--cycle;
+
+lx := lx-delta ; ly := ly-delta ; ux := ux+delta ; uy := uy+delta ;
+
+path s ; s := (lx,ly)--(ux,ly)--(ux,uy)--(lx,uy)--cycle;
+
+draw p withcolor nsblue ; draw q withcolor nsblue ;
+
+addto currentpicture also currentpicture
+ rotatedaround (.5[z2,z3],180) shifted (height/4,height/2) ;
+
+picture savedpicture ; savedpicture := currentpicture ;
+
+clip currentpicture to r ;
+setbounds currentpicture to r ;
+
+savedpicture := currentpicture ; currentpicture := nullpicture ;
+
+fill s withcolor nsyellow ;
+addto currentpicture also savedpicture ;
+\stopbuffer
+
+Many company logos earn their beauty from their simplicity. One of the logos that
+most Dutch people have imprinted in their mind is that of the Dutch Railway
+Company (NS). An interesting feature of this logo is that, although it is widely
+known, drawing it on a piece of paper from mind is a task that many people fail.
+
+\startlinecorrection[blank]
+\processMPbuffer[ns]
+\stoplinecorrection
+
+This logo makes a good candidate for demonstrating a few fine points of drawing
+graphics, like using linear equations, setting line drawing characteristics,
+clipping and manipulating bounding boxes.
+
+The implementation below is quite certainly not according to the official
+specifications, but it can nevertheless serve as an example of defining such
+logos.
+
+\startbuffer[a]
+numeric width ; width = 3cm ;
+numeric height ; height = width/2 ;
+numeric line ; line = height/4 ;
+\stopbuffer
+
+As always, we need to determine the dimensions first. Here, both the height and
+line width depend on the width of the graphic.
+
+Instead of calculating the blue shape such that it will be a filled outline, we
+will draw the logo shape using line segments. This is why we need the \type
+{line} parameter.
+
+\typebuffer[a]
+
+We want sharp corners which can be achieved by setting \type {linejoin} to \type
+{mitered}.
+
+\startbuffer[b]
+linejoin := mitered ; pickup pencircle scaled line ;
+\stopbuffer
+
+\typebuffer[b]
+
+The colors are rather primary blue and yellow. At the time of writing this
+manual, Dutch trains are still painted yellow, so we will use that shade as
+background color.
+
+\startbuffer[c]
+color nsblue ; nsblue := (0,0,1) ;
+color nsyellow ; nsyellow := (1,1,0) ;
+\stopbuffer
+
+\typebuffer[c]
+
+We will now describe the main curves. Although these expressions are not that
+advanced, they demonstrate that we can express relationships instead of using
+assignments.
+
+\startbuffer[d]
+z1 = (0, height/2) ;
+z2 = (width/2-height/4, y1) ;
+z3 = (width/2+height/4, y4) ;
+z4 = (width, 0) ;
+
+path p ; p := z1--z2--z3--z4 ;
+\stopbuffer
+
+\typebuffer[d]
+
+Although it is accepted to consider \type {z} to be a variable, it is in fact a
+\type {vardef} macro, that expands into a pair \type {(x,y)}. This means that the
+previous definitions internally become:
+
+\starttyping
+(x1,y1) = (0, height/2) ;
+(x2,y2) = (width/2-height/4, y1) ;
+(x3,y3) = (width/2+height/4, y4) ;
+(x4,y4) = (width, 0) ;
+\stoptyping
+
+These 8 relations can be solved by \METAPOST, since all dependencies are known.
+
+\starttyping
+x1 = 0 ; y1 = height/2 ;
+x2 = width/2-height/4 ; y2 = y1 ;
+x3 = width/2+height/4 ; y3 = y4 ;
+x4 = width ; y4 = 0 ;
+\stoptyping
+
+Since we express the variables \type {x} and \type {y} in terms of relations, we
+cannot reuse them, because that would mean that inconsistent relations occur. So,
+the following lines will lead to an error message:
+
+\starttyping
+z1 = (10,20) ; z1 = (30,50) ;
+\stoptyping
+
+For similar reasons, we may not assign a value (using \type {:=}) to such a \type
+{z} variable. Within a \METAPOST\ figure, \type {z} variables are automatically
+saved, which means that they can be reused for each figure.
+
+\startbuffer[x]
+drawpath p ; drawpoints p ; drawpointlabels p ;
+\stopbuffer
+
+So far, we have defined the following segment of the logo.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,x]
+\stoplinecorrection
+
+\startbuffer[e]
+z5 = (x4+height/2, y1) ;
+z6 = (x4, 2y1) ;
+z7 = 1.5[z5,z6] ;
+
+path q ; q := z3--z4--z5--z7 ;
+\stopbuffer
+
+The next expressions are used to define the second segment. The third expression
+determines \type {z7} to be positioned on the line \type {z5--z6}, where we
+extend this line by 50\%.
+
+\typebuffer[e]
+
+\startbuffer[x]
+drawpath q ; drawpoints q ; drawpointlabels q ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,x]
+\stoplinecorrection
+
+If we combine these two segments, we get:
+
+\startbuffer[x]
+drawpath p ; drawpoints p ; drawpointlabels p ;
+swappointlabels := true ;
+drawpath q ; drawpoints q ; drawpointlabels q ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,x]
+\stoplinecorrection
+
+However, when we draw them using the right linewidth and color, you will notice
+that we're not yet done:
+
+\startbuffer[f]
+draw p withcolor nsblue ; draw q withcolor nsblue ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,f]
+\stoplinecorrection
+
+The second curve is similar to the first one, but rotated over 180 degrees.
+
+\startbuffer[g]
+addto currentpicture also currentpicture
+ rotatedaround (.5[z2,z3],180) shifted (height/4,height/2) ;
+\stopbuffer
+
+\typebuffer[g]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,f,g]
+\stoplinecorrection
+
+In order to get the sharp edges, we need to clip off part of
+the curves and at first sight, we may consider using a
+scaled bounding box. However, when we show the natural
+bounding box, you will notice that a more complicated bit of
+calculations is needed.
+
+\startbuffer[x]
+draw boundingbox currentpicture
+ withpen pencircle scaled .5mm withcolor .625white ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,f,g,x]
+\stoplinecorrection
+
+The right clip path is calculated using the following expressions. Watch how we
+use \type {rt} and \type {top} to correct for the linewidth.
+
+\startbuffer[h]
+numeric d, lx, ly, ux, uy ; d = line/2 ;
+
+lx = -3d - d/3 ; ly = -d ; ux = rt x5 + d/3 ; uy = top y6 ;
+
+path r ; r := (lx,ly)--(ux,ly)--(ux,uy)--(lx,uy)--cycle;
+\stopbuffer
+
+\typebuffer[h]
+
+The clipping path is applied by saying:
+
+\startbuffer[i]
+clip currentpicture to r ;
+\stopbuffer
+
+\typebuffer[i]
+
+The result is quite acceptable:
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,f,g,h,i]
+\stoplinecorrection
+
+But, if you watch closely to how this graphic extends into to left margin of this
+document, you will see that the bounding box is not yet right.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,f,g,h,i,x]
+\stoplinecorrection
+
+\startbuffer[j]
+setbounds currentpicture to r ;
+\stopbuffer
+
+\typebuffer[j]
+
+We use the same path \type {r} to correct the bounding box.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,f,g,h,i,j,x]
+\stoplinecorrection
+
+There are a few subtle points involved, like setting the \type {linejoin}
+variable. If we had not set it to \type {mitered}, we would have got round
+corners. We don't set the \type {linecap}, because a flat cap would not extend
+far enough into the touching curve and would have left a small hole. The next
+example shows what happens if we set these variables to the wrong values:
+
+\startbuffer[bb]
+linejoin := rounded ; linecap := mitered ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,bb,c,d,e,f,g,h,i,j]
+\stoplinecorrection
+
+In fact we misuse the fact that both curves overlay each other.
+
+\startbuffer[f]
+draw p withcolor nsblue ; draw q withcolor .625white ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,f,g,h,i,j]
+\stoplinecorrection
+
+The complete logo definition is a bit more extensive because we also want to add
+a background. Because we need to clip the blue foreground graphic, we must
+temporarily store it when we fill the background.
+
+\typebuffer[ns]
+
+For practical use it makes sense to package this definition in a macro to which
+we pass the dimensions.
+
+\stopsection
+
+\startsection[title={Music sheets}]
+
+The next example demonstrates quite some features. Imagine that we want to make
+us a couple of sheets so that we can write a musical masterpiece. Let's also
+forget that \TEX\ can draw lines, which means that somehow we need to use
+\METAPOST.
+
+Drawing a bar is not that complicated as the following code demonstrates.
+
+\startbuffer
+\startusableMPgraphic{bar}
+ vardef MusicBar (expr width, gap, linewidth, barwidth) =
+ image
+ ( interim linecap := butt ;
+ for i=1 upto 5 :
+ draw ((0,0)--(width,0)) shifted (0,(i-1)*gap)
+ withpen pencircle scaled linewidth ;
+ endfor ;
+ for i=llcorner currentpicture -- ulcorner currentpicture ,
+ lrcorner currentpicture -- urcorner currentpicture :
+ draw i withpen pencircle scaled barwidth ;
+ endfor ; )
+ enddef ;
+\stopusableMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We can define the sidebars a bit more efficient using two predefined subpaths:
+
+\starttyping
+for i=leftboundary currentpicture, rightboundary currentpicture :
+\stoptyping
+
+We define a macro \type {MusicBar} that takes four arguments. The first two
+determine the dimensions, the last two concern the line widths. Now watch how we
+can use this macro:
+
+\startbuffer
+\includeMPgraphic{bar} ;
+draw MusicBar (200pt, 6pt, 1pt, 2pt) ;
+draw MusicBar (300pt, 6pt, 1pt, 2pt) shifted (0,-30pt) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+As you can see in this example, the bar is a picture that can be transformed
+(shifted in our case). However, a close look at the macro teaches us that it does
+a couple of draws too. This is possible because we wrap the whole in an image
+using the \type {image} macro. This macro temporary saves the current picture,
+and at the end puts the old \type {currentpicture} under the new one.
+
+We wrap the whole in a \type {vardef}. This means that the image is returned as
+if it was a variable. Actually, the last thing in a \type {vardef} should be a
+proper return value, in our case a picture. This also means that we may not end
+the \type {vardef} with a semi colon. So, when the content of the \type {vardef}
+is expanded, we get something
+
+\starttyping
+draw some_picture ... ;
+\stoptyping
+
+Because we are still drawing something, we can add transform directives and set
+attributes, like the color.
+
+The second \type {for} loop demonstrates two nice features. Instead of repeating
+the draw operation by copying code, we apply it to a list, in our case a list of
+paths. This list contains two simple line paths. Because an \type {image} starts
+with a fresh \type {currentpicture}, we can safely use the bounding box data to
+determine the height of the line.
+
+The next step in producing the sheets of paper is to put several bars on a page,
+preferable with the width of the current text. This time we will use a reusable
+graphic, because each bar is the same.
+
+\startbuffer
+\startreusableMPgraphic{bars}
+ \includeMPgraphic{bar} ;
+ draw MusicBar (TextWidth, 6pt, 1pt, 2pt) withcolor .625yellow ;
+\stopreusableMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\reuseMPgraphic{bars}
+\stoplinecorrection
+
+Instead of going through the trouble of letting \METAPOST\ calculate the positions
+of the bars, we will use \TEX. We put 12 bars on a page and let \TEX\ take care
+of the inter||bar spacing. Because we only want stretchable space between bars,
+called glue in \TEX, we need to remove the last added glue.
+
+\startnotmode[screen]
+
+\startbuffer[music]
+\startstandardmakeup[doublesided=no,page=]
+ \dorecurse{15}{\reuseMPgraphic{bars}\vfill}\removelastskip
+\stopstandardmakeup
+\stopbuffer
+
+\stopnotmode
+
+\startmode[screen]
+
+\startbuffer[music]
+\startstandardmakeup[doublesided=no,page=]
+ \dorecurse{10}{\reuseMPgraphic{bars}\vfill}\removelastskip
+\stopstandardmakeup
+\stopbuffer
+
+\stopmode
+
+\typebuffer[music]
+
+\startusableMPgraphic{bar}
+ vardef MusicBar (expr width, gap, linewidth, barwidth) =
+ image
+ ( interim linecap := butt ;
+ for i=1 upto 5 :
+ draw ((0,0)--(width,0))
+ randomized (1pt,1.5pt)
+ shifted (0,(i-1)*gap)
+ withpen pencircle scaled linewidth ;
+ endfor ;
+ for i=llcorner currentpicture -- ulcorner currentpicture ,
+ lrcorner currentpicture -- urcorner currentpicture :
+ draw i randomized 2pt shifted (0,-1pt)
+ withpen pencircle scaled barwidth ;
+ endfor ; )
+ enddef ;
+\stopusableMPgraphic
+
+\startreusableMPgraphic{bars} % trigger a new one
+ \includeMPgraphic{bar} ;
+ draw MusicBar (TextWidth, 6pt, 1pt, 2pt) withcolor .625yellow ;
+\stopreusableMPgraphic
+
+It may add to the atmosphere of handy||work if you slightly randomize the lines.
+We leave it up to the reader to figure out how the code should be changed to
+accomplish this.
+
+\startlinecorrection[blank]
+\reuseMPgraphic{bars}
+\stoplinecorrection
+
+The complete result is shown on the next page.
+
+\startpostponing
+\getbuffer[music]
+\stoppostponing
+
+\stopsection
+
+\startsection[title={The euro symbol}]
+
+When Patrick Gundlach posted a nice \METAPOST\ version of the euro symbol to the
+\CONTEXT\ discussion list, he added the comment \quotation {The official
+construction is ambiguous: how thick are the horizontal bars? How much do they
+stick out to the left? Is this thing a circle or what? Are the angles on the left
+side of the bars the same as the one on the right side? \unknown} The alternative
+below is probably not as official as his, but permits a finetuning. You are
+warned: whatever you try, the euro {\em is} and {\em will remain} an ugly symbol.
+
+We use a couple of global variables to control the euro shape within reasonable
+bounds. Then we define two circles. Next we define a vertical line that we use in
+a couple of cut and paste operations. Watch how the top left point of the outer
+circle determines the slant of the line that we use to slice the vertical bars.
+
+\startbuffer[euro]
+boolean trace_euro ; trace_euro := false ;
+
+vardef euro_symbol = image ( % begin_of_euro
+
+if unknown euro_radius : euro_radius := 2cm ; fi ;
+if unknown euro_width : euro_width := 3euro_radius/16 ; fi ;
+if unknown euro_r_offset : euro_r_offset := euro_width ; fi ;
+if unknown euro_l_offset : euro_l_offset := euro_radius/32 ; fi ;
+if unknown euro_l_shift : euro_l_shift := euro_r_offset ; fi ;
+if unknown euro_v_delta : euro_v_delta := euro_width/4 ; fi ;
+
+save
+ outer_circle, inner_circle, hor_bar,
+ right_line, right_slant, top_slant, bot_slant,
+ euro_circle, euro_topbar, euro_botbar ;
+
+path
+ outer_circle, inner_circle, hor_bar,
+ right_line, right_slant, top_slant, bot_slant,
+ euro_circle, euro_topbar, euro_botbar ;
+
+outer_circle := fullcircle scaled euro_radius ;
+inner_circle := fullcircle scaled (euro_radius-euro_width) ;
+
+if trace_euro : for i = outer_circle, inner_circle :
+ draw i withpen pencircle scaled 1pt withcolor .5white ;
+endfor ; fi ;
+
+right_line :=
+ (lrcorner outer_circle -- urcorner outer_circle)
+ shifted (-euro_r_offset,0) ;
+
+outer_circle := outer_circle cutbefore right_line ;
+
+right_slant :=
+ point 0 of outer_circle
+ -- origin shifted (0,ypart lrcorner outer_circle) ;
+
+euro_circle := buildcycle(outer_circle, right_line,
+ reverse inner_circle, reverse right_slant) ;
+
+hor_bar := (-euro_radius,0) -- (euro_radius,0) ;
+
+top_slant :=
+ right_slant shifted (-euro_radius+euro_r_offset-euro_l_offset,0) ;
+
+bot_slant :=
+ top_slant shifted (0,-euro_l_shift) ;
+
+if trace_euro : for i = right_line, right_slant, top_slant, bot_slant :
+ draw i withpen pencircle scaled 1pt withcolor .5white ;
+endfor ; fi ;
+
+euro_topbar := buildcycle
+ (top_slant, hor_bar shifted (0, euro_v_delta),
+ right_slant, hor_bar shifted (0, euro_v_delta+euro_width/2)) ;
+
+euro_botbar := buildcycle
+ (bot_slant, hor_bar shifted (0,-euro_v_delta),
+ right_slant, hor_bar shifted (0,-euro_v_delta-euro_width/2)) ;
+
+for i = euro_circle, euro_topbar, euro_botbar :
+ draw i withpen pencircle scaled 0 ;
+endfor ;
+for i = euro_circle, euro_topbar, euro_botbar :
+ fill i withpen pencircle scaled 0 ;
+endfor ;
+
+if trace_euro :
+ drawpoints euro_circle withcolor red ;
+ drawpoints euro_topbar withcolor green ;
+ drawpoints euro_botbar withcolor blue ;
+fi ;
+
+) enddef ; % end_of_euro
+\stopbuffer
+
+\typebuffer[euro]
+
+We only set a parameter when it is not yet set. This has
+the advantage that we don't have to set them when we change
+one. This way of manipulating paths (cutting and building)
+does not always work well because of rounding errors, but
+here it does work.
+
+\startbuffer[demo]
+euro_radius := 4cm ; trace_euro := true ; draw euro_symbol ;
+\stopbuffer
+
+\typebuffer[demo]
+
+For educational purposes, we have added a bit of
+tracing. When enabled, the euro shows up as:
+
+\startlinecorrection[blank]
+\processMPbuffer[euro,demo]
+\stoplinecorrection
+
+Of course it would be best to define the euro as one shape, but we won't go
+though that process right now. By packaging the combined paths in an image, we
+can conveniently color the euro symbol:
+
+\startbuffer[demo]
+draw euro_symbol withcolor .625red ;
+\stopbuffer
+
+\typebuffer[demo]
+
+\startlinecorrection[blank]
+\processMPbuffer[euro,demo]
+\stoplinecorrection
+
+You may wonder why we both draw and fill the euro, using a pen with zero width.
+We've done this in order to demonstrate the \type {redraw} and \type {refill}
+macros.
+
+\startbuffer[extra]
+redraw currentpicture withpen pencircle scaled 4pt withcolor .625yellow ;
+refill currentpicture withcolor .625white ;
+setbounds currentpicture to boundingbox currentpicture enlarged 2pt ;
+\stopbuffer
+
+\typebuffer[extra]
+
+\startlinecorrection[blank]
+\processMPbuffer[euro,demo,extra]
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Killing time}]
+
+Not seldom \TEX\ users want to use this program and its meta||relatives as
+general purpose tools, even at the cost of quite some effort or suboptimal
+results. Imagine that you are under way from our planet to Mars. After a long
+period of sleep you wake up and start wondering on what track you are. You even
+start questioning the experts that send you on your way, so you pop open your
+laptop, launch your editor and start metaposting.
+
+First you need to determine the begin and end points of your journey. For now it
+is enough to know the relative angle of the paths that both planets follow as
+well as the path themselves. We assume circular paths.
+
+\startbuffer
+path a ; a := fullcircle scaled 3cm ;
+path b ; b := fullcircle scaled 2cm rotated 120 ;
+
+draw a withpen pencircle scaled 1mm withcolor .625red ;
+draw b withpen pencircle scaled 1mm withcolor .625yellow ;
+
+draw point 0 of a withpen pencircle scaled 2mm ;
+draw point 0 of b withpen pencircle scaled 2mm ;
+\stopbuffer
+
+\typebuffer
+
+The rotation 120 can be calculated from the relative starting points and time the
+journey will take. Alternatively we can use the time along the path, but this
+would be a bit more fuzzy later on. \footnote {In case you wonder why \METAPOST\
+talks about the time on a path, you now have a cue.}
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+After a bit of playing with drawing paths between the two points, you decide to
+make a macro. We want to feed the angle between the paths but also the connecting
+path. So, we have to pass a path, but unfortunately we don't have direct access
+to the points. By splitting the argument definition we can pass an expression
+first, and a wildcard argument next.
+
+\startbuffer
+\startuseMPgraphic{gamble}
+def Gamble (expr rot) (text track) =
+ path a ; a := fullcircle scaled 3cm ;
+ path b ; b := fullcircle scaled 2cm rotated rot ;
+
+ pair aa ; aa := point 0 of a ;
+ pair bb ; bb := point 0 of b ;
+ path ab ; ab := track ;
+
+ draw a withpen pencircle scaled 1mm withcolor .625red ;
+ draw b withpen pencircle scaled 1mm withcolor .625yellow ;
+
+ draw aa withpen pencircle scaled 2mm ;
+ draw bb withpen pencircle scaled 2mm ;
+
+ drawarrow ab withpen pencircle scaled 1mm withcolor .625white ;
+
+ setbounds currentpicture to boundingbox a enlarged 2mm ;
+ draw boundingbox currentpicture withpen pencircle scaled .25mm ;
+enddef ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Because at this distance nobody will bother us with the thickness of the pen and
+colors, we code them the hard way. We create our own universe by setting a fixed
+boundingbox.
+
+We leave the Earth in the most popular way, straight upwards and after a few
+cycles, we leave it parallel to the surface. The path drawn reminds much of the
+trajectories shown in popular magazines.
+
+\startbuffer
+\startMPcode
+\includeMPgraphic{gamble} ;
+Gamble(120, aa {(0,1)} .. bb) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+According to \METAPOST, when we leave the Earth straight upwards and want a
+smooth trajectory, we have to pass through outer space.
+
+\startbuffer
+\startMPcode
+\includeMPgraphic{gamble} ;
+Gamble(120,aa {(1,0)} .. bb) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+Given that we want a smooth path as well as a short journey, we can best follow
+Mars' path. Here we face the risk that when we travel slower than Mars does, we
+have a problem.
+
+\startbuffer
+\startMPcode
+\includeMPgraphic{gamble} ;
+Gamble(120,aa {dir 90} .. {precontrol 0 of b rotated 90} bb) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+We can even travel a shorter path when we leave Earth at the surface that faces
+the point of arrival.
+
+\startbuffer
+\startMPcode
+\includeMPgraphic{gamble} ;
+Gamble(120,aa .. {precontrol 0 of b rotated 90} bb) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+In the end we decide that although the trajectories look impressive, we will not
+trust our lives to \METAPOST. A beautiful path is not neccessarily a good path.
+But even then, this macro provides a nice way to experiment with directions,
+controls and tensions.
+
+\stopsection
+
+% \startsection[title={Animations}]
+%
+% {\em Although \METAPOST\ is not that well suited for free hand drawings, you can
+% use it to make stylistics animations.}
+%
+% \stopsection
+
+\startsection[title={Selective randomization}]
+
+In this document we have used a lot of randomization. Because \CONTEXT\ often
+needs multiple runs to sort out cross references, positions, tables of contents,
+and so on, being real random every run would result in endless runs to get things
+right, because the size of graphics changes. This is prevented by storing the
+random seed betweeen runs. You can remove the \type {tuc} file to get a new seed
+(or run \type {context --purgeall}).
+
+Here is another example of randomization. This time we only randomize the control
+points so the main shape sort of remains intact which can be handy when you use
+such random shapes around text but still want a predictable size.
+
+\startbuffer
+\startMPcode
+fill fullcircle scaled 2cm
+ randomizedcontrols 0.1cm
+ withcolor darkred
+ withtransparency (1,.5) ;
+fill ((1cm,0)--(0,1cm)--(-1cm,0)--cycle)
+ randomizedcontrols 0.1cm
+ withcolor darkblue
+ withtransparency (1,.5) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+\startbuffer
+\startMPcode
+draw image (
+ fill fullcircle scaled 2cm
+ withcolor darkred
+ withtransparency (1,.5) ;
+ fill ((1cm,0)--(0,1cm)--(-1cm,0)--cycle)
+ withcolor darkblue
+ withtransparency (1,.5) ;
+) randomizedcontrols 0.1cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+\stopsection
+
+\startsection[title=Snapping]
+
+There are quite some helpers in \METAFUN\ and I must admit that I forgot
+about most. Some just ended up in the core because they can be useful, others
+serve as illustration. Here's one of them: \type {snapped}. First we define
+a few helpers that we then use to check out a few shapes.
+
+\startbuffer
+\startMPdefinitions
+def ShowSnapGrid(text shape) =
+ fill (shape xsized 77mm) withcolor white/3 ;
+ draw image (
+ for i=10mm step 5mm until 100mm :
+ draw fullsquare scaled i ;
+ endfor ;
+ ) withcolor 2white/3 ;
+ drawpoints (shape xsized 77mm) withcolor black ;
+enddef ;
+
+vardef SnapShape expr shape =
+ image (
+ draw shape ;
+ drawpoints shape ;
+ )
+enddef ;
+
+vardef ShowSnapShape expr shape =
+ ShowSnapGrid(shape);
+
+ draw SnapShape(shape xsized 77mm snapped -5mm ) withcolor red ;
+ draw SnapShape(shape xsized 77mm snapped 5mm ) withcolor red ;
+ draw SnapShape(shape xsized 77mm snapped (5mm,10mm)) withcolor green ;
+ draw SnapShape(shape xsized 77mm snapped (5mm,15mm)) withcolor blue ;
+ draw SnapShape(shape xsized 77mm snapped (5mm,20mm)) withcolor yellow ;
+enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\typebuffer \getbuffer
+
+In \in {figures} [fig:snapper:1], \in [fig:snapper:2] and \in [fig:snapper:3] we
+see how the original shape gets snapped on the grid. Of course in more complex
+images the direction of the snapping can change the result in an unwanted way,
+like overlapping shapes that obscure others, but normally this snapping is only
+useful for simple predictable cases (like title pages).
+
+\startplacefigure[reference=fig:snapper:1,title={Messing with \type{fullcircle}.}]
+\startMPcode
+ ShowSnapShape(fullcircle);
+\stopMPcode
+\stopplacefigure
+
+\startplacefigure[reference=fig:snapper:2,title={\type{fullsquare}}]
+\startMPcode
+ ShowSnapShape(fullsquare);
+\stopMPcode
+\stopplacefigure
+
+\startplacefigure[reference=fig:snapper:3,title={\type{fulltriangle}}]
+\startMPcode
+ ShowSnapShape(fulltriangle);
+\stopMPcode
+\stopplacefigure
+
+\stopsection
+
+\startsection[title=Arrowheads]
+
+Arrows are actually drawn quite well in \METAPOST, as the arrowheads nicely adapt
+to the direction of the point where the arrowhead is attached. There are however
+some limitations as the following examples demonstrate: arrows don't work well
+with transparency and you can probably figure out why. Alan Braslau came up with
+an extension that allows to set the dimple of the head. You can see all this
+in \in {figure} [fig:arrowheads].
+
+\startbuffer[a]
+numeric unit ; unit := mm ;
+
+drawoptions(withcolor .6blue withtransparency (1,.25)) ;
+
+pickup pencircle scaled 2unit ; ahlength := 6unit ;
+
+picture p ; p := image (
+ drawarrow reverse fullcircle rotated - 5 scaled 50unit ;
+ drawarrow reverse fullcircle rotated -10 scaled 30unit ;
+) shifted ( -45unit, 0unit) ;
+
+for i=0 step 90 until 360 : draw p rotated i ; endfor ;
+
+currentpicture := currentpicture shifted - center currentpicture ;
+
+p := currentpicture ; p := image (
+ draw llcorner p -- center p ;
+ drawarrow llcorner p -- 0.875[llcorner p,center p] ;
+) ;
+
+for i=0 step 90 until 360 : draw p rotated i ; endfor ;
+
+clip currentpicture to boundingbox (fullcircle scaled 80unit) ;
+
+if lua.mp.mode("screen") :
+ currentpicture := currentpicture ysized .4TextHeight ;
+else :
+ currentpicture := currentpicture xsized .4TextWidth ;
+fi ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startbuffer[b]
+ resetarrows ;
+\stopbuffer
+
+\startbuffer[a1]
+ ahvariant := 1 ;
+\stopbuffer
+\startbuffer[a2]
+ ahvariant := 2 ;
+\stopbuffer
+
+\startbuffer[a3]
+ ahvariant := 1 ; ahdimple := 1/2 ;
+\stopbuffer
+\startbuffer[a4]
+ ahvariant := 1 ; ahdimple := 1 ;
+\stopbuffer
+\startbuffer[a5]
+ ahvariant := 1 ; ahdimple := 5/2 ;
+\stopbuffer
+
+\startplacefigure[reference=fig:arrowheads,title=The way arrowheads are constructed.]
+ \doifelsemode {screen} {
+ \setupcombination[nx=3,ny=2]
+ } {
+ \setupcombination[nx=2,ny=3]
+ }
+ \startcombination[distance=2em]
+ {\processMPbuffer[a, b]} {\tttf ahvariant=0}
+ {\processMPbuffer[a1,a,b]} {\tttf ahvariant=1}
+ {\processMPbuffer[a2,a,b]} {\tttf ahvariant=2}
+ {\processMPbuffer[a3,a,b]} {\tttf ahvariant=1, ahdimple=1/2}
+ {\processMPbuffer[a4,a,b]} {\tttf ahvariant=1, ahdimple=1}
+ {\processMPbuffer[a5,a,b]} {\tttf ahvariant=1, ahdimple=5/2}
+ \stopcombination
+\stopplacefigure
+
+\stopsection
+
+\startsection[title=Teaser]
+
+Sometimes, when playing with \METAPOST\ you run into interesting cases. Here is
+one. The result is shown in \in {figure} [fig:teaser:1].
+
+\startbuffer
+\startusableMPgraphic{BackgroundTeaser}
+ fill OverlayBox enlarged 1mm withcolor darkyellow ; % bleed
+ path p ; p := OverlayBox enlarged -5mm ;
+ path q ; q := OverlayBox enlarged -10mm ;
+ fill q withcolor white ;
+ drawoptions(withcolor darkred) ;
+ fill reverse topboundary q -- topboundary p -- cycle ;
+ fill reverse bottomboundary q -- bottomboundary p -- cycle ;
+ drawoptions(withcolor darkgreen) ;
+ fill reverse leftboundary q -- leftboundary p -- cycle ;
+ fill reverse rightboundary q -- rightboundary p -- cycle ;
+\stopusableMPgraphic
+
+\defineoverlay
+ [BackgroundTeaser]
+ [\useMPgraphic{BackgroundTeaser}]
+
+\framed
+ [frame=off,
+ offset=15mm,
+ background=BackgroundTeaser,
+ align=normal]
+ {\input knuth }
+\stopbuffer
+
+\typebuffer
+
+\startplacefigure[reference=fig:teaser:1,title=Can you guess what happens here?]
+ \getbuffer
+\stopplacefigure
+
+\stopsection
+
+\startsection[title={Lists}]
+
+For some specific purpose I needed to sort a list of paths and therefore
+\METAFUN\ comes with a quick sort macro. Its working can be demonstrated by an
+example.
+
+\startbuffer[a]
+pair p[], pp[] ; numeric n ; n := 25 ;
+for i=1 upto n : p[i] := origin randomized 4cm ; endfor ;
+\stopbuffer
+
+\startbuffer[b]
+copylist(p,pp) ; % unsorted
+drawarrow listtolines(pp) shifted ( 0,0) withcolor darkblue ;
+\stopbuffer
+
+\startbuffer[c]
+copylist(p,pp) ; sortlist(pp)() ; % sorted
+drawarrow listtolines(pp) shifted (300,0) withcolor darkyellow ;
+\stopbuffer
+
+\startbuffer[d]
+copylist(p,pp) ; sortlist(pp)(xpart) ;
+drawarrow listtolines(pp) shifted (100,0) withcolor darkred ;
+
+\stopbuffer
+\startbuffer[e]
+copylist(p,pp) ; sortlist(pp)(ypart) ;
+drawarrow listtolines(pp) shifted (200,0) withcolor darkgreen ;
+\stopbuffer
+
+\startbuffer[f]
+vardef whow expr p = (xpart p + ypart p) enddef ;
+
+copylist(p,pp) ; sortlist(pp)(whow) ;
+drawarrow listtolines(pp) shifted (400,0) withcolor darkcyan ;
+\stopbuffer
+
+\startbuffer[g]
+vardef whow expr p = (xpart p ++ ypart p) enddef ;
+
+copylist(p,pp) ; sortlist(pp)(whow) ;
+drawarrow listtolines(pp) shifted (500,0) withcolor darkmagenta ;
+\stopbuffer
+
+\typebuffer[a,b,c,d,e,f,g]
+
+The result of this code is shown in \in {figure} [fig:sorting].
+
+\startplacefigure[reference=fig:sorting,title={Using the sorter.}]
+ \startcombination[3*2]
+ {\processMPbuffer[a,b]} {\tttf unsorted}
+ {\processMPbuffer[a,c]} {\tttf sorted}
+ {\processMPbuffer[a,d]} {\tttf xpart}
+ {\processMPbuffer[a,e]} {\tttf ypath}
+ {\processMPbuffer[a,f]} {\tttf xpart p + ypart p}
+ {\processMPbuffer[a,g]} {\tttf xpart p ++ ypart p}
+ \stopcombination
+\stopplacefigure
+
+There is a helper that converts a list of paths into a shape that covers all
+of them. In \in {figure} [fig:shapedlist] three shaped lists are shown.
+
+\startbuffer[a]
+ def ShowShape(expr e) =
+ draw image (
+
+ save p ; path p[] ;
+
+ def MakeShape(expr i,w,h,x,y) =
+ p[i] := e
+ xysized ((w,h) randomized (2mm,1mm))
+ shifted ((x,y) randomized (2mm,1mm)) ;
+ enddef ;
+
+ MakeShape(1,40mm,6mm,10mm, 0mm) ;
+ MakeShape(2,50mm,5mm, 5mm,-10mm) ;
+ MakeShape(3,20mm,8mm,30mm,-20mm) ;
+ MakeShape(4,55mm,5mm,10mm,-30mm) ;
+ MakeShape(5,55mm,5mm, 5mm,-50mm) ;
+
+ save s ; path s ; s := shapedlist(p) ; drawarrow s ;
+
+ linejoin := butt ;
+
+ for i=1 upto 5 :
+ fill p[i] withcolor .75white withtransparency (1,.5) ;
+ draw thetextext("\tttf " & decimal i, center p[i]) ;
+ endfor ;
+
+ ) ysized 4cm ;
+ enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startbuffer[b]
+ShowShape(unitsquare)
+\stopbuffer
+
+\startbuffer[c]
+ShowShape(unitcircle)
+\stopbuffer
+
+\startbuffer[d]
+ShowShape(unittriangle)
+\stopbuffer
+
+\startplacefigure[reference=fig:shapedlist,title={The \type {shapedlist} macro returns the envelope that covers all the paths in the list.}]
+ \startcombination[3*1]
+ {\processMPbuffer[a,b]} {\tttf unitsquare}
+ {\processMPbuffer[a,c]} {\tttf unitcircle}
+ {\processMPbuffer[a,d]} {\tttf unittriangle}
+ \stopcombination
+\stopplacefigure
+
+\stopsection
+
+\startsection[title=Table cells]
+
+Sometimes a standard \CONTEXT\ feature doesn't work out as expected. Take the
+following table:
+
+\startbuffer
+\bTABLE[frame=on,framecolor=blue,rulethickness=1pt]
+ \bTR
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD[framecolor=magenta] test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \eTR
+ \bTR
+ \bTD test \eTD
+ \bTD[framecolor=red] test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD[framecolor=green] test \eTD
+ \eTR
+\eTABLE
+\stopbuffer
+
+\typebuffer
+
+Because cells are drawn top|-|down and left|-|right a next cell border
+overruns the previous one.
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+\startbuffer
+\bTABLE[frame=on,framecolor=blue,rulethickness=1pt]
+ \bTR
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD[framecolor=magenta,frameoffset=-.5pt] test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \eTR
+ \bTR
+ \bTD test \eTD
+ \bTD[framecolor=red,frameoffset=-.5pt] test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD[framecolor=green,frameoffset=-.5pt] test \eTD
+ \eTR
+\eTABLE
+\stopbuffer
+
+You can try this:
+
+\typebuffer
+
+which gives us something that is not okay either for cells that touch an edge:
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+but we can cheat:
+
+\startlinecorrection
+\framed
+ [offset=overlay,
+ frameoffset=.5pt,
+ framecolor=blue,
+ rulethickness=1pt]
+ {\getbuffer}
+\stoplinecorrection
+
+This is achieved by framing the whole table:
+
+\starttyping
+\framed
+ [offset=overlay,
+ frameoffset=.5pt,
+ framecolor=blue,
+ rulethickness=1pt]
+ {...}
+\stoptyping
+
+\startbuffer
+\startuseMPgraphic{cell:innerframe}{innercolor}
+ draw OverlayBox enlarged -1.5OverlayLineWidth
+ withpen pensquare scaled OverlayLineWidth
+ withcolor \MPvar{innercolor} ;
+\stopuseMPgraphic
+
+\defineoverlay
+ [innerframe]
+ [{\uniqueMPgraphic{cell:innerframe}%
+ {innercolor=\framedparameter{innercolor}}}]
+
+\bTABLE[frame=on,framecolor=blue,rulethickness=1pt,innercolor=magenta]
+ \bTR
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD[background=innerframe] test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \eTR
+ \bTR
+ \bTD test \eTD
+ \bTD[background=innerframe,innercolor=red] test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD[background=innerframe,innercolor=green] test \eTD
+ \eTR
+\eTABLE
+\stopbuffer
+
+A \METAPOST\ alternative is also possible and it gives a bit nicer
+interface too:
+
+\typebuffer
+
+We get:
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-functions.tex b/doc/context/sources/general/manuals/metafun/metafun-functions.tex
new file mode 100644
index 000000000..780127408
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-functions.tex
@@ -0,0 +1,611 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-functions
+
+\environment metafun-environment
+
+\startchapter[title={Functions}]
+
+\index{functions}
+
+\startintro
+
+\METAPOST\ provides a wide range of functions, like \type {sind} and \type
+{floor}. We will discuss most of them here and define a few more. We will also
+introduce a few methods for drawing grids and functions.
+
+\stopintro
+
+\startsection[title={Overview}]
+
+What follows is a short overview of the functions that can be applied to numeric
+expressions and strings. Functions that operate on pairs, colors, paths and
+pictures are discussed in other chapters.
+
+First of all we have \type {+}, \type {-}, \type {/} and \type {*}. For as far as
+is reasonable, you can apply these to numerics, pairs and colors. Strings can be
+concatenated by \type {&}.
+
+Pythagorean addition is accomplished by \type {++}, while Pythagorean subtraction
+is handled by \type {+-+}. The \type {**} operator gives you exponentiation. The
+nature of the \METAPOST\ language is such that you can easily define interesting
+functions using such symbols.
+
+The logarithmic functions are based on bytes. This makes them quite accurate but
+forces you to think like a computer.
+
+\starttabulate[|lT|l|]
+\HL
+\NC mexp(x) \NC expential function with base 256 \NC \NR
+\NC mlog(x) \NC logarithm with base 256 \NC \NR
+\HL
+\stoptabulate
+
+The basic goniometric functions operate on degrees, which is why they have a
+\quote {d} in their name.
+
+\starttabulate[|lT|l|]
+\HL
+\NC cosd(x) \NC cosine of $x$ with $x$ in degrees \NC \NR
+\NC sind(x) \NC sine of $x$ with $x$ in degrees \NC \NR
+\HL
+\stoptabulate
+
+There are three ways to truncate numbers. The \type {round} function can also
+handle pairs and colors.
+
+\starttabulate[|lT|l|]
+\HL
+\NC ceiling(x) \NC the least integer greater than or equal to $x$ \NC \NR
+\NC floor(x) \NC the greatest integer less than or equal to $x$ \NC \NR
+\NC round(x) \NC round each component of $x$ to the nearest integer \NC \NR
+\HL
+\stoptabulate
+
+Of course we have:
+
+\starttabulate[|lT|l|]
+\HL
+\NC x mod y \NC the remainder of $x/y$ \NC \NR
+\NC x div y \NC the integer part of $x/y$ \NC \NR
+\NC abs(x) \NC the absolute value of $x$ \NC \NR
+\NC sqrt(x) \NC the square root of $x$ \NC \NR
+\NC x dotprod y \NC the dot product of two vectors \NC \NR
+\HL
+\stoptabulate
+
+What would life be without a certain randomness and uncertainty:
+
+\starttabulate[|lT|l|]
+\HL
+\NC normaldeviate \NC a number with mean 0 and standard deviation 1 \NC \NR
+\NC uniformdeviate(x) \NC a number between zero and $x$ \NC \NR
+\HL
+\stoptabulate
+
+The following functions are actually macros:
+
+\starttabulate[|lT|l|]
+\HL
+\NC decr(x,n) \NC decrement $x$ by $n$ \NC \NR
+\NC incr(x,n) \NC increment $x$ by $n$ \NC \NR
+\NC max(a,b,..) \NC return the maximum value in the list \NC \NR
+\NC min(a,b,..) \NC return the minimum value in the list \NC \NR
+\HL
+\stoptabulate
+
+The \type {min} and \type {max} funtions can be applied to numerics as well as
+strings.
+
+The following functions are related to strings:
+
+\starttabulate[|lT|l|]
+\HL
+\NC oct s \NC string representation of an octal number \NC \NR
+\NC hex s \NC string representation of a hexadecimal number \NC \NR
+\NC str s \NC string representation for a suffix \NC \NR
+\NC ASCII s \NC \ASCII\ value of the first character \NC \NR
+\NC char x \NC character of the given \ASCII\ code \NC \NR
+\NC decimal x \NC decimal representation of a numeric \NC \NR
+\HL
+\stoptabulate
+
+With \type {substring (i,j) of s} you can filter the substring bounded by the
+given indices from the given string.
+
+In \METAFUN\ we provide a few more functions (you can take a look in \type
+{mp-tool.mp} to see how they are defined. You need to be aware of very subtle
+rounding errors. Normally these only show up when you reverse an operation. This
+is a result from mapping to and from internal quantities.
+
+\starttabulate[|Tl|ml|]
+\HL
+\NC sqr(x) \NC x^2 \NC \NR
+\NC log(x) \NC \log(x) \NC \NR
+\NC ln(x) \NC \ln(x) \NC \NR
+\NC exp(x) \NC {\rm e}^x \NC \NR
+\NC pow(x, p) \NC x^p \NC \NR
+\NC inv(x) \NC 1/x \NC \NR
+\HL
+\stoptabulate
+
+The following sine and cosine functions take radians instead of angles in
+degrees.
+
+\starttabulate[|Tl|Tl|Tl|]
+\HL
+\NC sin(x) \NC asin(x) \NC invsin(x) \NC \NR
+\NC cos(x) \NC acos(x) \NC invcos(x) \NC \NR
+\HL
+\stoptabulate
+
+There are no tangent functions, so we provide both the radian and degrees
+versions:
+
+\starttabulate[|Tl|Tl|]
+\HL
+\NC tan(x) \NC tand(x) \NC \NR
+\NC cot(x) \NC cotd(x) \NC \NR
+\HL
+\stoptabulate
+
+Here are a couple of hyperbolic functions.
+
+\starttabulate[|Tl|Tl|]
+\HL
+\NC sinh(x) \NC asinh(x) \NC \NR
+\NC cosh(x) \NC acosh(x) \NC \NR
+\HL
+\stoptabulate
+
+We end with a few additional string converters.
+
+\starttabulate[|Tl|l|]
+\HL
+\NC ddecimal x \NC decimal representation of a pair \NC \NR
+\NC dddecimal x \NC decimal representation of a color \NC \NR
+\NC condition x \NC string representation of a boolean \NC \NR
+\HL
+\stoptabulate
+
+\stopsection
+
+\startsection[title={Grids}]
+
+\index{grids}
+\index{axis}
+
+Some day you may want to use \METAPOST\ to draw a function like graphic. In the
+regular \TEX\ distributions you will find a module \type {graph.mp} that provides
+many ways to accomplish this. For the moment, \METAFUN\ does not provide advanced
+features with respect to drawing functions, so this section will be relatively
+short.
+
+When drawing a functions (for educational purposes) we need to draw a couple of
+axis or a grid as well as a shape. Along the axis we can put labels. For this we
+can use the \METAPOST\ package \type {format.mp}, but this does not integrate
+that well into the way \METAFUN\ deals with text typeset by \TEX.
+
+For those who love dirty tricks and clever macros, close reading of the code in
+\type {format.mp} may be worthwhile. The format macros in there use \TEX\ to
+typeset the core components of a number, and use the dimensions of those
+components to compose combinations of signs, numbers and superscripts.
+
+In \METAFUN\ we have the module \type {mp-form.mp} which contains most of the
+code in \type {format.mp} but in a form that is a bit more suited for fine
+tuning. This permits us to use either the composition method, or to fall back on
+the \type {textext} method that is part of \METAFUN. That way we can also handle
+fonts that have digits with different dimensions. Another \quote {change}
+concerns the pattern separator. Instead of a \type {%} we use \type {@}; you can
+choose to set another separator, but for embedded definitions \type {%} is
+definitely a bad choice because \TEX\ sees it as a comment and ignores everything
+following it.
+
+\startbuffer[grd]
+drawoptions(withpen pencircle scaled 1pt withcolor .625yellow) ;
+
+draw hlingrid(0, 10, 1, 3cm, 3cm) ;
+draw vlingrid(0, 10, 1, 3cm, 3cm) ;
+
+draw hlingrid(0, 10, 1, 3cm, 3cm) shifted ( 3.5cm,0) ;
+draw vloggrid(0, 10, 1, 3cm, 3cm) shifted ( 3.5cm,0) ;
+
+draw hloggrid(0, 10, 1, 3cm, 3cm) shifted ( 7.0cm,0) ;
+draw vlingrid(0, 10, 1, 3cm, 3cm) shifted ( 7.0cm,0) ;
+
+draw hloggrid(0, 10, 1, 3cm, 3cm) shifted (10.5cm,0) ;
+draw vloggrid(0, 10, 1, 3cm, 3cm) shifted (10.5cm,0) ;
+\stopbuffer
+
+\typebuffer[grd]
+
+\startlinecorrection[blank]
+\processMPbuffer[grd]
+\stoplinecorrection
+
+\startbuffer[grd]
+drawoptions(withpen pencircle scaled 1pt withcolor .625yellow) ;
+
+draw hlingrid(0, 10, 1, 3cm, 3cm) slanted .5 ;
+draw vlingrid(0, 10, 1, 3cm, 3cm) slanted .5 ;
+\stopbuffer
+
+\typebuffer[grd]
+
+\startlinecorrection[blank]
+\processMPbuffer[grd]
+\stoplinecorrection
+
+Using macros like these often involves a bit of trial and error. The arguments to
+these macros are as follows:
+
+\starttyping
+hlingrid (Min, Max, Step, Length, Width)
+vlingrid (Min, Max, Step, Length, Height)
+hloggrid (Min, Max, Step, Length, Width)
+vloggrid (Min, Max, Step, Length, Height)
+\stoptyping
+
+The macros take the following text upto the semi||colon into account and return a
+picture. We will now apply this knowledge to a more meaningful example. First we
+draw a grid.
+
+You can use the grid drawing macros to produce your own paper, for instance using
+the following mixed \TEX ||\METAFUN\ code:
+
+\typebuffer[gridpage]
+
+This produces a page (as in \in {figure} [fig:gridpage]) with a metric grid. If
+you're hooked to the inch, you can set \type {unit := 1in}. If you want to
+process this code, you need to wrap it into the normal document producing
+commands:
+
+\starttyping
+\setupcolors[state=start]
+
+\starttext
+ ... definitions ...
+\stoptext
+\stoptyping
+
+\placefigure
+ [page]
+ [fig:gridpage]
+ {Quick and dirty grid paper.}
+ {\typesetfile
+ [mfun-901.tex]
+ [page=1,height=.9\textheight]}
+
+\stopsection
+
+\startsection[title={Drawing functions}]
+
+Today there are powerful tools to draw functions on grids, but for simple
+functions you can comfortably use \METAPOST. Let's first draw a simple
+log||linear grid.
+
+\startbuffer[grd]
+drawoptions(withpen pencircle scaled .25pt withcolor .5white) ;
+
+draw hlingrid (0, 20, .2, 20cm, 10cm) ;
+draw vloggrid (0, 10, .5, 10cm, 20cm) ;
+
+drawoptions(withpen pencircle scaled .50pt) ;
+
+draw hlingrid (0, 20, 1, 20cm, 10cm) ;
+draw vloggrid (0, 10, 1, 10cm, 20cm) ;
+\stopbuffer
+
+\typebuffer[grd]
+
+To this grid we add some labels:
+
+\startbuffer[txt]
+fmt_pictures := false ; % use TeX as formatting engine
+textextoffset := ExHeight ; % a variable set by ConTeXt
+
+draw hlintext.lft(0, 20, 5, 20cm, "@3e") ;
+draw vlogtext.bot(0, 10, 9, 10cm, "@3e") ;
+\stopbuffer
+
+\typebuffer[txt]
+
+The arguments to the text placement macros are similar to the ones for drawing
+the axes. Here we provide a format string.
+
+\starttyping
+hlintext (Min, Max, Step, Length, Format)
+vlintext (Min, Max, Step, Length, Format)
+hlogtext (Min, Max, Step, Length, Format)
+vlogtext (Min, Max, Step, Length, Format)
+\stoptyping
+
+When drawing a smooth function related curve, you need to provide enough sample
+points. The \type {function} macro will generate them for you, but you need to
+make sure that for instance the maximum and minimum values are part of the
+generated series of points. Also, a smooth curve is not always the right curve.
+Therefore we provide three drawing modes:
+
+\starttabulate[|cT|l|]
+\HL
+\NC \bf method \NC \bf result \NC \NR
+\HL
+\NC 1 \NC a punked curve, drawn using \type {--} \NC \NR
+\NC 2 \NC a smooth curve, drawn using \type {..} \NC \NR
+\NC 3 \NC a tight curve, drawn using \type {...} \NC \NR
+\HL
+\stoptabulate
+
+If method~2 or~3 do not give the desired outcome, you can try a smaller step
+combined with method~1.
+
+\startbuffer[log]
+draw
+ function(1,"log(x)","x",1,10,1) xyscaled (10cm,2cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,yellow) ;
+
+draw
+ function(2,".5log(x)","x",1,10,1) xyscaled (10cm,2cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,blue) ;
+\stopbuffer
+
+\typebuffer[log]
+
+\placefigure
+ [page]
+ {An example of a graphic with labels along the axes.}
+ {\doifmodeelse{screen}
+ {\scale[height=.85\textheight]{\processMPbuffer[grd,txt,log]}}
+ {\processMPbuffer[grd,txt,log]}}
+
+The first argument to the \type {function} macro specifies the drawing method.
+The last three arguments are the start value, end value and step. The second and
+third argument specify the function to be drawn. In this case the pairs \type
+{(x,x)} and \type {(.5log(x),x)} are calculated.
+
+\startbuffer[gon]
+textextoffset := ExHeight ;
+
+drawoptions(withpen pencircle scaled .50pt) ;
+
+draw hlingrid(-10, 10, 1, 10cm, 10cm) ;
+draw vlingrid( 0, 20, 1, 10cm, 20cm) shifted (0,-10cm) ;
+
+drawoptions() ;
+
+draw
+ function(2,"x","sind(x)",0,360,10) xyscaled (1cm/36,10cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,blue) ;
+
+draw
+ function(2,"x","sin(x*pi)",0,epsed(2),.1) xyscaled (10cm/2,5cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,yellow) ;
+
+draw
+ function(2,"x","cosd(x)",0,360,10) xyscaled (1cm/36,10cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,red) ;
+
+draw
+ function(2,"x","cos(x*pi)",0,epsed(2),.1) xyscaled (10cm/2,5cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,green) ;
+\stopbuffer
+
+\typebuffer[gon]
+
+\placefigure
+ [page]
+ {By using transparent colors, we don't have to calculate
+ and mark the common points: they already stand out.}
+ {\doifmodeelse{screen}
+ {\scale[height=.85\textheight]{\processMPbuffer[gon]}}
+ {\processMPbuffer[gon]}}
+
+In this example we draw sinus and cosine functions using degrees and radians. In
+the case of radians the end points are not calculated due to rounding errors. In
+such case you can use the \type {epsed} value, which gives slightly more
+playroom.
+
+\startbuffer[mix]
+draw function (1, "x", "sin(2x)" , 1, 10, .01) scaled 1.5cm
+ withpen pencircle scaled 1mm withcolor transparent(1,.5,red) ;
+draw function (1, "x", "sin(2x*x)" , 1, 10, .01) scaled 1.5cm
+ withpen pencircle scaled 1mm withcolor transparent(1,.5,green) ;
+draw function (1, "x", "sin(2x*x+x)", 1, 10, .01) scaled 1.5cm
+ withpen pencircle scaled 1mm withcolor transparent(1,.5,blue) ;
+\stopbuffer
+
+\typebuffer[mix]
+
+Of course you can do without a grid. The next example demonstrates a nice
+application of transparencies.
+
+\startlinecorrection[blank]
+\processMPbuffer[mix]
+\stoplinecorrection
+
+If we use the \type {exclusion} method for the transparencies, combined with no
+transparency, we get the following alternative.
+
+\startbuffer[mix]
+draw function (2, "x", "sin(x)" , 0, 2pi, pi/40) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,red) ;
+draw function (2, "x", "sin(2x)", 0, 2pi, pi/40) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,green) ;
+draw function (2, "x", "sin(3x)", 0, 2pi, pi/40) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,blue) ;
+\stopbuffer
+
+\typebuffer[mix]
+
+\startlinecorrection[blank]
+\processMPbuffer[mix,wipe]
+\stoplinecorrection
+
+The next alternative uses a larger step, and as a result (in drawing mode~2)
+gives worse results. (Without the \type {epsed} it would have looked even worse
+in the end points.
+
+ \startbuffer[mix]
+draw function (2, "x", "sin(x)" , 0, epsed(2pi), pi/10) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,red) ;
+draw function (2, "x", "sin(2x)", 0, epsed(2pi), pi/10) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,green) ;
+draw function (2, "x", "sin(3x)", 0, epsed(2pi), pi/10) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,blue) ;
+\stopbuffer
+
+\typebuffer[mix]
+
+\startlinecorrection[blank]
+\processMPbuffer[mix,wipe]
+\stoplinecorrection
+
+There are enough applications out there to draw nice functions, like gnuplot for
+which Mojca Miklavec made a backend that works well with \CONTEXT. Nevertheless
+it can be illustrative to explore the possibilities of the \CONTEXT, \LUATEX,
+\METAPOST\ combination using functions.
+
+First of all you can use \LUA\ to make paths and this is used in some of the
+debugging and tracing options that come with \CONTEXT. For instance, if you
+process a document with
+
+\starttyping
+context --timing yourdoc.tex
+\stoptyping
+
+then you can afterwards process a file that is generated while processing this
+document:
+
+\starttyping
+context --extras timing yourdoc
+\stoptyping
+
+This will give you a document with graphics that show where \LUATEX\ spent its
+time on. Of course these graphics are generated with \METAPOST.
+
+There are a few helpers built in (and more might follow). For example:
+
+\startbuffer
+draw
+ \ctxlua {
+ metapost.metafun.topath {
+ { x=1, y=1 },
+ { x=1, y=3 },
+ { 4, 1},
+ "cycle"
+ }
+ }
+ xysized(4cm,3cm)
+ withpen pencircle scaled 1mm
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+The \type {topath} function takes a table of points or strings.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+You can pass a connector so
+
+\startbuffer
+draw
+ \ctxlua {
+ metapost.metafun.topath (
+ {
+ { x=1, y=1 },
+ { x=1, y=3 },
+ { 4, 1 },
+ "cycle"
+ },
+ "--"
+ )
+ }
+ xysized(4cm,3cm)
+ withpen pencircle scaled 1mm
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+gives:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Writing such \LUA\ functions is no big deal. For instance we have available:
+
+\starttyping
+function metapost.metafun.interpolate(f,b,e,s,c)
+ tex.write("(")
+ for i=b,e,(e-b)/s do
+ local d = loadstring (
+ string.formatters["return function(x) return %s end"](f)
+ )
+ if d then
+ d = d()
+ if i > b then
+ tex.write(c or "...")
+ end
+ tex.write(string.formatters["(%F,%F)"](i,d(i)))
+ end
+ end
+ tex.write(")")
+end
+\stoptyping
+
+An example of usage is:
+
+\startbuffer
+draw
+ \ctxlua{metapost.metafun.interpolate(
+ "math.sin(x^2+2*x+math.sqrt(math.abs(x)))",
+ -math.pi/2,math.pi/2,100
+ )}
+ xysized(6cm,3cm)
+ withpen pencircle scaled 1mm
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+And indeed we get some drawing:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Let's see what happens when we use less accuracy and a different connector:
+
+\startbuffer
+draw
+ \ctxlua{metapost.metafun.interpolate(
+ "math.sin(x^2+2*x+math.sqrt(math.abs(x)))",
+ -math.pi/2,math.pi/2,10,"--"
+ )}
+ xysized(6cm,3cm)
+ withpen pencircle scaled 1mm
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+Now we get:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Of course we could extend this \LUA\ function with all kind of options and we
+might even do that when we need it.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-gadgets.tex b/doc/context/sources/general/manuals/metafun/metafun-gadgets.tex
new file mode 100644
index 000000000..9010fc403
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-gadgets.tex
@@ -0,0 +1,548 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-gadgets
+
+\environment metafun-environment
+
+\startchapter[title={Shapes, symbols and buttons}]
+
+\startintro
+
+One can use \METAPOST\ to define symbols and enhance buttons. Here we introduce
+some of the gadgets that come with \CONTEXT, as well as explain how to integrate
+such gadgets yourself.
+
+\stopintro
+
+\startsection[title={Interfacing to \TEX}]
+
+\index {interfacing}
+
+\startbuffer[a]
+\setupMPvariables
+ [EnglishRule]
+ [height=1ex,
+ width=\availablehsize,
+ color=darkgray]
+
+\startuniqueMPgraphic{EnglishRule}{height,width,color}
+ numeric height ; height = \MPvar{height} ;
+ x1 = 0 ; x3 = \MPvar{width} ; x2 = x4 = .5x3 ;
+ y1 = y3 = 0 ; y2 := -y4 = height/2 ;
+ fill z1 .. z2 .. z3 & z3 .. z4 .. z1 & cycle
+ withcolor \MPvar{color} ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\startbuffer[b]
+\defineblank
+ [EnglishRule]
+ [medium]
+
+\unexpanded\def\EnglishRule
+ {\start
+ \dontcomplain
+ \startlinecorrection[EnglishRule]
+ \noindent \reuseMPgraphic{EnglishRule}
+ \stoplinecorrection
+ \stop}
+\stopbuffer
+
+\getbuffer[a,b]
+
+In the early days of \METAPOST\ support in \CONTEXT, Tobias Burnus asked me if it
+was possible to define English rules. What exactly does an english rule look
+like? Here is one:
+
+\EnglishRule
+
+As you can see, such a rule has to adapt itself to the current text width,
+normally \type {\hsize} in \TEX, or on request \type {\availablehsize} in
+\CONTEXT. We need to set the height to a reasonable size, related to the font
+size, and we also need to take care of proper spacing. Of course we want to run
+\METAPOST\ as less times as possible, so we need to use unique graphics. Let's
+start with the graphic.
+
+\typebuffer[a]
+
+As you can see, we pass two arguments to the graphic definition. The first
+argument is the name, the second argument is a comma separated list of variables.
+This list serves two purposes. First this list is used to create a unique profile
+for the graphic. This means that when we change the value of a variable, a new
+graphic is generated that reflects the change. A second purpose of the list is to
+convert \TEX\ data structures into \METAPOST\ ones, especially dimensions and
+colors. The graphic itself is not that spectacular. We use \type {&} because we
+don't want smooth connections.
+
+\typebuffer[b]
+
+When setting the variables, we used \type {\availablehsize}. We need to use \type
+{\noindent}, a rather familiar \TEX\ primitive, that we use here to start a non
+indented paragraph, being the graphic. The line correction is needed to get the
+spacing around the rule (graphic) right. We pass a blank skip identifier that is
+mapped to a convenient medium skip.
+
+\startbuffer[c]
+Why is this called an English line?
+
+\startnarrower
+ \EnglishRule
+ Is it because they cannot draw a straight one? This could be true
+ after a few strong beers, but then, how do Germans draw a line?
+ \EnglishRule
+\stopnarrower
+\stopbuffer
+
+\typebuffer[c]
+
+As expected, the rule adapts itself to the current width of the text. The height
+of the rule in the middle matches the height of a character with no ascenders and
+descenders.
+
+\getbuffer[c]
+
+\stopsection
+
+\startsection[title={Random graphics}]
+
+\index{randomization}
+
+\startbuffer[a]
+\startuseMPgraphic{fuzzycount}
+ begingroup
+ save height, vstep, hsize, span, drift, d, cp ;
+ height := 3/ 4 * \the \bodyfontsize * \currentfontscale ;
+ span := 1/ 3 * height ;
+ drift := 1/10 * height ;
+ hsize := \the\hsize ;
+ vstep := \the\lineheight ;
+ xmax := hsize div 5span ;
+ pickup pencircle scaled (1/12 * height) ;
+ def d = (uniformdeviate drift) enddef ;
+ for i := 1 upto \MPvar{n} :
+ xpos := ((i-1) mod (5*xmax))*span ;
+ ypos := ((i-1) div (5*xmax))*vstep ;
+ draw
+ if (i mod 5)=0 : ((-d-4.5span,d)--(+d-0.5span,height-d))
+ else : ((-d,+d)--(+d,height-d)) fi
+ shifted (xpos,-ypos+d-drift) ;
+ endfor;
+ picture cp ; cp := currentpicture ;
+ if (ypart ulcorner cp - ypart llcorner cp) <= vstep :
+ setbounds currentpicture to
+ (llcorner cp shifted (0,-ypart llcorner cp) --
+ lrcorner cp shifted (0,-ypart lrcorner cp) --
+ urcorner cp -- ulcorner cp -- cycle) ;
+ fi
+ endgroup ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[b]
+\useMPgraphic{fuzzycount}{n=1001}
+\stopbuffer
+
+Given enough time and paper, we can probably give you some
+
+\startlinecorrection[blank]
+\getbuffer[a,b]
+\stoplinecorrection
+
+reasons why \METAPOST\ is fun. To mention a few: you can enhance the layout with
+graphic ornaments, you can tune your graphics at runtime, and simple high quality
+graphics can be very effective.
+
+\startbuffer[c]
+\startuseMPgraphic{fuzzycount}
+ begingroup
+ save height, span, drift, d, cp ;
+ height := 3/ 5 * \baselinedistance ;
+ span := 1/ 3 * height ;
+ drift := 1/10 * height ;
+ pickup pencircle scaled (1/12 * height) ;
+ def d = (uniformdeviate drift) enddef ;
+ for i := 1 upto \MPvar{n} :
+ draw
+ if (i mod 5)=0 : ((-d-4.5span,d)--(+d-0.5span,height-d))
+ else : ((-d,+d)--(+d,height-d)) fi
+ shifted (span*i,d-drift) ;
+ endfor;
+ picture cp ; cp := currentpicture ; % for readability
+ setbounds currentpicture to
+ (llcorner cp shifted (0,-ypart llcorner cp) --
+ lrcorner cp shifted (0,-ypart lrcorner cp) --
+ urcorner cp -- ulcorner cp -- cycle) ;
+ endgroup ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[d]
+\setupMPvariables[fuzzycount][n=10]
+\stopbuffer
+
+\getbuffer[c,d]
+
+The previous graphics draws exactly 1001 lines in a scratch||numbers||in||a||wall
+fashion. In 1998, the \NTG\ did a survey among its members, and in the report, we
+used this fuzzy counter to enhance the rather dull tables.
+
+\startbuffer
+\starttabulate[|l|c|l|]
+\HL
+\NC system \NC \% \NC \# users \NC\NR
+\HL
+\NC Atari \NC 10.4 \NC \useMPgraphic{fuzzycount}{n=11} \NC\NR
+\NC MSDOS \NC 49.1 \NC \useMPgraphic{fuzzycount}{n=52} \NC\NR
+\NC OS/2 \NC ~9.4 \NC \useMPgraphic{fuzzycount}{n=10} \NC\NR
+\NC MacOS \NC ~5.7 \NC \useMPgraphic{fuzzycount}{n= 6} \NC\NR
+\NC UNIX \NC 51.9 \NC \useMPgraphic{fuzzycount}{n=55} \NC\NR
+\NC WINDOWS \NC 64.2 \NC \useMPgraphic{fuzzycount}{n=68} \NC\NR
+\HL
+\stoptabulate
+\stopbuffer
+
+\placetable
+ [here][tab:fuzzy]
+ {Operating system (n=106).}{\getbuffer}
+
+\in {Table} [tab:fuzzy] demonstrates how scratch numbers can be used. An
+interesting side effect is that when you look long enough to these kind of
+graphics, it looks like the lines are no longer horizontal. This table is defined
+as follows:
+
+\typebuffer
+
+You will notice that we pass a variable to the graphic using a second argument.
+We can access this variable with \type {\MPvar}. The graphic is defined as usable
+graphic, because we want to generate a unique random one each time.
+
+\typebuffer[c]
+
+The core of the macro is the \type {for} loop. Within this loop, we draw groups
+of four plus one lines. The draw path's look a bit complicated, but this has to
+do with the fact that a \type {mod} returns $0-4$ while we like to deal with
+$1-5$.
+
+The height adapts itself to the height of the line. The bounding box correction
+at the end ensures that the baseline is consistent and that the random vertical
+offsets fall below the baseline.
+
+Because we want to be sure that \type {n} has a value, we preset it by saying:
+
+\typebuffer[d]
+
+In the table, it makes sense to adapt the drawing to the lineheight, but a more
+general solution is to adapt the height to the fontsize.
+
+\starttyping
+height := 3/ 4 * \the \bodyfontsize * \currentfontscale ;
+\stoptyping
+
+\getbuffer[a]
+
+In the table we called the graphic directly, but how about making it available as
+a conversion macro? In \CONTEXT\ this is not that hard:
+
+\startbuffer
+\def\fuzzycount#1{{\tx\useMPgraphic{fuzzycount}{n=#1}}}
+\defineconversion[fuzzy][\fuzzycount]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Because such a counter should not be that large, we use \type {\tx} to switch to
+a smaller font. This also demonstrates how the graphic adapts itself to the font
+size.
+
+We can now use this conversion for instance in an itemize. To save space we use
+three columns and no white space between the lines. The \type {2*broad} directive
+makes sure that we have enough room for the number.
+
+\startbuffer
+\startitemize[fuzzy,pack,2*broad,columns,three]
+\item one \item two \item three
+\item four \item five \item six
+\item seven \item eight \item nine
+\stopitemize
+\stopbuffer
+
+\getbuffer
+
+\typebuffer
+
+A careful reader will have noticed that the previous definition of the fuzzy
+counter drawing is not suited to generate the graphics we started with.
+
+\typebuffer[b]
+
+This time we want to limit the width to the current \type {\hsize}. We only need
+to add a few lines of code. Watch how we don't recalculate the bounding box when
+more lines are used.
+
+\typebuffer[a]
+
+\stopsection
+
+\startsection[title={Graphic variables}]
+
+\index{graphics+variables}
+\index{variables}
+
+In the previous sections we have seen that we can pass information to the graphic
+by means of variables. How exactly does this mechanism work?
+
+\startbuffer[def]
+\setupMPvariables[smile][type=1,height=1.25ex,color=darkred]
+
+\startuniqueMPgraphic{smile}{type,height,color}
+ numeric size ; size := \MPvar{height} ;
+ drawoptions(withcolor \MPvar{color}) ;
+ pickup pencircle xscaled (size/6) yscaled (size/12) ;
+ draw halfcircle rotated -90 scaled size ;
+ pickup pencircle scaled (size/4) ;
+ if \MPvar{type}=1 :
+ for i=-1,+1 : draw origin shifted (0,i*size/4) ; endfor ;
+ elseif \MPvar{type}=2 :
+ for i=-1,+1 : draw origin shifted (-size/2,i*size/4) ; endfor ;
+ pickup pencircle scaled (size/6) ;
+ draw (size/4,0) -- (-size/4,0) ;
+ fi ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\startbuffer[sym]
+\definesymbol[smile] [\uniqueMPgraphic{smile}{type=1}]
+\definesymbol[smilemore][\uniqueMPgraphic{smile}{type=2}]
+\stopbuffer
+
+\startbuffer[exa]
+Say it with a \symbol [smile]\ or maybe even a \symbol
+[smilemore], although seeing too many \dorecurse {10}
+{\symbol [smile]\ } \unskip in one text may make you cry.
+\stopbuffer
+
+\getbuffer[def,sym]
+
+A nice application of setting up variables for a specific graphic (or class of
+graphics) is the following. In an email message the author can express his own or
+the readers expected emotions with so called smilies like: \symbol [smile]. If
+you want them in print, you can revert to combinations of characters in a font,
+but as a \TEX\ user you may want to include nicer graphics.
+
+A convenient way to implement these is to make them into symbols, one reason
+being that in that case they will adapt themselves to the current font size.
+
+\typebuffer[exa] \getbuffer[exa]
+
+Because we want an efficient implementation, we will use unique graphics, because
+these will only be generated when the circumstances change.
+
+\typebuffer[sym]
+
+The definition itself then becomes:
+
+\typebuffer[def]
+
+We can now change some characteristics of the smilies without the need to
+redefine the graphic.
+
+\startbuffer[set]
+\setupMPvariables[smile][height=1ex,color=darkred]
+\stopbuffer
+
+\typebuffer[set]
+
+\getbuffer[set,exa]
+
+In order to keep the smilies unique there is some magic involved, watch the
+second argument in the next line:
+
+\starttyping
+\startuniqueMPgraphic{smile}{type,height,color}
+\stoptyping
+
+Because unique graphics often are used in backgrounds, its uniqueness is
+determined by the overlay characteristics. In our case however the uniqueness is
+determined by the smilies type, height and color. By explicitly specifying these,
+we make sure that they count in the creation of the uniqueness stamp.
+
+\startbuffer[exa]
+\midaligned{\switchtobodyfont[60pt]\symbol[smile]}
+\stopbuffer
+
+\typebuffer[exa]
+
+Because we use the ex||height, the previous call works as expected.
+
+\startlinecorrection[blank]
+\getbuffer[exa]
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Shape libraries}]
+
+\index{graphics+libraries}
+
+Unfortunately it takes some effort to define graphics, attach them to an overlay,
+and invoke the background. However, the good news is that since in many cases we
+want a consistent layout, we only have to do it once. The next table has some
+hashed backgrounds. (More information about how to define tables can be found in
+the \CONTEXT\ documentation and Up||To||Date documents.)
+
+\startbuffer
+\bTABLE[frame=off,meta:hash:linecolor=darkyellow,offset=3ex]
+ \bTR
+ \bTD[background=meta:hash:right] right \eTD
+ \bTD[background=meta:hash:left] left \eTD
+ \bTD[background=meta:hash:horizontal] horizontal \eTD
+ \bTD[background=meta:hash:vertical] vertical \eTD
+ \eTR
+\eTABLE
+\stopbuffer
+
+\getbuffer[shape-a,shape-b,shape-c]
+
+\placetable
+ {A hashed table.}
+ {\getbuffer}
+
+This table is defined as:
+
+\typebuffer
+
+The graphics themselves are defined in a \METAPOST\ module. In this particular
+example, the macro \type {some_hash} is defined in the file \type {mp-back.mp}.
+This macro takes six arguments:
+
+\starttyping
+some_hash (width, height, linewidth, linecolor, angle, gap) ;
+\stoptyping
+
+Because we don't want to define a specific overlay for each color and linewidth,
+we will use variables in the definition of the unique graphic.
+
+\typebuffer[shape-a]
+
+These variables are preset using \type {\setupMPvariables}:
+
+\typebuffer[shape-b]
+
+The last step in this process is to define the different
+alternatives as overlays:
+
+\typebuffer[shape-c]
+
+As we can see in the definition of the table, we can pass settings to the \type
+{\bTABLE} command. Actually, we can pass such settings to each command that
+supports backgrounds, or more precisely \type {\framed}. \in {Table} [tab:hashes]
+is for instance defined as:
+
+\startbuffer
+\bTABLE[frame=off,meta:hash:linewidth=.4pt,align=middle,offset=2ex]
+ \bTR
+ \bTD[background={meta:hash:left,meta:hash:right},
+ meta:hash:linecolor=darkyellow]
+ left \par \& \par right \eTD
+ \bTD[background={meta:hash:horizontal,meta:hash:vertical},
+ meta:hash:linecolor=darkred]
+ horizontal \par \& \par vertical \eTD
+ \eTR
+\eTABLE
+\stopbuffer
+
+\typebuffer
+
+The long names are somewhat cumbersome, but in that way we can prevent name
+clashes. Also, since the \METAPOST\ interface is english, the variables are also
+english.
+
+\placetable
+ [here][tab:hashes]
+ {A double hashed table.}
+ {\getbuffer}
+
+\stopsection
+
+\startsection[title={Symbol collections}]
+
+\index{graphics+symbols}
+\index{symbols}
+
+In \CONTEXT, a symbol can be defined without much coding. The advantage of using
+symbols is that you can redefine them depending on the situation. So,
+
+\starttyping
+\definesymbol [yes] [\em Yes!]
+\stoptyping
+
+creates a symbol, that lets \type {\symbol[yes]} expand into {\em Yes!} Since
+nearly anything can be a symbol, we can also say:
+
+\starttyping
+\definesymbol [yes] [\mathematics{\star}]
+\stoptyping
+
+or even the already defined symbol \symbol[star], by saying:
+
+\starttyping
+\definesymbol [yes] [{\symbol[star]}]
+\stoptyping
+
+It may be clear that we can use a graphic as well:
+
+\typebuffer[symb-c]
+
+Since we have collected some nice buttons in a \METAPOST\ file already, we can
+use a rather simple definition:
+
+\typebuffer[symb-a]
+
+This leaves a few settings:
+
+\typebuffer[symb-b]
+
+These symbols are collected in \in {table} [tab:symbols], and are called up with
+the \CONTEXT\ commands like \type {\symbol[menu:left]}. If needed, we can collect
+these button symbols in a so called symbol set, which permits us to instantly
+switch between sets with similar symbols.
+
+\startbuffer
+\bTABLE[frame=off,width=36pt,align=middle]
+ \bTR \bTD \dontleavehmode \symbol[menu:left] \eTD
+ \bTD \dontleavehmode \symbol[menu:right] \eTD
+ \bTD \dontleavehmode \symbol[menu:list] \eTD
+ \bTD \dontleavehmode \symbol[menu:index] \eTD
+ \bTD \dontleavehmode \symbol[menu:person] \eTD
+ \bTD \dontleavehmode \symbol[menu:stop] \eTD
+ \bTD \dontleavehmode \symbol[menu:info] \eTD
+ \bTD \dontleavehmode \symbol[menu:down] \eTD
+ \bTD \dontleavehmode \symbol[menu:up] \eTD
+ \bTD \dontleavehmode \symbol[menu:print] \eTD \eTR
+ \bTR \bTD left \eTD
+ \bTD right \eTD
+ \bTD list \eTD
+ \bTD index \eTD
+ \bTD person \eTD
+ \bTD stop \eTD
+ \bTD info \eTD
+ \bTD down \eTD
+ \bTD up \eTD
+ \bTD print \eTD \eTR
+\eTABLE
+\stopbuffer
+
+\getbuffer[symb-a,symb-b,symb-c]
+
+\placetable
+ [here][tab:symbols]
+ {A collection of button symbols.}
+ {\getbuffer}
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-graphics.tex b/doc/context/sources/general/manuals/metafun/metafun-graphics.tex
new file mode 100644
index 000000000..79c5df0df
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-graphics.tex
@@ -0,0 +1,21 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-graphics
+
+\environment metafun-environment
+
+\startchapter[title={Example graphics}]
+
+\startintro
+
+In this chapter we will show some of the graphics that we made the last few years
+using \METAPOST. They give an impression of what kind of non||mathematical
+drawings can be made.
+
+\stopintro
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-index.tex b/doc/context/sources/general/manuals/metafun/metafun-index.tex
new file mode 100644
index 000000000..8be313d85
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-index.tex
@@ -0,0 +1,25 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-index
+
+\environment metafun-environment
+
+\startchapter[reference=index,title={Index}]
+
+ \startcolumns
+ \placeregister[index]
+ \stopcolumns
+
+\stopchapter
+
+% \startchapter[reference=commands,title={Commands}]
+%
+% \startcolumns
+% \placeregister[command]
+% \stopcolumns
+%
+% \stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-introduction.tex b/doc/context/sources/general/manuals/metafun/metafun-introduction.tex
new file mode 100644
index 000000000..b519055c0
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-introduction.tex
@@ -0,0 +1,101 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-introduction
+
+\environment metafun-environment
+
+\starttitle[title={Introduction}]
+
+This document is about \METAPOST\ and \TEX. The former is a graphic programming
+language, the latter a typographic programming language. However, in this
+document we will not focus on real programming, but more on how we can interface
+between those two languages. We will do so by using \CONTEXT, a macro package
+written in \TEX, in which support for \METAPOST\ is integrated in the core. The
+\TEX\ macros are integrated in \CONTEXT, and the \METAPOST\ macros are bundled in
+\METAFUN.
+
+When Donald Knuth wrote his typographical programming language \TEX\ he was in
+need for fonts, especially mathematical fonts. So, as a side track, he started
+writing \METAFONT, a graphical language. When you read between the lines in the
+\METAFONT\ book and the source code, the name John Hobby is mentioned alongside
+complicated formulas. It will be no surprise then, that, since he was tightly
+involved in the development of \METAFONT, after a few years his \METAPOST\ showed
+up.
+
+While its ancestor \METAFONT\ was originally targeted at designing fonts,
+\METAPOST\ is more oriented to drawing graphics as used in scientific
+publications. Since \METAFONT\ produced bitmap output, some of its operators make
+use of this fact. \METAPOST\ on the other hand produces \POSTSCRIPT\ code, which
+means that it has some features not present in \METAFONT\ and vice versa.
+
+With \METAFUN\ I will demonstrate that \METAPOST\ can also be used, or misused,
+for less technical drawing purposes. We will see that \METAPOST\ can fill in some
+gaps in \TEX, especially its lack of graphic capabilities. We will demonstrate
+that graphics can make a document more attractive, even if it is processed in a
+batch processing system like \TEX. Most of all, we will see that embedding
+\METAPOST\ definitions in the \TEX\ source enables a smooth communication between
+both programs.
+
+The best starting point for using \METAPOST\ is the manual written by its author
+John Hobby. You can find this manual at every main \TEX\ repository. Also, a copy
+of the \METAFONT\ book from Donald Knuth is worth every cent, if only because it
+will give you the feeling that many years of graphical fun lays ahead.
+
+In this \METAFUN\ manual we will demonstrate how you can embed graphics in a
+\TEX\ document, but we will also introduce most of the features of \METAPOST. For
+this reason you will see a lot of \METAPOST\ code. For sure there are better
+methods to solve problems, but I have tried to demonstrate different methods and
+techniques as much as possible.
+
+I started using \METAPOST\ long after I started using \TEX, and I never regret
+it. Although I like \TEX\ very much, I must admit that sometimes using \METAPOST\
+is even more fun. Therefore, before we start exploring both in depth, I want to
+thank their creators, Donald Knuth and John Hobby, for providing me these
+fabulous tools. Of course I also need to thank \THANH, for giving the \TEX\
+community \PDFTEX, as well as providing me the hooks I considered necessary for
+implementing some of the features presented here. In the meantime Taco Hoekwater
+has created the \METAPOST\ library so that it can be an integral component of
+\LUATEX. After that happened, the program was extended to deal with more than one
+number implementation: in addition to scaled integers we now can switch to floats
+and arbitrary precision decimal or binary calculations. I myself prototyped a
+simple but efficient \LUA\ script interface. With Luigi Scarso, who is now the
+maintainer of \METAPOST, we keep improving the system, so who knows what will
+show up next.
+
+I also want to thank David Arnold and Ton Otten for their fast proofreading, for
+providing me useful input, and for testing the examples. Without David's patience
+and help, this document would be far from perfect English and less complete.
+Without Ton's help, many small typos would have gone unnoticed.
+
+In the second version of this manual the content was been adapted to \CONTEXT\
+\MKIV\ that uses \LUATEX\ and the built in \METAPOST\ library. In the meantime
+some \LUA\ has been brought into the game, not only to help construct graphics,
+but also as a communication channel. In the process some extra features have been
+added and some interfacing has been upgraded. The third version of this document
+deals with that too. It makes no sense to maintain compatibility with \CONTEXT\
+\MKII, but many examples can be used there as well. In the meantime most
+\CONTEXT\ users have switched to \MKIV, so this is no real issue. In the fourth
+update some new features are presented and the discussion of obsolete ones have
+been removed.
+
+The fifth update describes the \MPIV\ version of \METAFUN\ which brings some more
+and improved functionality. Some examples are inspired from questions by users and
+examples that Alan Braslau, Luigi Scarso and I made when testing new features and
+macros. Some examples can be rewritten in a more efficient way but are kept as
+they are. Therefore this manual presents different ways to solve problems.
+Hopefully this is not too confusing. Numerous examples can be found in the other
+manuals and test suite.
+
+\blank[big,samepage]
+
+\startlines
+Hans Hagen
+Hasselt NL
+\currentdate[month,year]
+\stoplines
+
+\stoptitle
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-layout.tex b/doc/context/sources/general/manuals/metafun/metafun-layout.tex
new file mode 100644
index 000000000..2be7e19ff
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-layout.tex
@@ -0,0 +1,990 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-layout
+
+\environment metafun-environment
+
+\startchapter[title={Enhancing the layout}]
+
+\startintro
+
+One of the most powerful and flexible commands of \CONTEXT\ is \type {\framed}.
+We can use the background features of this command to invoke and position
+graphics that adapt themselves to the current situation. Once understood,
+overlays will become a natural part of the \CONTEXT\ users toolkit.
+
+\stopintro
+
+\startsection[title={Overlays}]
+
+\index{overlays}
+
+Many \CONTEXT\ commands support overlays. The term {\em overlay} is a bit
+confusing, since such an overlay in most cases will lay under the text. However,
+because there can be many layers on top of each other, the term suits its
+purpose.
+
+When we want to put a \METAPOST\ graphic under some text, we go through a three
+step process. First we define the graphic itself:
+
+\startbuffer
+\startuniqueMPgraphic{demo circle}
+ path p ;
+ p := fullcircle xscaled \overlaywidth yscaled \overlayheight ;
+ fill p withcolor .85white ;
+ draw p withpen pencircle scaled 2pt withcolor .625red ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+This graphic will adapt itself to the width and height of the overlay. Both \type
+{\overlaywidth} and \type {\overlayheight} are macros that return a dimension
+followed by a space. The next step is to register this graphic as an overlay.
+
+\startbuffer
+\defineoverlay[demo circle][\uniqueMPgraphic{demo circle}]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+We can now use this overlay in any command that provides the \type {\framed}
+functionality. Since this graphic is defined as unique, \CONTEXT\ will try to
+reuse already calculated and embedded graphics when possible.
+
+\startbuffer
+\framed[background=demo circle]{This text is overlayed.}
+\stopbuffer
+
+\typebuffer
+
+The background can be set to \type {color}, \type {screen}, an overlay
+identifier, like \typ {demo circle}, or a comma separated list of those.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+The \type {\framed} command automatically draws a ruled box, which can be quite
+useful when debugging a graphic. However, in this case we want to turn the frame
+off.
+
+\startbuffer
+\framed
+ [background=demo circle,frame=off]
+ {This text is overlayed.}
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+In this case, it would have made sense to either set the \type {offset} to a
+larger value, or to set \type {backgroundoffset}. In the latter case, the ellipse
+is positioned outside the frame.
+
+The difference between the three offsets \type {offset}, \type {frameoffset} and
+\type {backgroundoffset} is demonstrated in \in {figure} [fig:offsets]. While the
+\type {offset} is added to the (natural or specified) dimensions of the content
+of the box, the other two are applied to the frame and background and don't add
+to the dimensions.
+
+In the first row we only set the \type {offset}, while in the second row, the
+(text) offset is set to \type {3pt}. When not specified, the \type {offset} has a
+comfortable default value of \type {.25ex} (some 25\% of the height of an~x).
+
+\startbuffer
+\setupframed
+ [width=.3\textwidth,
+ background=demo circle]
+\startcombination[3*3]
+ {\framed[offset=none] {\TeX}} {\tt offset=none}
+ {\framed[offset=overlay] {\TeX}} {\tt offset=overlay}
+ {\framed[offset=0pt] {\TeX}} {\tt offset=0pt}
+ {\framed[offset=1pt] {\TeX}} {\tt offset=1pt}
+ {\framed[offset=2pt] {\TeX}} {\tt offset=2pt}
+ {\framed[offset=4pt] {\TeX}} {\tt offset=4pt}
+ {\framed[offset=3pt] {\TeX}} {\tt offset=3pt}
+ {\framed[frameoffset=3pt] {\TeX}} {\tt frameoffset=3pt}
+ {\framed[backgroundoffset=3pt]{\TeX}} {\tt backgroundoffset=3pt}
+\stopcombination
+\stopbuffer
+
+\typebuffer
+
+\placefigure
+ [here][fig:offsets]
+ {The three offsets.}
+ {\getbuffer}
+
+As the first row in \in {figure} [fig:offsets] demonstrates, instead of a value,
+one can pass a keyword. The \type {overlay} keyword implies that there is no
+offset at all and that the lines cover the content. With \type {none} the frame
+is drawn tight around the content. When the offset is set to \type {0pt} or more,
+the text is automatically set to at least the height of a line. You can turn this
+feature off by saying \type {strut=off}. More details can be found in the
+\CONTEXT\ manual.
+
+In \in {figure} [fig:all offsets] we have set {offset} to \type {3pt}, \type
+{frameoffset} to \type {6pt} and \type {backgroundoffset} to \type {9pt}. Both
+the frame and background offset are sort of imaginary, since they don't
+contribute to the size of the box.
+
+\startbuffer
+\ruledhbox
+ {\framed
+ [offset=3pt,frameoffset=6pt,backgroundoffset=9pt,
+ background=screen,backgroundscreen=.85]
+ {Welcome in the hall of frame!}}
+\stopbuffer
+
+\typebuffer
+
+\placefigure
+ [here][fig:all offsets]
+ {The three offsets.}
+ {\getbuffer}
+
+\stopsection
+
+\startsection[title={Overlay variables}]
+
+The communication between \TEX\ and embedded \METAPOST\ graphics takes place by
+means of some macros.
+
+\starttabulate[|l|p|]
+\HL
+\NC overlay status macro \NC meaning \NC \NR
+\HL
+\NC \tex {overlaywidth} \NC the width of the graphic, as
+ calculated from the actual
+ width and background offset \NC \NR
+\NC \tex {overlayheight} \NC the height of the graphic, as
+ calculated from the actual
+ height, depth and background
+ offset \NC \NR
+\NC \tex {overlaydepth} \NC the depth of the graphic, if
+ available \NC \NR
+\NC \tex {overlaycolor} \NC the background color, if given \NC \NR
+\NC \tex {overlaylinecolor} \NC the color of the frame \NC \NR
+\NC \tex {overlaylinewidth} \NC the width of the frame \NC \NR
+\HL
+\stoptabulate
+
+The dimensions of the overlay are determined by dimensions of the background,
+which normally is the natural size of a \type {\framed}. When a background offset
+is specified, it is added to \type {overlayheight} and \type {overlaywidth}.
+
+Colors can be converted by \type {\MPcolor} and in addition to the macros
+mentioned, you can use all macros that expand into a dimension or dimen register
+prefixed by the \TEX\ primitive \type {\the} (this and other primitives are
+explained in \quotation {The \TeX book}, by Donald Knuth).
+
+\stopsection
+
+\startsection[title={Stacking overlays}]
+
+A background can be a gray scale (\type {screen}), a color (\type {color}), a
+previously defined overlay identifier, or any combination of these. The next
+assignments are therefore valid:
+
+\starttyping
+\framed[background=color,backgroundcolor=red]{...}
+\framed[background=screen,backgroundscreen=.8]{...}
+\framed[background=circle]{...}
+\framed[background={color,cow},backgroundcolor=red]{...}
+\framed[background={color,cow,grid},backgroundcolor=red]{...}
+\stoptyping
+
+In the last three cases of course you have to define \type {circle}, \type {cow}
+and \type {grid} as overlay. These items are packed in a comma separated list,
+which has to be surrounded by \type {{}}.
+
+\stopsection
+
+\startsection[title={Foregrounds}]
+
+\startbuffer[a]
+\startuniqueMPgraphic{backfore}
+ draw fullcircle
+ xscaled \overlaywidth yscaled \overlayheight
+ withpen pencircle scaled 2pt
+ withcolor .625yellow ;
+\stopuniqueMPgraphic
+
+\defineoverlay[backfore][\uniqueMPgraphic{backfore}]
+\stopbuffer
+
+\startbuffer[b]
+\framed
+ [background=backfore,backgroundoffset=4pt]
+ {one, two, three, \unknown}
+\stopbuffer
+
+\startbuffer[c]
+\framed
+ [background={foreground,backfore},backgroundoffset=4pt]
+ {one, two, three, \unknown}
+\stopbuffer
+
+The overlay system is actually a system of layers. Sometimes we are confronted
+with a situation in which we want the text behind another layer. This can be
+achieved by explicitly placing the foreground layer, as in \in {figure}
+[fig:foreground].
+
+\getbuffer[a]
+
+\placefigure
+ [here][fig:foreground]
+ {Foreground material moved backwards.}
+ {\setupframed[linewidth=1pt]%
+ \startcombination
+ {\getbuffer[b]} {frame on top layer}
+ {\getbuffer[c]} {frame on bottom layer}
+ \stopcombination}
+
+The graphic layer is defined as follows:
+
+\typebuffer[a]
+
+The two framed texts have a slightly different definition. The leftmost graphic
+is defined as:
+
+\typebuffer[b]
+
+The rightmost graphic is specified as:
+
+\typebuffer[c]
+
+The current values of the frame color and frame width are passed to the overlay.
+It often makes more sense to use colors defined at the document level, if only to
+force consistency.
+
+\startbuffer
+\startuniqueMPgraphic{super ellipse}
+ path p ; p := unitsquare
+ xscaled \overlaywidth yscaled \overlayheight
+ superellipsed .85 ;
+ pickup pencircle scaled \overlaylinewidth ;
+ fill p withcolor \MPcolor{\overlaycolor} ;
+ draw p withcolor \MPcolor{\overlaylinecolor} ;
+\stopuniqueMPgraphic
+
+\defineoverlay[super ellipse][\uniqueMPgraphic{super ellipse}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This background demonstrates that a super ellipse is rather well suited as frame.
+
+\startbuffer
+\framed
+ [background=super ellipse,
+ frame=off,
+ width=3cm,
+ align=middle,
+ framecolor=darkyellow,
+ rulethickness=2pt,
+ backgroundcolor=darkgray]
+ {\white This is a\\Super Ellipsed\\sentence.}
+\stopbuffer
+
+\typebuffer
+
+Such a super ellipse looks quite nice and is a good candidate for backgrounds,
+for which the superness should be at least~.85.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Typesetting graphics}]
+
+I have run into people who consider it kind of strange when you want to use \TEX\
+for non||mathematical typesetting. If you agree with them, you may skip this
+section with your eyes closed.
+
+One of the \CONTEXT\ presentation styles (number 15, tagged as balls) stepwise
+builds screens full of sentences, quotes or concepts, packages in balloons and
+typesets them as a paragraph. We will demonstrate that \TEX\ can typeset graphics
+using the following statement.
+
+% \let\processword\relax
+
+\startbuffer[lions]
+\processwords{As you may know, \TEX's ambassador is a lion, while {\METAFONT}
+is represented by a lioness. It is still unclear if they have a relationship,
+but if so, and if a cub is born, may it enjoy \METAFUN.}
+\stopbuffer
+
+\startquotation
+\def\processwords#1{#1}\getbuffer[lions]
+\stopquotation
+
+The low level \CONTEXT\ macro \type {\processwords} provides a mechanism to treat
+the individual words of its argument. The macro is called as follows:
+
+\typebuffer[lions]
+
+In order to perform a task, you should also define a macro \type {\processword},
+which takes one argument. The previous quote was typeset with the following
+definition in place:
+
+\starttyping
+\def\processword#1{#1}
+\stoptyping
+
+A slightly more complicated definition is the following:
+
+\startbuffer
+\def\processword#1{\noindent\framed{#1}\space}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We now get:
+
+\blank\getbuffer[lions]\blank
+
+If we can use \type {\framed}, we can also use backgrounds.
+
+\startbuffer
+\def\processword#1%
+ {\noindent\framed[frame=off,background=lions]{#1} }
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We can add a supperellipsed frame using the following definition:
+
+\startbuffer
+\startuniqueMPgraphic{lions a}
+ path p ; p := fullsquare
+ xyscaled (\overlaywidth,\overlayheight) superellipsed .85 ;
+ pickup pencircle scaled 1pt ;
+ fill p withcolor .850white ; draw p withcolor .625yellow ;
+\stopuniqueMPgraphic
+
+\defineoverlay[lions][\uniqueMPgraphic{lions a}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\bgroup \blank \veryraggedright\getbuffer[lions]\unskip \blank \egroup
+
+\startbuffer
+\startuseMPgraphic{lions b}
+ path p ; p := fullsquare
+ xyscaled (\overlaywidth,\overlayheight) randomized 5pt ;
+ pickup pencircle scaled 1pt ;
+ fill p withcolor .850white ; draw p withcolor .625yellow ;
+\stopuseMPgraphic
+
+\defineoverlay[lions][\uniqueMPgraphic{lions b}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\bgroup \blank \veryraggedcenter\getbuffer[lions]\unskip \blank \egroup
+
+\startbuffer
+\startuniqueMPgraphic{lions c}
+ path p ; p := fullsquare
+ xyscaled (\overlaywidth,\overlayheight) squeezed 2pt ;
+ pickup pencircle scaled 1pt ;
+ fill p withcolor .850white ; draw p withcolor .625yellow ;
+\stopuniqueMPgraphic
+
+\defineoverlay[lions][\uniqueMPgraphic{lions c}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\bgroup \blank \veryraggedleft\getbuffer[lions]\unskip \blank \egroup
+
+These paragraphs were typeset with the following settings.
+
+\starttyping
+\setupalign[broad, right] % == \veryraggedright
+\setupalign[broad, middle] % == \veryraggedcenter
+\setupalign[broad, left] % == \veryraggedleft
+\stoptyping
+
+The \type {broad} increases the raggedness. We defined three different graphics
+(a, b and c) because we want some to be unique, which saves some processing. Of
+course we don't reuse the random graphics. In the definition of \type
+{\processword} we have to use \type {\noindent} because otherwise \TEX\ will put
+each graphic on a line of its own. Watch the space at the end of the macro.
+
+\stopsection
+
+\startsection[title={Graphics and macros}]
+
+Because \TEX's typographic engine and \METAPOST's graphic engine are separated,
+interfacing between them is not as natural as you may expect. In \CONTEXT\ we
+have tried to integrate them as much as possible, but using the interface is not
+always as convenient as it should be. What method you follow, depends on the
+problem at hand.
+
+The official \METAPOST\ way to embed \TEX\ code into graphics is to use \typ
+{btex ... etex}. As soon as \CONTEXT\ writes the graphic data to the intermediate
+\METAPOST\ file, it looks for these commands. When it has encountered an \type
+{etex}, \CONTEXT\ will make sure that the text that is to be typeset by \TEX\ is
+{\em not} expanded. This is what you may expect, because when you would embed
+those commands in a stand||alone graphic, they would also not be expanded, if
+only because \METAPOST\ does not know \TEX. With expansion we mean that \TEX\
+commands are replaced by their meaning (which can be quite extensive).
+
+{\em Users of \CONTEXT\ MKIV\ can skip the next paragraph}.
+
+When \METAPOST\ sees a \type {btex} command, it will consult a so called \type
+{mpx} file. This file holds the \METAPOST\ representation of the text typeset by
+\TEX. Before \METAPOST\ processes a graphic definition file, it first calls
+another program that filters the \type {btex} commands from the source file, and
+generates a \TEX\ file from them. This file is then processed by \TEX, and after
+that converted to a \type {mpx} file. In \CONTEXT\ we let \TEXEXEC\ take care of
+this whole process.
+
+Because the \typ {btex ... etex} commands are filtered from the raw \METAPOST\
+source code, they cannot be part of macro definitions and loop constructs. When
+used that way, only one instance would be found, while in practice multiple
+instances may occur.
+
+This drawback is overcome by \METAFUN's \type {textext} command. This command
+still uses \typ {btex ... etex} but writes these commands to a separate job
+related file each time it is used. \footnote {It took the author a while to find
+out that there is a \METAPOST\ module called \type {tex.mp} that provides a
+similar feature, but with the disadvantage that each text results in a call to
+\TEX. Each text goes into a temporary file, which is then included and results in
+\METAPOST\ triggering \TEX.} After the first \METAPOST\ run, this file is merged
+with the original file, and \METAPOST\ is called again. So, at the cost of an
+additional run, we can use text typeset by \TEX\ in a more versatile way. Because
+\METAPOST\ runs are much faster than \TEX\ runs, the price to pay in terms of run
+time is acceptable. Unlike \typ {btex ... etex}, the \TEX\ code in \type
+{textext} command is expanded, but as long as \CONTEXT\ is used this is seldom a
+problem, because most commands are somewhat protected.
+
+If we define a graphic with text to be typeset by \TEX, there is a good chance
+that this text is not frozen but passes as argument. A \TEX||like solution for
+passing arbitrary content to such a graphic is the following: \footnote {The \type
+{\unexpanded} prefix makes the command robust for being passed as argument. It is not
+to be confused with the primitive. We had this feature already when the primitive
+showed up and it was considered to be inconvenient for other macro packages to adapt to
+the \CONTEXT\ situation. So keep that in mind when you mix macro packages.}
+
+\startbuffer[def]
+\unexpanded\def\RotatedText#1#2%
+ {\startuseMPgraphic{RotatedText}
+ draw btex #2 etex rotated #1 ;
+ \stopuseMPgraphic
+ \useMPgraphic{RotatedText}}
+\stopbuffer
+
+\typebuffer[def] \getbuffer[def]
+
+This macro takes two arguments (the \type {#} identifies an
+argument):
+
+\startbuffer[exa]
+\RotatedText{15}{Some Rotated Text}
+\stopbuffer
+
+\typebuffer[exa]
+
+The text is rotated over 15 degrees about the origin in a counterclockwise
+direction.
+
+\startlinecorrection[blank]
+\getbuffer[exa]
+\stoplinecorrection
+
+In \CONTEXT\ we seldom pass settings like the angle of rotation in this manner.
+You can use \type {\setupMPvariables} to set up graphic||specific variables. Such
+a variable can be accessed with \type {\MPvar}.
+
+\startbuffer[def]
+\setupMPvariables[RotatedText][rotation=90]
+
+\startuseMPgraphic{RotatedText}
+ draw textext{Some Text} rotated \MPvar{rotation} ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[def] \getbuffer[def]
+
+An example:
+
+\startbuffer[exa]
+\RotatedText{-15}{Some Rotated Text}
+\stopbuffer
+
+\typebuffer[exa]
+
+\startlinecorrection[blank]
+\getbuffer[exa]
+\stoplinecorrection
+
+In a similar fashion we can isolate the text. This permits us to use the same
+graphics with different settings.
+
+\startbuffer[def]
+\setupMPvariables[RotatedText][rotation=270]
+
+\setMPtext{RotatedText}{Some Text}
+
+\startuseMPgraphic{RotatedText}
+ draw \MPbetex{RotatedText} rotated \MPvar{rotation} ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[def] \getbuffer[def]
+
+This works as expected:
+
+\startbuffer[exa]
+\RotatedText{165}{Some Rotated Text}
+\stopbuffer
+
+\typebuffer[exa]
+
+\startlinecorrection[blank]
+\getbuffer[exa]
+\stoplinecorrection
+
+It is now a small step towards an encapsulating macro (we assume that you are
+familiar with \TEX\ macro definitions).
+
+\startbuffer[def]
+\def\RotatedText[#1]#2%
+ {\setupMPvariables[RotatedText][#1]%
+ \setMPtext{RotatedText}{#2}%
+ \useMPgraphic{RotatedText}}
+
+\setupMPvariables[RotatedText][rotation=90]
+
+\startuseMPgraphic{RotatedText}
+ draw \MPbetex{RotatedText} rotated \MPvar{rotation} ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[def] \getbuffer[def]
+
+Again, we default to a 90 degrees rotation, and pass both the settings and text
+in an indirect way. This method permits you to build complicated graphics and
+still keep macros readable.
+
+\startbuffer[exa]
+\RotatedText[rotation=240]{Some Rotated Text}
+\stopbuffer
+
+\typebuffer[exa]
+
+\startlinecorrection[blank]
+\getbuffer[exa]
+\stoplinecorrection
+
+You may wonder why we don't use the variable mechanism to pass the text. The main
+reason is that the text mechanism offers a few more features, one of which is
+that it passes the text straight on, without the danger of unwanted expansion of
+embedded macros. Using \type {\setMPtext} also permits you to separate \TEX\ and
+\METAPOST\ code and reuse it multiple times (imagine using the same graphic in a
+section head command).
+
+There are three ways to access a text defined with \type {\setMPtext}. Imagine
+that we have the following definitions:
+
+\startbuffer
+\setMPtext {1} {Now is this \TeX\ or not?}
+\setMPtext {2} {See what happens here.}
+\setMPtext {3} {Text streams become pictures.}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The \type {\MPbetex} macro returns a \typ {btex ... etex} construct. The \type
+{\MPstring} returns the text as a \METAPOST\ string, between quotes. The raw text
+can be fetched with \type {\MPtext}.
+
+\startbuffer
+\startMPcode
+ picture p ; p := \MPbetex {1} ;
+ picture q ; q := textext( \MPstring{2} ) ;
+ picture r ; r := thelabel("\MPtext {3}",origin) ;
+
+ for i=p, boundingbox p : draw i withcolor .625red ; endfor ;
+ for i=q, boundingbox q : draw i withcolor .625yellow ; endfor ;
+ for i=r, boundingbox r : draw i withcolor .625white ; endfor ;
+
+ currentpicture := currentpicture scaled 2 ;
+ draw origin
+ withpen pencircle scaled 5.0mm withcolor white ;
+ draw origin
+ withpen pencircle scaled 2.5mm withcolor black ;
+ draw boundingbox currentpicture
+ withpen pencircle scaled .1mm
+ dashed evenly ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+The first two lines return text typeset by \TEX, while the last line leaves this
+to \METAPOST.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+If you watch closely, you will notice that the first (red) alternative is
+positioned with the baseline on the origin.
+
+\startbuffer
+\startMPcode
+ picture p ; p := \MPbetex {1} ;
+ picture q ; q := textext.origin( \MPstring{2} ) ;
+ picture r ; r := thelabel.origin("\MPtext {3}",origin) ;
+
+ for i=p, boundingbox p : draw i withcolor .625red ; endfor ;
+ for i=q, boundingbox q : draw i withcolor .625yellow ; endfor ;
+ for i=r, boundingbox r : draw i withcolor .625white ; endfor ;
+
+ currentpicture := currentpicture scaled 2 ;
+ draw origin withpen pencircle scaled 5.0mm
+ withcolor white ;
+ draw origin withpen pencircle scaled 2.5mm
+ withcolor black ;
+ draw boundingbox currentpicture
+ withpen pencircle scaled .1mm
+ dashed evenly ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+This draws:
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+This picture demonstrates that we can also position \type {textext}'s and \type
+{label}'s on the baseline. For this purpose the repertoire of positioning
+directives (\type {top}, \type {lft}, etc.) is extended with an \type {origin}
+directive. Another extra positioning directive is \type {raw}. This one does not
+do any positioning at all.
+
+\starttyping
+picture q ; q := textext.origin( \MPstring{2} ) ;
+picture r ; r := thelabel.origin("\MPtext {3}",origin) ;
+\stoptyping
+
+We will now apply this knowledge of text inclusion in graphics to a more advanced
+example. The next definitions are the answer to a question on the \CONTEXT\
+mailinglist with regards to framed texts with titles.
+
+\startbuffer[a]
+\defineoverlay[FunnyFrame][\useMPgraphic{FunnyFrame}]
+
+\defineframedtext[FunnyText][frame=off,background=FunnyFrame]
+
+\def\StartFrame{\startFunnyText}
+\def\StopFrame {\stopFunnyText }
+
+\def\FrameTitle#1%
+ {\setMPtext{FunnyFrame}{\hbox spread 1em{\hss\strut#1\hss}}}
+
+\setMPtext{FunnyFrame}{} % initialize the text variable
+\stopbuffer
+
+\startbuffer[b]
+\startuseMPgraphic{FunnyFrame}
+ picture p ; numeric w, h, o ;
+ p := textext.rt(\MPstring{FunnyFrame}) ;
+ w := OverlayWidth ; h := OverlayHeight ; o := BodyFontSize ;
+ p := p shifted (2o,h-ypart center p) ; draw p ;
+ drawoptions (withpen pencircle scaled 1pt withcolor .625red) ;
+ draw (2o,h)--(0,h)--(0,0)--(w,0)--(w,h)--(xpart urcorner p,h) ;
+ draw boundingbox p ;
+ setbounds currentpicture to unitsquare xyscaled(w,h) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[c1]
+\FrameTitle{Zapf (1)}
+
+\StartFrame
+Coming back to the use of typefaces in electronic
+publishing: many of the new typographers receive their
+knowledge and information about the rules of typography from
+books, from computer magazines or the instruction manuals
+which they get with the purchase of a PC or software.
+\StopFrame
+\stopbuffer
+
+\getbuffer[a,b,c1]
+
+In this example, the title is positioned on top of the frame. Title and text are
+entered as:
+
+\typebuffer[c1]
+
+The implementation is not that complicated and uses the frame commands that are
+built in \CONTEXT. Instead of letting \TEX\ draw the frame, we use \METAPOST,
+which we also use for handling the title. The graphic is defined as follows:
+
+\typebuffer[b]
+
+Because the framed title is partly positioned outside the main frame, and because
+the main frame will be combined with the text, we need to set the boundingbox
+explicitly. This is a way to create so called free figures, where part of the
+figure lays beyond the area that is taken into account when positioning the
+graphic. The shift
+
+\starttyping
+... shifted (2o,h-ypart center p)
+\stoptyping
+
+ensures that the title is vertically centered over the top line of the main box.
+
+The macros that use this graphic combine some techniques of defining macros,
+using predefined \CONTEXT\ classes, and passing information to graphics.
+
+\typebuffer[a]
+
+There is a little bit of low level \TEX\ code involved, like a horizontal box
+(\type {\hbox}) that stretches one em||space beyond its natural size (\type
+{spread 1em}) with a centered text (two times \type {\hss}). Instead of applying
+this spread, we could have enlarged the frame on both sides.
+
+\startbuffer[b]
+\startuseMPgraphic{FunnyFrame}
+ picture p ; numeric o ; path a, b ; pair c ;
+ p := textext.rt(\MPstring{FunnyFrame}) ;
+ a := unitsquare xyscaled(OverlayWidth,OverlayHeight) ;
+ o := BodyFontSize ;
+ p := p shifted (2o,OverlayHeight-ypart center p) ;
+ drawoptions (withpen pencircle scaled 1pt withcolor .625red) ;
+ b := a randomized (o/2) ;
+ fill b withcolor .85white ; draw b ;
+ b := (boundingbox p) randomized (o/8) ;
+ fill b withcolor .85white ; draw b ;
+ draw p withcolor black;
+ setbounds currentpicture to a ;
+ \stopuseMPgraphic
+\stopbuffer
+
+In the previous graphic we calculated the big rectangle taking the small one into
+account. This was needed because we don't use a background fill. The next
+definition does, so there we can use a more straightforward approach by just
+drawing (and filling) the small rectangle on top of the big one.
+
+\typebuffer[b] \getbuffer[b]
+
+\startbuffer[c2]
+\FrameTitle{Zapf (2)}
+
+\StartFrame
+There is not so much basic instruction, as of now, as there
+was in the old days, showing the differences between good
+and bad typographic design.
+\StopFrame
+\stopbuffer
+
+\getbuffer[c2]
+
+Because we use a random graphic, we cannot guarantee beforehand that the left and
+right edges of the small shape touch the horizontal lines in a nice way. The next
+alternative displaces the small shape plus text so that its center lays on the
+line. On the average, this looks better.
+
+\startbuffer[b]
+\startuseMPgraphic{FunnyFrame}
+ picture p ; numeric o ; path a, b ; pair c ;
+ p := textext.rt(\MPstring{FunnyFrame}) ;
+ a := unitsquare xyscaled(OverlayWidth,OverlayHeight) ;
+ o := BodyFontSize ;
+ p := p shifted (2o,OverlayHeight-ypart center p) ;
+ drawoptions (withpen pencircle scaled 1pt withcolor .625red) ;
+ b := a randomized (o/2) ;
+ fill b withcolor .85white ; draw b ;
+ c := center p ;
+ c := b intersectionpoint (c shifted (0,-o)--c shifted(0,o)) ;
+ p := p shifted (c-center p) ;
+ b := (boundingbox p) randomized (o/8) ;
+ fill b withcolor .85white ; draw b ;
+ draw p withcolor black;
+ setbounds currentpicture to a ;
+ \stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[b] \getbuffer[b]
+
+\getbuffer[c2]
+
+Yet another definition uses super ellipsed shapes instead of random ones. We need
+a high degree of superness (.95) in order to make sure that the curves don't
+touch the texts.
+
+\startbuffer[b]
+\startuseMPgraphic{FunnyFrame}
+ picture p ; numeric o ; path a, b ; pair c ;
+ p := textext.rt(\MPstring{FunnyFrame}) ;
+ o := BodyFontSize ;
+ a := unitsquare xyscaled(OverlayWidth,OverlayHeight) ;
+ p := p shifted (2o,OverlayHeight-ypart center p) ;
+ drawoptions (withpen pencircle scaled 1pt withcolor .625red) ;
+ b := a superellipsed .95 ;
+ fill b withcolor .85white ; draw b ;
+ b := (boundingbox p) superellipsed .95 ;
+ fill b withcolor .85white ; draw b ;
+ draw p withcolor black ;
+ setbounds currentpicture to a ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[b] \getbuffer[b]
+
+\startbuffer[c3]
+\FrameTitle{Zapf (3)}
+
+\StartFrame
+Many people are just fascinated by their PC's tricks, and
+think that a widely||praised program, called up on the
+screen, will make everything automatic from now on.
+\StopFrame
+\stopbuffer
+
+\getbuffer[c3]
+
+There are quite some hard coded values in these graphics, like the linewidths,
+offsets and colors. Some of these can be fetched from the \type {\framed}
+environment either by using \TEX\ macros or dimensions, or by using their
+\METAFUN\ counterparts. In the following table we summarize both the available
+\METAPOST\ variables and their \TEX\ counterparts. They may be used
+interchangeably.
+
+\starttabulate[|l|Tl|l|]
+\HL
+\NC \bf \METAPOST\ variable \NC \rm \bf \TEX\ command \NC \bf meaning \NC\NR
+\HL
+\NC OverlayWidth \NC \string\overlaywidth
+ \NC current width \NC\NR
+\NC OverlayHeight \NC \string\overlayheight
+ \NC current height \NC\NR
+\NC OverlayDepth \NC \string\overlayheight
+ \NC current depth (often zero) \NC\NR
+\NC OverlayColor \NC \string\MPcolor\string{\string\overlaycolor\string}
+ \NC background color \NC\NR
+\NC OverlayLineWidth \NC \string\overlaylinewidth
+ \NC width of the frame \NC\NR
+\NC OverlayLineColor \NC \string\MPcolor\string{\overlaylinecolor\string}
+ \NC color of the frame \NC\NR
+\NC BaseLineSkip \NC \string\the\string\baselineskip
+ \NC main line distance \NC\NR
+\NC LineHeight \NC \string\the\string\baselineskip
+ \NC idem \NC\NR
+\NC BodyFontSize \NC \string\the\string\bodyfontsize
+ \NC font size of the running text \NC\NR
+\NC StrutHeight \NC \string\strutheight
+ \NC space above the baseline \NC\NR
+\NC StrutDepth \NC \string\strutdepth
+ \NC space below the baseline \NC\NR
+\NC ExHeight \NC 1ex
+ \NC height of an x \NC \NR
+\NC EmWidth \NC 1em
+ \NC width of an m-dash \NC \NR
+\HL
+\stoptabulate
+
+\startbuffer[b]
+\startuseMPgraphic{FunnyFrame}
+ picture p ; numeric o ; path a, b ; pair c ;
+ p := textext.rt(\MPstring{FunnyFrame}) ;
+ o := BodyFontSize ;
+ a := unitsquare xyscaled(OverlayWidth,OverlayHeight) ;
+ p := p shifted (2o,OverlayHeight-ypart center p) ;
+ pickup pencircle scaled OverlayLineWidth ;
+ b := a superellipsed .95 ;
+ fill b withcolor OverlayColor ;
+ draw b withcolor OverlayLineColor ;
+ b := (boundingbox p) superellipsed .95 ;
+ fill b withcolor OverlayColor ;
+ draw b withcolor OverlayLineColor ;
+ draw p withcolor black ;
+ setbounds currentpicture to a ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[b] \getbuffer[b]
+
+\startbuffer[d]
+\setupframedtexts
+ [FunnyText]
+ [backgroundcolor=lightgray,
+ framecolor=darkred,
+ rulethickness=2pt,
+ offset=\bodyfontsize,
+ before={\blank[big,medium]},
+ after={\blank[big]},
+ width=\textwidth]
+\stopbuffer
+
+\getbuffer[d,c3]
+
+We used the following command to pass the settings:
+
+\typebuffer[d]
+
+In a real implementation, we should also take care of some additional spacing
+before the text, which is why we have added more space before than after the
+framed text.
+
+We demonstrated that when defining graphics that are part of the layout, you need
+to have access to information known to the typesetting engine. Take \in {figure}
+[fig:penalty]. The line height needs to match the font and the two thin
+horizontal lines should match the {\em x}||height. We also need to position the
+baseline, being the lowest one of a pair of lines, in such a way that it suits
+the proportions of the line as specified by the strut. A strut is an imaginary
+large character with no width. You should be aware of the fact that while \TEX\
+works its way top||down, in \METAPOST\ the origin is in the lower left corner.
+
+\startmode[screen]
+
+\placefigure
+ [page][fig:penalty]
+ {Penalty lines.}
+ {\typesetfile[mfun-902.tex][page=1,frame=on,height=.85\textheight]}
+
+\stopmode
+
+\startnotmode[screen]
+
+\placefigure
+ [here][fig:penalty]
+ {Penalty lines.}
+ {\typesetfile[mfun-902.tex][page=1,frame=on,height=.50\textheight]}
+
+\stopnotmode
+
+\typebuffer[handwrit]
+
+This code demonstrates the use of \type {LineHeight}, \type {ExHeight}, \type
+{StrutHeight} and \type {StrutDepth}. We set the interline spacing to 1.5 so that
+we get a bit more loose layout. The variables mentioned are set each time a
+graphic is processed and thereby match the current font settings.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-lua.tex b/doc/context/sources/general/manuals/metafun/metafun-lua.tex
new file mode 100644
index 000000000..da35cccde
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-lua.tex
@@ -0,0 +1,1060 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+% this is an extension of about-lua
+
+\startcomponent mfun-lua
+
+\environment metafun-environment
+
+\startchapter[title={Lua}]
+
+\index{\LUA}
+
+\startintro
+
+Already for some years I have been wondering how it would be if we could escape
+to \LUA\ inside \METAPOST, or in practice, use \MPLIB\ in \LUATEX. The idea is
+simple: embed \LUA\ code in a \METAPOST\ file that gets run as soon as it's seen.
+In case you wonder why \LUA\ code makes sense, imagine generating graphics using
+external data. The capabilities of \LUA\ to deal with that is more flexible and
+advanced than in \METAPOST. Of course we could generate a \METAPOST\ definition
+of a graphic from data but often it makes more sense to do the reverse. I finally
+found time and reason to look into this and in the following sections I will
+describe how it's done.
+
+\stopintro
+
+\startsection[title=Introduction]
+
+\stopsection
+
+\startsection[title=The basics]
+
+The approach is comparable to \LUATEX's \type {\directlua}. That primitive can be
+used to execute \LUA\ code and in combination with \type {tex.print} we can pipe
+back strings into the \TEX\ input stream. There a complication is that that we
+have to be able to operate under different so called catcode regimes: the meaning
+of characters can differ per regime. We also have to deal with line endings in
+special ways as they relate to paragraphs and such. In \METAPOST\ we don't have
+that complication so getting back input into the \METAPOST\ input, we can do so
+with simple strings. For that a mechanism similar to \type {scantokens} can be
+used. That way we can return anything (including nothing) as long as \METAPOST\
+can interpret it and as long as it fulfils the expectations.
+
+\starttyping
+numeric n ; n := scantokens("123.456") ;
+\stoptyping
+
+A script is run as follows:
+
+\starttyping
+numeric n ; n := runscript("return '123.456'") ;
+\stoptyping
+
+This primitive doesn't have the word \type {lua} in its name so in principle any
+wrapper around the library can use it as hook. In the case of \LUATEX\ the script
+language is of course \LUA. At the \METAPOST\ end we only expect a string. How
+that string is constructed is completely up to the \LUA\ script. In fact, the
+user is completely free to implement the runner any way she or he wants, like:
+
+\starttyping
+local function scriptrunner(code)
+ local f = loadstring(code)
+ if f then
+ return tostring(f())
+ else
+ return ""
+ end
+end
+\stoptyping
+
+This is hooked into an instance as follows:
+
+\starttyping
+local m = mplib.new {
+ ...
+ run_script = scriptrunner,
+ ...
+}
+\stoptyping
+
+Now, beware, this is not the \CONTEXT\ way. We provide print functions and other
+helpers, which we will explain in the next section.
+
+\stopsection
+
+\startsection[title=Helpers]
+
+After I got this feature up and running I played a bit with possible interfaces
+at the \CONTEXT\ (read: \METAFUN) end and ended up with a bit more advanced runner
+where no return value is used. The runner is wrapped in the \type {lua} macro.
+
+\startbuffer
+numeric n ; n := lua("mp.print(12.34567)") ;
+draw textext(n) xsized 4cm withcolor darkred ;
+\stopbuffer
+
+\typebuffer
+
+This renders as:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+In case you wonder how efficient calling \LUA\ is, don't worry: it's fast enough,
+especially if you consider suboptimal \LUA\ code and the fact that we switch
+between machineries.
+
+\startbuffer
+draw image (
+ lua("statistics.starttiming()") ;
+ for i=1 upto 10000 : draw
+ lua("mp.pair(math.random(-200,200),math.random(-50,50))") ;
+ endfor ;
+ setbounds currentpicture to fullsquare xyscaled (400,100) ;
+ lua("statistics.stoptiming()") ;
+) withcolor darkyellow withpen pencircle scaled 1 ;
+draw textext(lua("mp.print(statistics.elapsedtime())"))
+ ysized 50 withcolor darkred ;
+\stopbuffer
+
+\typebuffer
+
+Here the line:
+
+\starttyping
+draw lua("mp.pair(math.random(-200,200),math.random(-50,50))") ;
+\stoptyping
+
+effectively becomes (for instance):
+
+\starttyping
+draw scantokens "(25,40)" ;
+\stoptyping
+
+which in turn becomes:
+
+\starttyping
+draw scantokens (25,40) ;
+\stoptyping
+
+The same happens with this:
+
+\starttyping
+draw textext(lua("mp.print(statistics.elapsedtime())")) ...
+\stoptyping
+
+This becomes for instance:
+
+\starttyping
+draw textext(scantokens "1.23") ...
+\stoptyping
+
+and therefore:
+
+\starttyping
+draw textext(1.23) ...
+\stoptyping
+
+We can use \type {mp.print} here because the \type {textext} macro can deal with
+numbers. The next also works:
+
+\starttyping
+draw textext(lua("mp.quoted(statistics.elapsedtime())")) ...
+\stoptyping
+
+Now we get (in \METAPOST\ speak):
+
+\starttyping
+draw textext(scantokens (ditto & "1.23" & ditto) ...
+\stoptyping
+
+Here \type {ditto} represents the double quotes that mark a string. Of course,
+because we pass the strings directly to \type {scantokens}, there are no outer
+quotes at all, but this is how it can be simulated. In the end we have:
+
+\starttyping
+draw textext("1.23") ...
+\stoptyping
+
+What you use, \type {mp.print} or \type {mp.quoted} depends on what the expected
+code is: an assignment to a numeric can best be a number or an expression
+resulting in a number.
+
+This graphic becomes:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The runtime on my current machine is some 0.25 seconds without and 0.12 seconds
+with caching. But to be honest, speed is not really a concern here as the amount
+of complex \METAPOST\ graphics can be neglected compared to extensive node list
+manipulation. With \LUAJITTEX\ generating the graphic takes 15\% less time.
+
+\startbuffer
+numeric n ; n := lua("mp.print(1) mp.print('+') mp.print(2)") ;
+draw textext(n) xsized 1cm withcolor darkred ;
+\stopbuffer
+
+The three print command accumulate their arguments:
+
+\typebuffer
+
+As expected we get:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\startbuffer
+numeric n ; n := lua("mp.print(1,'+',2)") ;
+draw textext(n) xsized 1cm withcolor darkred ;
+\stopbuffer
+
+Equally valid is:
+
+\typebuffer
+
+This gives the same result:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Of course all kind of action can happen between the prints. It is also legal to
+have nothing returned as could be seen in the 10.000 dot example: there the timer
+related code returns nothing so effectively we have \type {scantokens("")}. Another
+helper is \type {mp.quoted}, as in:
+
+\startbuffer
+draw
+ textext(lua("mp.quoted('@0.3f'," & decimal n & ")"))
+ withcolor darkred ;
+\stopbuffer
+
+\typebuffer
+
+This typesets \processMPbuffer. Watch the \type {@}. When no percent character is
+found in the format specifier, we assume that an \type {@} is used instead.
+
+\startbuffer
+\startluacode
+table.save("demo-data.lua",
+ {
+ { 1, 2 }, { 2, 4 }, { 3, 3 }, { 4, 2 },
+ { 5, 2 }, { 6, 3 }, { 7, 4 }, { 8, 1 },
+ }
+)
+\stopluacode
+\stopbuffer
+
+But, the real benefit of embedded \LUA\ is when we deal with data that is stored
+at the \LUA\ end. First we define a small dataset:
+
+\typebuffer
+
+\getbuffer
+
+There are several ways to deal with this table. I will show clumsy as well as
+better looking ways.
+
+\startbuffer
+lua("MP = { } MP.data = table.load('demo-data.lua')") ;
+numeric n ;
+lua("mp.print('n := ',\#MP.data)") ;
+for i=1 upto n :
+ drawdot
+ lua("mp.pair(MP.data[" & decimal i & "])") scaled cm
+ withpen pencircle scaled 2mm
+ withcolor darkred ;
+endfor ;
+\stopbuffer
+
+\typebuffer
+
+Here we load a \LUA\ table and assign the size to a \METAPOST\ numeric. Next we
+loop over the table entries and draw the coordinates.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+We will stepwise improve this code. In the previous examples we omitted wrapper
+code but here we show it:
+
+\startbuffer
+\startluacode
+ MP.data = table.load('demo-data.lua')
+ function MP.n()
+ mp.print(#MP.data)
+ end
+ function MP.dot(i)
+ mp.pair(MP.data[i])
+ end
+\stopluacode
+
+\startMPcode
+ numeric n ; n := lua("MP.n()") ;
+ for i=1 upto n :
+ drawdot
+ lua("MP.dot(" & decimal i & ")") scaled cm
+ withpen pencircle scaled 2mm
+ withcolor darkred ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+So, we create a few helpers in the \type {MP} table. This table is predefined so
+normally you don't need to define it. You may however decide to wipe it clean.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+You can decide to hide the data:
+
+\startbuffer
+\startluacode
+ local data = { }
+ function MP.load(name)
+ data = table.load(name)
+ end
+ function MP.n()
+ mp.print(#data)
+ end
+ function MP.dot(i)
+ mp.pair(data[i])
+ end
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+It is possible to use less \LUA, for instance in:
+
+\startbuffer
+\startluacode
+ local data = { }
+ function MP.loaded(name)
+ data = table.load(name)
+ mp.print(#data)
+ end
+ function MP.dot(i)
+ mp.pair(data[i])
+ end
+\stopluacode
+
+\startMPcode
+ for i=1 upto lua("MP.loaded('demo-data.lua')") :
+ drawdot
+ lua("MP.dot(",i,")") scaled cm
+ withpen pencircle scaled 4mm
+ withcolor darkred ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+Here we also omit the \type {decimal} because the \type {lua} macro is clever
+enough to recognize it as a number.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+By using some \METAPOST\ magic we can even go a step further in readability:
+
+\startbuffer
+\startMPcode{doublefun}
+ lua.MP.load("demo-data.lua") ;
+
+ for i=1 upto lua.MP.n() :
+ drawdot
+ lua.MP.dot(i) scaled cm
+ withpen pencircle scaled 4mm
+ withcolor darkred ;
+ endfor ;
+
+ for i=1 upto MP.n() :
+ drawdot
+ MP.dot(i) scaled cm
+ withpen pencircle scaled 2mm
+ withcolor white ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+Here we demonstrate that it also works ok in \type {double} mode, which makes
+much sense when processing data from other sources. Watch how we omit the
+type {lua.} prefix: the \type {MP} macro will deal with that.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+So in the end we can simplify the code that we started with to:
+
+\starttyping
+\startMPcode{doublefun}
+ for i=1 upto MP.loaded("demo-data.lua") :
+ drawdot
+ MP.dot(i) scaled cm
+ withpen pencircle scaled 2mm
+ withcolor darkred ;
+ endfor ;
+\stopMPcode
+\stoptyping
+
+\stopsection
+
+\startsection[title=Access to variables]
+
+The question with such mechanisms is always: how far should we go. Although
+\METAPOST\ is a macro language it has properties of procedural languages. It also
+has more introspective features at the user end. For instance, one can loop over
+the resulting picture and manipulate it. This means that we don't need full
+access to \METAPOST\ internals. However, it makes sense to provide access to
+basic variables: \type {numeric}, \type {string}, and \type {boolean}.
+
+\startbuffer
+draw textext(lua("mp.quoted('@0.15f',mp.get.numeric('pi')-math.pi)"))
+ ysized 1cm
+ withcolor darkred ;
+\stopbuffer
+
+\typebuffer
+
+In double mode you will get zero printed but in scaled mode we definitely get a
+difference:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\startbuffer
+boolean b ; b := true ;
+draw textext(lua("mp.quoted(mp.get.boolean('b') and 'yes' or 'no')"))
+ ysized 1cm
+ withcolor darkred ;
+\stopbuffer
+
+In the next example we use \type {mp.quoted} to make sure that indeed we pass a
+string. The \type {textext} macro can deal with numbers but an unquoted \type
+{yes} or \type {no} is asking for problems.
+
+\typebuffer
+
+Especially when more text is involved it makes sense to predefine a helper in
+the \type {MP} namespace if only because \METAPOST\ (currently) doesn't like
+newlines in the middle of a string, so a \type {lua} call has to be on one line.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Here is an example where \LUA\ does something that would be close to impossible,
+especially if more complex text is involved.
+
+% \enabletrackers[metapost.lua]
+
+\startbuffer
+string s ; s := "ΤΕΧ" ; % "τεχ"
+draw textext(lua("mp.quoted(characters.lower(mp.get.string('s')))"))
+ ysized 1cm
+ withcolor darkred ;
+\stopbuffer
+
+\typebuffer
+
+As you can see here, the whole repertoire of helper functions can be used in
+a \METAFUN\ definition.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=The library]
+
+In \CONTEXT\ we have a dedicated runner, but for the record we mention the
+low level constructor:
+
+\starttyping
+local m = mplib.new {
+ ...
+ script_runner = function(s) return loadstring(s)() end,
+ script_error = function(s) print(s) end,
+ ...,
+}
+\stoptyping
+
+An instance (in this case \type {m}) has a few extra methods. Instead you can use
+the helpers in the library.
+
+\starttabulate[|l|l|]
+\HL
+\NC \type {m:get_numeric(name)} \NC returns a numeric (double) \NC \NR
+\NC \type {m:get_boolean(name)} \NC returns a boolean (\type {true} or \type {false}) \NC \NR
+\NC \type {m:get_string (name)} \NC returns a string \NC \NR
+\HL
+\NC \type {mplib.get_numeric(m,name)} \NC returns a numeric (double) \NC \NR
+\NC \type {mplib.get_boolean(m,name)} \NC returns a boolean (\type {true} or \type {false}) \NC \NR
+\NC \type {mplib.get_string (m,name)} \NC returns a string \NC \NR
+\HL
+\stoptabulate
+
+In \CONTEXT\ the instances are hidden and wrapped in high level macros, so there
+you cannot use these commands.
+
+\stopsection
+
+\startsection[title=\CONTEXT\ helpers]
+
+The \type {mp} namespace provides the following helpers:
+
+\starttabulate[|l|l|]
+\HL
+\NC \type {print(...)} \NC returns one or more values \NC \NR
+\NC \type {pair(x,y)}
+ \type {pair(t)} \NC returns a proper pair \NC \NR
+\NC \type {triplet(x,y,z)}
+ \type {triplet(t)} \NC returns an \RGB\ color \NC \NR
+\NC \type {quadruple(w,x,y,z)}
+ \type {quadruple(t)} \NC returns an \CMYK\ color \NC \NR
+\NC \type {format(fmt,...)} \NC returns a formatted string \NC \NR
+\NC \type {quoted(fmt,...)}
+ \type {quoted(s)} \NC returns a (formatted) quoted string \NC \NR
+\NC \type {path(t[,connect][,close])} \NC returns a connected (closed) path \NC \NR
+\HL
+\stoptabulate
+
+The \type {mp.get} namespace provides the following helpers:
+
+\starttabulate[|l|l|]
+\HL
+\NC \type {numeric(name)} \NC gets a numeric from \METAPOST \NC \NR
+\NC \type {boolean(name)} \NC gets a boolean from \METAPOST \NC \NR
+\NC \type {string(name)} \NC gets a string from \METAPOST \NC \NR
+\HL
+\stoptabulate
+
+\stopsection
+
+\startsection[title=Paths]
+
+In the meantime we got several questions on the \CONTEXT\ mailing list about turning
+coordinates into paths. Now imagine that we have this dataset:
+
+\startbuffer[dataset]
+10 20 20 20 -- sample 1
+30 40 40 60
+50 10
+
+10 10 20 30 % sample 2
+30 50 40 50
+50 20
+
+10 20 20 10 # sample 3
+30 40 40 20
+50 10
+\stopbuffer
+
+\typebuffer[dataset]
+
+In this case I've put the data in a buffer so that it can be shown
+here as well as used in a demo. Watch how we can add comments. The
+following code converts this into a table with three subtables.
+
+\startbuffer
+\startluacode
+ MP.myset = mp.dataset(buffers.getcontent("dataset"))
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We use the \type {MP} (user) namespace to store the table. Next we turn
+these subtables into paths:
+
+\startbuffer
+\startMPcode
+ for i=1 upto lua("mp.print(mp.n(MP.myset))") :
+ draw
+ lua("mp.path(MP.myset[" & decimal i & "])")
+ xysized (HSize-.25ExHeight,10ExHeight)
+ withpen pencircle scaled .25ExHeight
+ withcolor basiccolors[i]/2 ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+This gives:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+Instead we can fill the path in which case we also need to close it. The
+\type {true} argument deals with that:
+
+\startbuffer
+\startMPcode
+ for i=1 upto lua("mp.print(mp.n(MP.myset))") :
+ path p ; p :=
+ lua("mp.path(MP.myset[" & decimal i & "],true)")
+ xysized (HSize,10ExHeight) ;
+ fill p
+ withcolor basiccolors[i]/2
+ withtransparency (1,.5) ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+We get:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+\startbuffer
+\startMPcode
+ for i=1 upto lua("mp.print(mp.n(MP.myset))") :
+ path p ; p :=
+ lua("mp.path(MP.myset[" & decimal i & "])")
+ xysized (HSize,10ExHeight) ;
+ p :=
+ (xpart llcorner boundingbox p,0) --
+ p --
+ (xpart lrcorner boundingbox p,0) --
+ cycle ;
+ fill p
+ withcolor basiccolors[i]/2
+ withtransparency (1,.25) ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+The following makes more sense:
+
+\typebuffer
+
+So this gives:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+This (area) fill is so common that we have a helper for it:
+
+\startbuffer
+\startMPcode
+ for i=1 upto lua("mp.size(MP.myset)") :
+ fill area
+ lua("mp.path(MP.myset[" & decimal i & "])")
+ xysized (HSize,5ExHeight)
+ withcolor basiccolors[i]/2
+ withtransparency (2,.25) ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+So this gives:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+A variant call is the following: \footnote {Getting that to work properly in the
+library was non||trivial as the loop variable \type {i} is an abstract nameless
+variable at the \METAPOST\ end. When investigating this Luigi Scarso and I found out
+that the internals of \METAPOST\ are not really geared for interfacing this way
+but in the end it worked out well.}
+
+\startbuffer
+\startMPcode
+ for i=1 upto lua("mp.size(MP.myset)") :
+ fill area
+ lua("mp.path(MP.myset[mp.get.numeric('i')])")
+ xysized (HSize,5ExHeight)
+ withcolor basiccolors[i]/2
+ withtransparency (2,.25) ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+The result is the same:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+\startbuffer
+\startluacode
+ MP.mypath = function(i)
+ return mp.path(MP.myset[mp.get.numeric(i)])
+ end
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startMPcode
+ for i=1 upto lua("mp.size(MP.myset)") :
+ fill area
+ lua("MP.mypath('i')")
+ xysized (HSize,5ExHeight)
+ withcolor basiccolors[i]/2
+ withtransparency (2,.25) ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+This snippet of \METAPOST\ code still looks kind of horrible so how can we make
+it look better? Here is an attempt, First we define a bit more \LUA:
+
+\startbuffer
+\startluacode
+local data = mp.dataset(buffers.getcontent("dataset"))
+
+MP.dataset = {
+ Line = function(n) mp.path(data[n]) end,
+ Size = function() mp.size(data) end,
+}
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We can now make the \METAPOST\ look more natural. Of course this is possible
+because in \METAFUN\ the \type {lua} macro does some extra work.
+
+\startbuffer
+\startMPcode
+ for i=1 upto lua.MP.dataset.Size() :
+ path p ; p :=
+ lua.MP.dataset.Line(i)
+ xysized (HSize-ExHeight,20ExHeight) ;
+ draw
+ p
+ withpen pencircle scaled .25ExHeight
+ withcolor basiccolors[i]/2 ;
+ drawpoints
+ p
+ withpen pencircle scaled ExHeight
+ withcolor basiccolors[i]/2 ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+As expected, we get the desired result:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+Once we start making things look nicer and more convenient, we quickly end up
+with helpers like the once in the next example. First we save some demo data
+in files:
+
+\startbuffer
+\startluacode
+ io.savedata("foo.tmp","10 20 20 20 30 40 40 60 50 10")
+ io.savedata("bar.tmp","10 10 20 30 30 50 40 50 50 20")
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We load the data in datasets:
+
+\startbuffer
+\startMPcode
+ lua.mp.datasets.load("foo","foo.tmp") ;
+ lua.mp.datasets.load("bar","bar.tmp") ;
+ fill area
+ lua.mp.datasets.foo.Line()
+ xysized (HSize/2-EmWidth-.25ExHeight,10ExHeight)
+ withpen pencircle scaled .25ExHeight
+ withcolor darkyellow ;
+ fill area
+ lua.mp.datasets.bar.Line()
+ xysized (HSize/2-EmWidth-.25ExHeight,10ExHeight)
+ shifted (HSize/2+EmWidth,0)
+ withpen pencircle scaled .25ExHeight
+ withcolor darkred ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+Because the datasets are stores by name we can use them without worrying about
+them being forgotten:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+If no tag is given, the filename (without suffix) is used as tag, so the following is
+valid:
+
+\starttyping
+\startMPcode
+ lua.mp.datasets.load("foo.tmp") ;
+ lua.mp.datasets.load("bar.tmp") ;
+\stopMPcode
+\stoptyping
+
+The following methods are defined for a dataset:
+
+\starttabulate[|l|pl|]
+\HL
+\NC \type {method} \NC usage \NC \NR
+\HL
+\NC \type {Size} \NC the number of subsets in a dataset \NC \NR
+\NC \type {Line} \NC the joined pairs in a dataset making a non|-|closed path \NC \NR
+\NC \type {Data} \NC the table containing the data (in subsets, so there is always at least one subset) \NC \NR
+\HL
+\stoptabulate
+
+{\em In order avoid interference with suffix handling in \METAPOST\ the methods
+start with an uppercase character.}
+
+\stopsection
+
+\startsection[title=Passing variables]
+
+You can pass variables from \METAPOST\ to \CONTEXT. Originally that happened via
+a temporary file and so called \METAPOST\ specials. Nowadays it's done via \LUA.
+Here is an example:
+
+\startbuffer
+\startMPcalculation
+
+passvariable("version","1.0") ;
+passvariable("number",123) ;
+passvariable("string","whatever") ;
+passvariable("point",(1.5,2.8)) ;
+passvariable("triplet",(1/1,1/2,1/3)) ;
+passvariable("quad",(1.1,2.2,3.3,4.4)) ;
+passvariable("boolean",false) ;
+passvariable("path",fullcircle scaled 1cm) ;
+path p[] ; p[1] := fullcircle ; p[2] := fullsquare ;
+passarrayvariable("list",p,1,2,1) ; % first last step
+\stopMPcalculation
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+We can visualize the result with
+
+\startbuffer
+\startluacode
+context.tocontext(metapost.variables)
+\stopluacode
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+In \TEX\ you can access these variables as follows:
+
+\startbuffer
+\MPrunvar{version}
+\MPruntab{quad}{3}
+(\MPrunset{triplet}{,})
+
+$(x,y) = (\MPruntab{point}{1},\MPruntab{point}{2})$
+$(x,y) = (\MPrunset{point}{,})$
+\stopbuffer
+
+\typebuffer
+
+This becomes: % we need a hack as we cross pages and variables get replace then
+
+\startlines
+\getbuffer
+\stoplines
+
+Here we passed the code between \type {\startMPcalculation} and \type
+{\stopMPcalculation} which does not produce a graphic and therefore takes no
+space in the flow. Of course it also works with normal graphics.
+
+\startbuffer
+\startMPcode
+path p ; p := fullcircle xyscaled (10cm,2cm) ;
+path b ; b := boundingbox p ;
+startpassingvariable("mypath")
+ passvariable("points",p) ;
+ startpassingvariable("metadata")
+ passvariable("boundingbox",boundingbox p) ;
+ stoppassingvariable ;
+stoppassingvariable ;
+fill p withcolor .625red ;
+draw b withcolor .625yellow ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \getbuffer
+\stoplinecorrection
+
+This time we get:
+
+\ctxlua{context.tocontext(metapost.variables)}
+
+You need to be aware of the fact that a next graphic resets the previous
+variables. You can easily overcome that limitation by saving the variables (in
+\LUA). It helps that when a page is being shipped out (which can involve
+graphics) the variables are protected. You can push and pop variable sets with
+\type {\MPpushvariables} and \type {\MPpopvariables}. Because you can nest
+the \type {start}||\type{stop} pairs you can create quite complex indexed
+and hashed tables. If the results are not what you expect, you can enable a
+tracker to follow what gets passed:
+
+\starttyping
+\enabletrackers[metapost.variables]
+\stoptyping
+
+Serializing variables can be done with the \type {tostring} macro, for instance:
+
+\startbuffer
+\startMPcode
+message("doing circle",fullcircle);
+draw fullcircle ;
+\stopMPcode
+\stopbuffer
+
+In this case the \type {tostring} is redundant as the message already does the
+serialization.
+
+\stopsection
+
+\stopchapter
+
+% \startMPcode{doublefun}
+% numeric n ; n := 123.456 ;
+% lua("print('>>>>>>>>>>>> number',mp.get.number('n'))") ;
+% lua("print('>>>>>>>>>>>> number',mp.get.boolean('n'))") ;
+% lua("print('>>>>>>>>>>>> number',mp.get.string('n'))") ;
+% boolean b ; b := true ;
+% lua("print('>>>>>>>>>>>> boolean',mp.get.number('b'))") ;
+% lua("print('>>>>>>>>>>>> boolean',mp.get.boolean('b'))") ;
+% lua("print('>>>>>>>>>>>> boolean',mp.get.string('b'))") ;
+% string s ; s := "TEST" ;
+% lua("print('>>>>>>>>>>>> string',mp.get.number('s'))") ;
+% lua("print('>>>>>>>>>>>> string',mp.get.boolean('s'))") ;
+% lua("print('>>>>>>>>>>>> string',mp.get.string('s'))") ;
+% \stopMPcode
+
+% \usemodule[graph]
+%
+% \startluacode
+% local d = nil
+% function MP.set(data)
+% d = data
+% end
+% function MP.n()
+% mp.print(d and #d or 0)
+% end
+% function MP.get(i,j)
+% mp.print(d and d[i] and d[i][j] or 0)
+% end
+% \stopluacode
+%
+% \startluacode
+% MP.set {
+% { 1, 0.5, 2.5 },
+% { 2, 1.0, 3.5 },
+% }
+% \stopluacode
+%
+% \startMPpage[instance=graph,offset=2mm]
+%
+% draw begingraph(3cm,5cm);
+% numeric a[];
+% for j = 1 upto MP.n() :
+% path b;
+% augment.b(MP.get(j,1),MP.get(j,2));
+% augment.b(MP.get(j,1),MP.get(j,3));
+% setrange(0,0,3,4);
+% gdraw b;
+% endfor ;
+% endgraph ;
+% \stopMPpage
+
+% \starttext
+%
+% % \enabletrackers[metapost.variables]
+%
+% \startMPcode
+% numeric n[] ; for i=1 upto 10: n[i] := 1/i ; endfor ;
+% path p[] ; for i=1 upto 10: p[i] := fullcircle xyscaled (cm*i,cm/i) ; endfor ;
+% numeric r[][] ; for i=1 upto 4 : for j=1 upto 3 : r[i][j] := uniformdeviate(1) ; endfor ; endfor ;
+% pair u[][] ; for i=1 step 0.5 until 4 : for j=1 step 0.1 until 2 : u[i][j] := (i,j) ; endfor ; endfor ;
+%
+% passvariable("x",12345) ;
+% passarrayvariable("n-array",n,1,7,1) ;
+% passarrayvariable("p-array",p,1,7,1) ;
+% passvariable("p",(1,1) .. (2,2)) ;
+%
+% startpassingvariable("b")
+% for i=1 upto 4 :
+% startpassingvariable(i)
+% for j=1 upto 3 :
+% passvariable(j,r[i][j])
+% endfor
+% stoppassingvariable
+% endfor
+% stoppassingvariable ;
+%
+% startpassingvariable("a")
+% startpassingvariable("test 1")
+% passvariable(1,123)
+% passvariable(2,456)
+% stoppassingvariable ;
+% startpassingvariable("test 2")
+% passvariable(0,123)
+% passvariable(1,456)
+% passvariable(2,789)
+% passvariable(999,987)
+% stoppassingvariable ;
+% startpassingvariable("test 3")
+% passvariable("first",789)
+% passvariable("second",987)
+% stoppassingvariable
+% stoppassingvariable ;
+%
+% startpassingvariable("c")
+% for i=1 step 0.5 until 4 :
+% startpassingvariable(i)
+% for j=1 step 0.1 until 2 :
+% passvariable(j,u[i][j])
+% endfor
+% stoppassingvariable
+% endfor
+% stoppassingvariable ;
+%
+% draw fullcircle scaled 1cm ;
+% \stopMPcode
+%
+% \ctxluacode{inspect(metapost.variables)}
+%
+% \ctxcommand{mprunvar("x")}
+
+\stoptext
+
+
diff --git a/doc/context/sources/general/manuals/metafun/metafun-macros.tex b/doc/context/sources/general/manuals/metafun/metafun-macros.tex
new file mode 100644
index 000000000..e1df13c92
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-macros.tex
@@ -0,0 +1,91 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-macros
+
+\environment metafun-environment
+
+\startchapter[title={\METAFUN\ macros}]
+
+\index{metafun}
+
+\startintro
+
+\CONTEXT\ comes with a series of \METAPOST\ modules. In this chapter we will
+summarize the most important \TEX\ and \METAPOST\ macros. More information can be
+found in the documentation of the modules.
+
+\stopintro
+
+There are several ways to use the power of \METAFUN, either or not using
+\CONTEXT.
+
+\startitemize[n]
+
+\startitem
+ You can create an independent \type {mp} file and process it with the
+ \METAPOST\ program or \MPTOPDF. Depending on what features you use, the
+ succes of a run depends on the proper set up of the programs that take care
+ of running \TEX\ for \type {btex}.
+\stopitem
+
+\startitem
+ You can embed the graphic in a \type {\startMPpage} construct and process it
+ with \CONTEXT\ \MKIV. In that case you have the full \METAFUN\ functionality
+ available. If for some reason you still want to use \MKII, you need to use
+ \TEXEXEC\ as before processing the file, it will do a couple of checks on the
+ file. It will also make sure that the temporary files (\type {mpt} for \type
+ {textext}'s and \type {mpo} for outline fonts) are taken care of too.
+\stopitem
+
+\startitem
+ You can integrate the graphic in the document flow, using buffers, \METAPOST\
+ code sections, or (reusable) graphic containers. In that case the graphics
+ are processed runtime or between runs. This happens automatically.
+\stopitem
+
+\stopitemize
+
+Unless you want to write low level \CONTEXT\ code yourself, there is no real
+reason to look into the modules that deal with \METAPOST\ support. The
+traditional (partly generic) code is collected in:
+
+\starttabulate[|lT|p|]
+\NC supp-mps.tex \NC low level inclusion macros and housekeeping \NC\NR
+\NC supp-mpe.tex \NC experimental extensions (like specials) \NC\NR
+\NC supp-pdf.tex \NC \METAPOST\ to \PDF\ conversion \NC\NR
+\stoptabulate
+
+Especially the last two can be used in other macro packages. However, in
+\CONTEXT\ we have regrouped the code (plus more) in other files:
+
+\starttabulate[|lT|p|]
+\NC meta-***.tex \NC definition and managing \NC\NR
+\NC mlib-***.tex \NC processing and conversion \NC\NR
+\stoptabulate
+
+The last category will certainly grow. Some of these modules are preloaded,
+others can be loaded using the command \type {\useMPlibrary}, like
+
+\starttyping
+\useMPlibrary[clp,txt]
+\stoptyping
+
+for loading the predefined clipping paths and text tricks.
+
+The \METAPOST\ code is organized in files named \type {mp-****.mp}. The core file
+is \type {mp-tool.mp} and this file can comfortably be used in stand||alone
+graphics. The file \type {metafun.mp} is used to load the collection of modules
+into a format. The collection of \METAPOST\ code files will grow in due time, but
+as long as you use the \METAFUN\ format, you don't have to keep track of the
+organization of files. Most files relate to subsystems and are loaded
+automatically, like the files that implement page layout support and flow charts.
+
+Although this document is the main source of information, occasionally the source
+code of \METAFUN, and in many cases the source code of \CONTEXT\ may contain
+additional information and examples.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-positioning.tex b/doc/context/sources/general/manuals/metafun/metafun-positioning.tex
new file mode 100644
index 000000000..5a3b1ece0
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-positioning.tex
@@ -0,0 +1,1013 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-positioning
+
+\environment metafun-environment
+
+\startchapter[reference=sec:positioning,title={Positional graphics}]
+
+\startintro
+
+In this chapter, we will explore one of the more advanced, but also conceptually
+more difficult, graphic capabilities of \CONTEXT. It took quite a few experiments
+to find the {\em right} way to support these kind of graphics, and you can be
+sure that in due time extensions will show up. You can skip this chapter if you
+are no \CONTEXT\ user. Because we're now a decade into \MKIV\ the tricks here
+will assume that you use \CONTEXT\ \MKIV\ because we have a more convenient
+interface there. For old|-|school \MKII\ usage you can look in old \METAFUN\
+manuals or in the \type {mkii} source files. Of course we remain compatible, it's
+just that more (convenient) interfaces were added.
+
+\stopintro
+
+\startsection[title={The status quo}]
+
+After \TEX\ has read a paragraph of text, it will try to break this paragraph
+into lines. When this is done, the result is flushed and after that \TEX\ will
+check if a page should be split off. As a result, we can hardly predict how a
+document will come out. Therefore, when we want graphics to adapt themselves to
+this text, maybe even to text broken across lines, we have to deal with this
+asynchronous feature of \TEX\ in a rather advanced way. Before we present a way
+of dealing with this complexity, we will elaborate on the nature of embedded
+graphics in \TEX.
+
+When \TEX\ entered the world of typesetting, desktop printers were not that
+common, let alone color desktop printers. But times have changed and nowadays we
+want color and graphics and if possible we want them integrated in the text. When
+\METAPOST\ showed up it depended on the \DVI\ processor to recognize the
+\POSTSCRIPT\ code as being produced by \METAPOST\ and therefore also include the
+fonts that were used. But color was still limited to \RGB. When \PDFTEX\ evolved
+I wrote an interpreter (in \TEX) that could translate the output to \PDF. This
+also opened up the possibility to add features to \METAPOST, like \CMYK\ colors,
+shading, transparencies etc. But basically the \TEX\ and \METAPOST\ processes
+were rather isolated. We could of course pass information to \METAPOST\ and pick
+up information from \METAPOST\ in a second pass. That has changed in \LUATEX.
+
+In order to really integrate \METAPOST\ graphics into the flow you need to know
+where you are on the page and how large graphics should be, especially when you
+want them to depend on the layout. A first solution to this was to embed specials
+in the \DVI\ that could later be used to extract positions. In retrospect this
+was a relative trivial extension, something that could have been around much
+earlier but somehow didn't happen. Anyhow, after some experiments \PDFTEX\ got a
+native position tracker which meant that no post processor was needed. Of course
+\LUATEX\ inherited this feature too. Because positioning is rather bound to the
+macro package reading this chapter only makes sense when you use \CONTEXT.
+
+\stopsection
+
+\startbuffer[arrow:1]
+\startMPpositionmethod{mypos:arrow}
+ \startMPpositiongraphic{mypos:arrow}
+ save pa, pb, pm, pab, na, nb, sa, sb ;
+ path pa, pb, pm, pab ; numeric na, nb ; string sa, sb ;
+ % the tags
+ sa := texstr("from") ;
+ sb := texstr("to") ;
+ % we need to check page crossing so we fetch the page numbers
+ na := positionpage(sa) ;
+ nb := positionpage(sb) ;
+ % we use the repositioned shapes
+ pa := positionbox(sa) ;
+ pb := positionbox(sb) ;
+ % but want circles instead of rectangles
+ pa := llcorner pa .. lrcorner pa .. urcorner pa .. ulcorner pa .. cycle ;
+ pb := llcorner pb .. lrcorner pb .. urcorner pb .. ulcorner pb .. cycle ;
+ pickup pencircle scaled 1pt ;
+ if na = nb :
+ % both are on the same page
+ fill pa withcolor .800white ;
+ fill pb withcolor .800white ;
+ draw pa withcolor .625yellow ;
+ draw pb withcolor .625yellow ;
+ pm := .5[center pa,center pb] shifted (0,2*LineHeight) ;
+ pab := center pa .. pm .. center pb ;
+ pab := pab cutbefore (pab intersectionpoint pa) ;
+ pab := pab cutafter (pab intersectionpoint pb) ;
+ drawarrow pab dashed evenly withcolor .625red ;
+ positionatanchor(sa) ;
+ elseif nb < na :
+ % they are on different pages and we're at the first one
+ fill pb withcolor .800white ;
+ draw pb withcolor .625yellow ;
+ pab := center pb {up} .. ulcorner bbox pb ;
+ pab := pab cutbefore (pab intersectionpoint pb) ;
+ drawarrow pab dashed evenly withcolor .625red ;
+ positionatanchor(sb) ;
+ else :
+ % they are on different pages and we're at the last one
+ fill pa withcolor .800white ;
+ draw pa withcolor .625yellow ;
+ pab := center pa {up} .. urcorner bbox pa ;
+ pab := pab cutbefore (pab intersectionpoint pa) ;
+ drawarrow pab dashed evenly withcolor .625red ;
+ positionatanchor(sa) ;
+ fi ;
+ \stopMPpositiongraphic
+ % we put it here at the first position
+ \MPpositiongraphic{mypos:arrow}
+ % we need to carry information forward and make sure that we also
+ % check and flush at the second position of the pair
+ \ifnum\MPp{\MPvar{from}}<\MPp{\MPvar{to}}\relax
+ \expanded{\setMPpositiongraphic{\MPvar{to}}{mypos:arrow}{to=\MPvar{from}}}
+ \fi
+\stopMPpositionmethod
+\stopbuffer
+
+\startbuffer[arrow:2]
+\setMPpositiongraphic{A-1}{mypos:arrow}{to=A-2}
+\stopbuffer
+
+\startbuffer[box:1]
+\startMPpositiongraphic{mpos:box}{fillcolor,linecolor,linewidth}
+ string tag; tag := "\MPvar{self}" ;
+ path box ; box := positionbox(tag) ;
+ box := box enlarged \MPvar{filloffset} ;
+ fill box
+ withcolor \MPvar{fillcolor} ;
+ draw box
+ withcolor \MPvar{linecolor}
+ withpen pencircle scaled \MPvar{linewidth} ;
+ positioninregion ;
+\stopMPpositiongraphic
+\stopbuffer
+
+\startbuffer[box:1:also]
+\startMPpositiongraphic{mpos:box}{fillcolor,linecolor,linewidth}
+ path box ; box := positionbox(texstr("self")) ;
+ box := box enlarged texvar("filloffset") ;
+ fill box
+ withcolor texvar("fillcolor") ;
+ draw box
+ withcolor texvar("linecolor")
+ withpen pencircle scaled texvar("linewidth") ;
+ positioninregion ;
+\stopMPpositiongraphic
+\stopbuffer
+
+\startbuffer[box:2]
+\setupMPvariables
+ [mpos:box]
+ [linecolor=blue,
+ linewidth=\linewidth,
+ fillcolor=lightgray,
+ filloffset=2pt]
+
+\setupMPvariables[mpos:box][linecolor=darkred]
+\setupMPvariables[mpos:par][linecolor=darkred]
+
+\startpositionoverlay{backgraphics}
+ \setMPpositiongraphic{A-0}{mpos:box}{self=A-0}
+ \setMPpositiongraphic{A-3}{mpos:box}{self=A-3}
+ \setMPpositiongraphic{A-4}{mpos:box}{self=A-4}
+\stoppositionoverlay
+\stopbuffer
+
+\getbuffer[arrow:1,arrow:2]
+\getbuffer[box:1,box:2]
+
+\startsection[title={The concept}]
+
+\index {graphics+positioning}
+\index {positioning}
+\index {anchoring}
+
+Because we have a \LUA\ connection in \MPLIB, we have implemented a couple of
+helpers that make live easier. This is also why the following examples are \MKIV\
+specific, although \MKII\ can do the same, but with a bit different set of
+helpers. We can for instance query properties of \hpos {A-0} {positions} without
+using \TEX\ macros but can use \METAPOST\ macros instead. Let's give an example.
+The background and frame behind the word \type {position} in this paragraph is
+not done with \type {\framed} but using a different mechanism:
+
+\starttyping
+to get \hpos {A-0} {positions} sorted
+\stoptyping
+
+The \type {\hpos} refers to a position and we have bound that position to a graphic:
+
+\starttyping
+\setMPpositiongraphic{A-0}{mpos:box}{self=A-0}
+\stoptyping
+
+The graphic itself is defined with:
+
+\typebuffer[box:1]
+
+A variant that has no macro calls and does all via the \LUA\ intercaface in \MKIV\ is
+the following:
+
+\typebuffer[box:1:also]
+
+A \type {\hpos} position has several properties: the coordinates of the origin:
+\type {x} and \type {y}, the dimensions of the boxed content, \type {w}, \type
+{h} and \type {d}, and the page number \type {p}. An additional helper \type
+{positioninregion} will move the drawing to the right spot in the region.
+Examples or regions are the page, text area or some overlay. The \type
+{positionatanchor} variant relocates to the anchor of the given tag. The first
+helper is actually a shortcut for:
+
+\starttyping
+currentpicture := currentpicture shifted - positionxy(positionanchor) ;
+\stoptyping
+
+In our case we use a dedicated layer \type {backgraphics} that we have hooked into
+the page backgrounds:
+
+\starttyping
+\setupbackgrounds
+ [page]
+ [background={backgraphics,foreground,foregraphics}]
+
+\defineoverlay [backgraphics] [\positionoverlay{backgraphics}]
+\defineoverlay [foregraphics] [\positionoverlay{foregraphics}]
+\stoptyping
+
+The relation between position graphics and that layer are defined as follows
+(we will come back to this in a moment):
+
+\typebuffer[box:2]
+
+\stopsection
+
+\startsection[title={A more detailed view}]
+
+As we know, a decent portion of \TEX's attention is focused on breaking
+paragraphs into lines and determining the optimal point to split off the page.
+Trying to locate the optimal points to break lines is a dynamic process. The
+space between words is flexible and we don't know in advance when a \hpos {A-1}
+{word} or piece of a word |<|maybe it's best to talk of typographic \hpos {A-2}
+{globs} instead|>| will end up on the page. It might even cross the page
+boundary.
+
+In the previous section we saw \hpos {A-3} {word} and \hpos {A-4} {globs}
+encircled and connected by an arrow. This graphic can be drawn only when the
+position and dimensions are known. Unfortunately, this information is only
+available after the paragraph is typeset and the best breakpoints are chosen.
+\bpos {A-5} Because the text must be laid on top of the graphic, the graphic must
+precede the first word in the typeset stream or it must be positioned on a
+separate layer. In the latter case it can be calculated directly after the
+paragraph is typeset, but in the former case a second pass is needed. \epos {A-5}
+Because such graphics are not bound to one paragraph, the multi||pass option
+suits better because it gives us more control: the more we know about he final
+state, the better we can act upon it. Think of graphics on the first page that
+depend on the content of the last page \bpos {A-6} or, as in this paragraph,
+backgrounds that depend on the typeset text. \epos {A-6}
+
+The arrows that connect the shapes are drawn with the following code that now
+looks familiar:
+
+\typebuffer[arrow:1]
+
+and
+
+\typebuffer[arrow:2]
+
+However, here we anchor at one of the positions because we don't flush in a layer
+but at the position itself. Indeed it looks complex.
+
+It may be clear now that we need some positional information in order to provide
+features like the ones shown here. The fact that we will act upon in a second
+pass simplifies the task, although it forces us to store the positional
+information between runs in some place. This may look uncomfortable at first
+sight, but it also enables us to store some additional information. Now why is
+that needed?
+
+A position has no dimensions, it's just a place somewhere on the page. In order
+to do tricks like those shown here, we also need to know the height and depth of
+lines at a specific point as well as the width of the box(es) we're dealing with.
+In the encircled examples, the dimensions of the box following the positional
+node are stored along with the position.
+
+In order to process the graphics, we tag each point with a name, so that we can
+attach actions to those points. In fact they become trigger points. As we will
+demonstrate, we also need to store the current page number. This brings the data
+stored with a point to:
+
+\starttyping
+<identifier> <pagenumber> <x> <y> <width> <height> <depth>
+\stoptyping
+
+Actually we store more information, for example the region in which the positions
+sit. Depending on the use we can also get access to paragraph and line properties
+but discussing these is beyond this manual. These are for instance used in the
+text backgrounds.
+
+The page number is needed in order to let the graphics engine determine boundary
+conditions. Backgrounds like those shown here can span multiple pages. In order
+to calculate the right backgrounds, some additional information must be
+available, like the top and bottom of the current text area. In fact, these are
+just normal points that can be saved while processing the split off page. So,
+apart from positioning anchors in the text we need anchors on crucial points of
+the layout. This means that this kind of support cannot be fully integrated into
+the \TEX\ kernel, unless we also add extensive support for layout definitions,
+and that is probably not what we want.
+
+As soon as something like $(x,y)$ shows up, a logical question is where $(0,0)$
+is located. Although this is a valid question, the answer is less important than
+you may expect. Even if we know that ($0,0)$ is \quote {officially} located in
+the bottom left corner of the page, the simple fact that in \CONTEXT\ we are
+dealing with a mixed page concept, like paper size and print paper size, or left
+and right pages, forces us to think in relative positions instead of absolute
+ones. Therefore, graphics, even those that involve multiple positions, are
+anchored to a position on the layer on which they are located.
+
+Users who simply want to use these features may wonder why we go into so much
+detail. The main reason is that in the end many users will want to go beyond the
+simple cases, and when dealing with these issues, you must be aware not only of
+height, depth and width, but also of the crossing of a page boundary, and the
+height and depth of lines. In some cases your graphics may have to respond to
+layout characteristics, like differences between odd and even pages. Given that
+unique identifiers are used for anchor points, in \CONTEXT\ you can have access
+to all the information needed. Here are some of the helpers:
+
+\starttabulate[|T||]
+\NC positionpath (tag) \NC the path determined by width, height and depth \NC \NR
+\NC positionxy (tag) \NC the origin \NC \NR
+\NC positionwhd (tag) \NC the dimensions (in a triplet) \NC \NR
+\NC positionpage (tag) \NC the page number fo the position \NC \NR
+\NC positionregion(tag) \NC the region that the position sits in \NC \NR
+\NC positionbox (tag) \NC the positioned box (path shifted over coordinates) \NC \NR
+\NC positionanchor \NC the current anchor of the region \NC \NR
+\stoptabulate
+
+The \type {positionwhd} macro returns a triplet that you can query, like:
+
+\starttyping
+triplet whd ; whd := positionwhd("\MPvar{from}");
+numeric wd; wd := wdpart whd ;
+\stoptyping
+
+We will add more such convenient helpers in the future. In the \CONTEXT\
+distribution you can find examples (in manuals or librarties) that demonstrate
+other tricks with positioning.
+
+\stopsection
+
+\startsection[title={Anchors and layers}]
+
+\index{anchoring}
+\index{layers}
+
+\startbuffer[g-circle]
+\startMPpositiongraphic{mypos:circle}
+ path p ; p := positionbox(texstr("self")) ;
+ p := fullcircle xsized (bbwidth(p)+4pt) shifted center p ;
+ pickup pencircle scaled 1pt ;
+ fill p withcolor .800white ;
+ draw p withcolor .625yellow ;
+ positioninregion ;
+\stopMPpositiongraphic
+\stopbuffer
+
+\startbuffer[g-line]
+\startMPpositiongraphic{mypos:line}
+ path pa, pb, pab ; numeric na, nb ; string ta, tb ;
+ ta := texstr("from") ;
+ tb := texstr("to") ;
+ na := positionpage(ta) ;
+ nb := positionpage(tb) ;
+ pa := positionbox(ta) ;
+ pb := positionbox(tb) ;
+ pa := fullcircle xsized (bbwidth(pa)+4pt) shifted center pa ;
+ pb := fullcircle xsized (bbwidth(pb)+4pt) shifted center pb ;
+ if na = nb :
+ pab := center pa -- center pb ;
+ pab := pab cutbefore (pab intersectionpoint pa) ;
+ pab := pab cutafter (pab intersectionpoint pb) ;
+ pickup pencircle scaled 1pt ;
+ draw pab withcolor .625yellow ;
+ positioninregion ;
+ fi ;
+\stopMPpositiongraphic
+\stopbuffer
+
+\getbuffer[g-circle,g-line]
+
+\startbuffer[a]
+\setMPpositiongraphic{X-1}{mypos:arrow}{to=X-2}
+\setMPpositiongraphic{X-2}{mypos:arrow}{to=X-3}
+\stopbuffer
+
+\startbuffer[b]
+In a previous section we saw that some \hpos {X-1} {words} were
+\hpos {X-2} {circled} and connected by an \hpos {X-3} {arrow}.
+As with most things in \CONTEXT, marking these words is separated
+from declaring what to do with those words. This paragraph is keyed
+in as:
+\stopbuffer
+
+\getbuffer[a,b]
+
+\typebuffer[b]
+
+We see three position anchors, each marked by an identifier: \type {X-1}, \type
+{X-2} and \type {X-3}. Each of these anchors can be associated with a (series) of
+graphic operations. Here we defined:
+
+\typebuffer[a]
+
+These examples clearly demonstrate that we cannot control to what extent graphics
+will cover text and vice versa. A solution to this problem is using position
+overlays. We can define such an overlay as follows:
+
+\startbuffer
+\startpositionoverlay{backgraphics}
+ \setMPpositiongraphic{G-1}{mypos:circle}
+ \setMPpositiongraphic{G-2}{mypos:circle}
+ \setMPpositiongraphic{G-3}{mypos:circle}
+ \setMPpositiongraphic{G-4}{mypos:circle}
+\stoppositionoverlay
+
+\startpositionoverlay{foregraphics}
+ \setMPpositiongraphic{G-1}{mypos:line}{to=G-2}
+ \setMPpositiongraphic{G-2}{mypos:line}{to=G-3}
+ \setMPpositiongraphic{G-3}{mypos:line}{to=G-4}
+\stoppositionoverlay
+\stopbuffer
+
+\getbuffer \typebuffer
+
+\startbuffer
+First we have defined an \hpos {G-1} {\strut overlay}. This
+overlay can be attached to some overlay layer, like, in our
+case, the \hpos {G-2} {\strut page}. We define four small \hpos
+{G-3} {\strut circles}. These are drawn as soon as the page
+overlay is typeset. Because they are located in the
+background, they don't cover the \hpos {G-4} {\strut text}, while
+the lines do. The previous paragraph was typeset by saying:
+\stopbuffer
+
+\getbuffer \typebuffer
+
+As said, the circles are on the background layer, but the lines are not! They are
+positioned on top of the text. This is a direct result of the definition of the
+page background:
+
+\starttyping
+\defineoverlay [foregraphics] [\positionoverlay{foregraphics}]
+\defineoverlay [backgraphics] [\positionoverlay{backgraphics}]
+
+\setupbackgrounds
+ [page]
+ [background={backgraphics,foreground,foregraphics}]
+\stoptyping
+
+\doifmode{screen}{\writestatus{CHECK}{POSITION GRAPHICS}}
+
+In this definition, the predefined overlay \type {foreground} inserts the page
+data itself, so the foreground graphics end up on top. This example also
+demonstrates that you should be well aware of the way \CONTEXT\ builds a page.
+There are six main layers, in some cases with sublayers. The body text goes into
+the main text layer, which, unless forced otherwise, lays on top.
+
+\startitemize[packed,n,columns,three]
+\item paper background
+\item area backgrounds
+\item page backgrounds
+\item text areas
+\item logo areas
+\item main text
+\stopitemize
+
+The paper background is used for special (sometimes internal) purposes. There are
+three page backgrounds: left, right and both. The text areas, logo areas and
+backgrounds form a $5 \times 5$ matrix with columns containing the leftedge,
+leftmargin, text, rightmargin, and rightedge. The rows of the matrix contain the
+top, header, text, footer, and bottom. The main text is what you are reading now.
+
+Since the page background is applied last, the previous layers can be considered
+to be the foreground to the page background layer. And, indeed, it is available
+as an overlay under the name \type {foreground}, as we already saw in the
+example. Foregrounds are available in most cases, but (for the moment) not when
+we are dealing with the text area. Since anchoring the graphics is implemented
+rather independent of the position of the graphics themselves, this is no real
+problem, we can put them all on the page layer, if needed in separate overlays.
+
+How is such a graphic defined? In fact these graphics are a special case of the
+already present mechanism of including \METAPOST\ graphics. The circles are
+defined as follows:
+
+\typebuffer[g-circle]
+
+Drawing the lines is handled in a similar fashion.
+
+\typebuffer[g-line]
+
+The command \tex {startMPpositiongraphic} defines a graphic, in this example we
+have called it \type {mypos:circle}. Here we show the definition out of order but
+normally you need to define it before you refer to it.
+
+The \METAPOST\ macro \type {positionbox} returns a box that is constructed from
+the coordinates and dimensions. After this call, the corners are available via
+\type {llcorner}, \type {lrcorner}, \type {urcorner} and \type {ulcorner}. The
+center is accessible by \type {center}. When we are finished drawing the graphic,
+we can anchor the result with \type {positioninregion}. This macro automatically
+handles positioning on specific layers. The helper macros are not loaded by
+default, you do that with:
+
+\typebuffer[g-include]
+
+The position macro \type {\MPpos} returns the current characteristics of a
+position. The previously defined G~positions return:
+
+\starttabulate[|c|c|c|c|c|c|c|]
+\HL
+\NC position\NC page\NC$x$\NC$y$\NC width\NC height\NC depth\NC\NR
+\HL
+\NC G-1\NC\MPp{G-1}\NC\MPx{G-1}\NC\MPy{G-1}\NC\MPw{G-1}\NC\MPh{G-1}\NC\MPd{G-1}\NC\NR
+\NC G-2\NC\MPp{G-2}\NC\MPx{G-2}\NC\MPy{G-2}\NC\MPw{G-2}\NC\MPh{G-2}\NC\MPd{G-2}\NC\NR
+\NC G-3\NC\MPp{G-3}\NC\MPx{G-3}\NC\MPy{G-3}\NC\MPw{G-3}\NC\MPh{G-3}\NC\MPd{G-3}\NC\NR
+\NC G-4\NC\MPp{G-4}\NC\MPx{G-4}\NC\MPy{G-4}\NC\MPw{G-4}\NC\MPh{G-4}\NC\MPd{G-4}\NC\NR
+\HL
+\stoptabulate
+
+The numbers represent the real pagenumber~$p$, the current position $(x,y)$, and
+the dimensions of the box $(w,h,d)$ if known. These values are fed directly into
+\METAPOST\ graphics but the individual components can be asked for by \type
+{\MPp}, \type {\MPx}, \type {\MPy}, \type {\MPw}, \type {\MPh} and \type {\MPd}.
+
+In the previous definition of the graphic, we saw another macro, \type {\MPvar}.
+When we invoke a graphic or attach a graphic to a layer, we can pass variables.
+We can also set specific variables in other ways, as we will see later.
+
+\starttyping
+\setMPpositiongraphic{G-1}{mypos:circle}
+\setMPpositiongraphic{G-1}{mypos:line}{to=G-2}
+\stoptyping
+
+In the second definition, we let the variable \type {to} point to another
+position. When needed, we can ask for the value of \type {to} by \type
+{\MPvar{to}}. For reasons of convenience, the current position is assigned
+automatically to \type {from} and \type {self}. This means that in the line we
+saw in the graphic:
+
+\starttyping
+path p ; p := positionbox(texstr("self")) ;
+\stoptyping
+
+\type {texstr("self")} will return the current position, which, fed to \type
+{positionbox} will return a box with the right dimensions. We already warned the
+reader: this is not an easy chapter.
+
+\stopsection
+
+\startsection[title={More layers}]
+
+\index{layers}
+
+\setupbackgrounds
+ [state=repeat]
+
+Overlays are one of the nicer features of \CONTEXT\ and even more nice things can
+be build on top of them. Overlays are defined first and then assigned to framed
+boxes using the \type {background} variable.
+
+You can stack overlays, which is why they are called as such. You can use the
+special overlay called \type {foreground} to move the topmost (often text) layer
+down in the stack.
+
+\starttabulate
+\HL
+\NC background overlay \NC a text, graphic, hyperlink or widget \NC \NR
+\NC position overlay \NC a series of macros triggered by positions \NC \NR
+\NC background layer \NC a box that can hold boxes with offsets \NC \NR
+\HL
+\stoptabulate
+
+The last kind of layer can be used in other situations as well, but in most cases
+it will be hooked into a background overlay.
+
+\startbuffer
+\definelayer[MyLayer][option=test]
+
+\setupbackgrounds[text][leftmargin][background=MyLayer]
+
+\setlayer[MyLayer][x=.5cm,y=5cm]
+ {\rotate{\framed{This goes to the background}}}
+\stopbuffer
+
+\typebuffer \getbuffer \setuplayer[MyLayer][option=] % no frames
+
+In this case the framed text will be placed in the background of the (current)
+page with the given offset to the topleft corner. Instead of a fixed position,
+you can inherit the current position using the \type {position} directive. Say
+that we have a layer called \type {YourLayer} which we put in the background of
+the text area.
+
+\startbuffer
+\definelayer[YourLayer]
+\setupbackgrounds[text][text][background=YourLayer]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We can now move some framed text to this layer using \type {\setlayer} with the
+directive \type {position} set to \type {yes}.
+
+\startbuffer
+here: \setlayer[YourLayer][position=yes]{\inframed{Here}}
+\stopbuffer
+
+\typebuffer
+
+You can influence the placement by explicitly providing an offset (\type
+{hoffset} and|/|or \type {voffset}), a position (\type {x} and|/|or \type {y}) or
+a location directive (\type {location}). Normally you will use the offsets for
+the layer as a whole and the positions for individual contributions. The next
+example demonstrates the use of a location directive.
+
+\startbuffer
+here: \setlayer[YourLayer][position=yes,location=c]{\inframed{Here}}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Many layers can be in use at the same time. In the next example we put something
+in the page layer. By default, we turn on position tracking, which visualizes the
+bounding box of the content and shows the reference point.
+
+\startbuffer
+\definelayer[BackLayer][position=yes]
+\setupbackgrounds[page][background=BackLayer]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\setupbackgrounds
+ [page]
+ [background={PageFrame,BackLayer,backgraphics,foreground,foregraphics}]
+
+Next we define an overlay that we can put behind for instance framed texts. We
+use \METAPOST\ to draw \type {Shape}.
+
+\startbuffer
+\defineoverlay[Shape] [BackLayer] [\uniqueMPgraphic{Shape}]
+
+\startuniqueMPgraphic{Shape}
+ path p ; p := fullcircle xyscaled(OverlayWidth,OverlayHeight) ;
+ fill p withcolor \MPcolor{lightgray} ;
+ draw p withpen pencircle scaled 1pt withcolor \MPcolor{darkred} ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer[def]
+\defineframed[Shaped][background=Shape,frame=off,location=low]
+\stopbuffer
+
+\getbuffer[def]
+
+We can now put this background shape behind the running text, for instance with:
+
+\startbuffer
+.... some \inframed[background=Shape]{text} with a frame ...
+.... some \Shaped{text} with a frame ...
+\stopbuffer
+
+\typebuffer
+
+\startlines
+\getbuffer
+\stoplines
+
+The \type {\Shaped} macro was defined as:
+
+\typebuffer[def]
+
+Watch how the graphics are moved to the background while the frame of the first
+text stays on top, since it remains part of the text flow.
+
+\startbuffer[def]
+\setuplayer[BackLayer][direction=reverse]
+\stopbuffer
+
+\getbuffer[def]
+
+\startlines
+\getbuffer
+\stoplines
+
+In the previous instance of the example we have reversed the stacking. Reversal
+can be done with the \type {direction} directive.
+
+\typebuffer[def]
+
+% next series
+
+\startbuffer
+\setuplayer
+ [BackLayer]
+ [position=no,corner=bottom,height=\paperheight]
+
+\setlayer[BackLayer][x=2cm,y=10cm,location=bl]
+ {\externalfigure[somecow.pdf][width=1cm]}
+
+\setlayer[BackLayer][x=1cm,y=8cm,location=br]
+ {\externalfigure[somecow.pdf][width=1cm]}
+
+\setlayer[BackLayer][x=2cm,y=4cm,location=tl]
+ {\externalfigure[somecow.pdf][width=1cm]}
+
+\setlayer[BackLayer][x=10cm,y=1cm,location=tr]
+ {\externalfigure[somecow.pdf][width=1cm]}
+\stopbuffer
+
+You can influence the placement of a background component by using a different
+anchor point.
+
+\typebuffer {\setuplayer[option=test]\getbuffer}
+
+\startbuffer[xx]
+\setuplayer
+ [BackLayer]
+ [position=no,corner=bottom,height=\paperheight]
+
+\setlayer[BackLayer][x=15cm,y=5cm,location=bl]
+ {\externalfigure[somecow.pdf][width=3cm]}
+
+\setlayer[BackLayer][x=15cm,y=5cm,location=br]
+ {\externalfigure[somecow.pdf][width=3cm]}
+
+\setlayer[BackLayer][x=15cm,y=5cm,location=tl]
+ {\externalfigure[somecow.pdf][width=2cm]}
+
+\setlayer[BackLayer][x=15cm,y=5cm,location=tr]
+ {\externalfigure[somecow.pdf][width=2cm]}
+
+\setlayer[BackLayer][x=15cm,y=5cm,location=c]
+ {\externalfigure[somecow.pdf][width=3cm]}
+\stopbuffer
+
+% \startpostponing
+
+Instead of using relative positions, you can also use absolute ones. Of course
+you need to know how your coordinates relate to the rest of the layout
+definition.
+
+\typebuffer[xx]
+
+These examples again demonstrate how we can influence the placement by assigning
+an anchor point to \type {position}. Here we also put the reference point in the
+lower left corner (\type {bottom}). This mechanism only works when we also use
+\type {height}.
+
+{\setuplayer[option=test]\getbuffer[xx]}
+
+\page
+
+% \stoppostponing
+
+\setupbackgrounds
+ [page]
+ [background={PageFrame,DemoLayer,backgraphics,foreground,foregraphics}]
+
+\definelayer
+ [DemoLayer]
+ [position=yes]
+
+\startbuffer
+\definelayer
+ [DemoLayer]
+ [position=yes]
+
+\startplacefigure[title={Demo 1}]
+ \ruledhbox\bgroup
+ \setlayerframed
+ [DemoLayer] [hoffset=-10mm,voffset=5mm]
+ {\startMPcode
+ fill fullcircle scaled 2cm withcolor .625red ;
+ \stopMPcode}%
+ \setlayerframed
+ [DemoLayer] [voffset=-10mm]
+ {\startMPcode
+ fill fullcircle scaled 2cm withcolor .625green ;
+ \stopMPcode}%
+ \setlayerframed
+ [DemoLayer] [hoffset=10mm,voffset=5mm]
+ {\startMPcode
+ fill fullcircle scaled 2cm withcolor .625blue ;
+ \stopMPcode}%
+ \egroup
+\stopplacefigure
+\stopbuffer
+
+\getbuffer
+
+One of the reasons for developing the layer mechanism was that we needed to
+slightly change the position of figures in the final stage of typesetting. The
+previous pages demonstrate how one can position anything anywhere on the page,
+but in the case of figures the position may depend on where the text ends up on
+the page.
+
+Normally, when you manipulate a document this way, you are in the final stage of
+typesetting. You may qualify this as desk top publishing without actually using a
+desktop.
+
+\typebuffer
+
+\startbuffer[demo]
+\startbuffer
+\setlayer [DemoLayer]
+ [position=yes,
+ voffset=-1.5cm,
+ width=3cm,
+ height=2cm]
+ {\MPfigure{somecow.pdf}{scaled .5 slanted .5}}
+\stopbuffer
+
+\placefigure[right]{}{\ruledhbox{\getbuffer}}
+\stopbuffer
+
+{\setuplayer[option=test]\getbuffer[demo]}
+
+The previous example also demonstrated the use of \METAPOST\ for rotating the
+picture. The \type {\MPfigure} macro encapsulates the code in a shortcut. You can
+achieve special effects by using the layers behind floating bodies and alike, but
+always keep in mind that the readability of the text should not be violated too
+much.
+
+\typebuffer[demo]
+
+In these examples we added a \type {\ruledhbox} around the pseudo graphics so
+that you can see what the size is of those graphics.
+
+% summary
+
+We have already seen a lot of parameters that can be used to control the content
+of a layer. There are a few more. General housekeeping takes place with:
+
+\starttabulate[|Tl|Tl|l|]
+\HL
+\NC state \NC start \NC enable the layer \NC \NR
+\NC \NC stop \NC disable the layer \NC \NR
+\NC position \NC no \NC use absolute positions \NC \NR
+\NC \NC yes \NC use relative positions \NC \NR
+\NC \NC overlay \NC idem, but ignore the size \NC \NR
+\NC direction \NC normal \NC put new data on top \NC \NR
+\NC \NC reverse \NC put new data below old data \NC \NR
+\HL
+\stoptabulate
+
+Sometimes all data needs to be offset in a similar way. You can use both offset
+parameters for that.
+
+\starttabulate[|Tl|l|]
+\HL
+\NC hoffset \NC an additional horizontal displacement \NC \NR
+\NC voffset \NC an additional vertical displacement \NC \NR
+\HL
+\stoptabulate
+
+You can position data anywhere in the layer. When positioning is turned on, the
+current position will get a placeholder. You can change the dimensions of that
+placeholder (when \type {position} is set to \type {overlay}), zero dimensions
+are used.
+
+\starttabulate[|Tl|l|]
+\HL
+\NC x \NC the horizontal displacement \NC \NR
+\NC y \NC the vertical displacement \NC \NR
+\NC width \NC the (non natural) width \NC \NR
+\NC height \NC the (non natural) height \NC \NR
+\NC location \NC \tttf l r t b c lt lb rt rb \NC \NR
+\HL
+\stoptabulate
+
+The \type {location} directive determines what point of the data is used as
+reference point. You can keep track of this point and the placement when you
+enable test mode. This is how the rectangles in the previous examples were
+drawn.
+
+\starttabulate[|Tl|Tl|l|]
+\HL
+\NC option \NC test \NC show positioning information \NC \NR
+\HL
+\stoptabulate
+
+When you are enhancing the final version of a document, you can explicitly
+specify on what page the data will go. Use this option with care.
+
+\starttabulate[|Tl|l|]
+\HL
+\NC page \NC the page where the data will go \NC \NR
+\HL
+\stoptabulate
+
+Because layers can migrate to other pages, they may disappear due to the
+background not being recalculated. In case of doubt, you can force repetitive
+background calculation by:
+
+\starttyping
+\setupbackgrounds[state=repeat]
+\stoptyping
+
+% restore 'm
+
+\setupbackgrounds
+ [page]
+ [background={PageFrame,backgraphics,foreground,foregraphics}]
+
+\setupbackgrounds
+ [state=start]
+
+\stopsection
+
+\startsection[title={Complex text in graphics}]
+
+\index{text}
+
+If you like to embed \METAPOST\ snippets in \CONTEXT, you may want to combine
+text and graphics and let \METAPOST\ provide the position and the dimensions of
+the text to be typeset outside by \TEX. For most applications using the \METAFUN\
+\type {textext} macro works well enough, but when the typeset text needs to
+communicate with the typesetting engine, for instance because it contains
+hyperlinks or references, you can use the following method:
+
+\startitemize[packed]
+\item define a layer
+\item define a (reusable) graphic
+\item put your text into the layer
+\item combine the graphic with the text
+\stopitemize
+
+You must be aware of the fact that when the layer is flushed, its content is
+gone. You can take advantage of this by using the same graphic with multiple
+texts.
+
+\startbuffer
+\definelayer[test]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+You don't need to pass the width and height explicitly, but when you do so, you
+have access to them later.
+
+\startbuffer
+\startuseMPgraphic{oeps}
+ path p ; p := fullcircle scaled 6cm ;
+ fill p withcolor .8white ;
+ draw p withpen pencircle scaled 1mm withcolor .625red ;
+ register ("somepos-1",0cm,0cm,center currentpicture) ;
+ register ("somepos-2",3cm,1cm,(-1cm,-1cm)) ;
+ register ("somepos-3",2cm,0cm,(-2cm,2cm)) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The \METAFUN\ \type {register} macro takes the following arguments:
+
+\starttyping
+register ("tag",width,height,(x offset,y offset)) ;
+\stoptyping
+
+The width and height are available in the macros \type {\MPlayerwidth} and \type
+{\MPlayerheight} and are equivalent to \type {\MPw{tag}} and \type {\MPh{tag}},
+
+\startbuffer
+\setMPlayer [test] [somepos-1] [location=c]
+ {Does it work al right?}
+
+\setMPlayer [test] [somepos-2]
+ {\framed
+ [width=\MPlayerwidth,height=\MPlayerheight,
+ background=color,backgroundcolor=white]
+ {It Works!}}
+
+\setMPlayer [test] [somepos-3]
+ {\externalfigure[cow-fun.mps][width=2cm]}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Combining the graphic and the text is handled by the macro \type {\getMPlayer}.
+
+\startbuffer
+\getMPlayer [test] {\useMPgraphic{oeps}}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The macro \type {\getMPlayer} is built on top of \type {\framed}. The settings
+passed in the (optional) second argument are the same as those to \type
+{\framed}.
+
+\starttyping
+\getMPlayer
+ [test]
+ [frame=on,offset=5pt]
+ {\useMPgraphic{oeps}}
+\stoptyping
+
+As you see, you need a bit of a twisted mind to handle graphics this way, but at
+least the functionality is there to create complex graphics in a declarative way.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-reference.tex b/doc/context/sources/general/manuals/metafun/metafun-reference.tex
new file mode 100644
index 000000000..6eb177949
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-reference.tex
@@ -0,0 +1,659 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-reference
+
+\environment metafun-environment
+
+\startchapter[reference=reference,title={Reference}]
+
+\startintro
+
+In this chapter, we will demonstrate most of the drawing related primitives and
+macros as present in plain \METAPOST\ and \METAFUN\ extensions.
+
+If a path is shown and|/|or a transformation is applied, we show the original in
+red and the transformed path or point in yellow. The small dark gray crosshair is
+the origin and the black rectangle the bounding box. In some drawings, in light
+gray we show the points that make up the path.
+
+This list describes traditional \METAPOST\ and the stable part of \METAFUN. As
+\METAPOST\ evolves, new primitives are added but they are not always that
+relevant to us. If you browse the \METAFUN\ sources you will for sure notice more
+functionality than summarized here. Most of that is meant for usage in \CONTEXT\
+and not exposed to the user. Other macros are still somewhat experimental but
+might become more official at some point. The same is true for \METAFUN\
+commands: not all make sense for daily usage and some are just there as helper
+for additional modules.
+
+\stopintro
+
+\startsection[title={Paths}]
+
+\index{paths}
+
+\ShowSampleA {mc} {pair} {(1,.5)}
+\ShowSampleA {mm} {pair .. pair} {(0,0)..(.75,0)..(1,.25)..(1,1)}
+\ShowSampleA {mm} {pair ... pair} {(0,0)..(.75,0)...(1,.25)..(1,1)}
+\ShowSampleA {mm} {pair -- pair\quad (a)} {(0,0)--(.75,0)--(1,.25)--(1,1)}
+\ShowSampleA {mm} {pair -- pair\quad (b)} {(0,0)..(.75,0)--(1,.25)..(1,1)}
+\ShowSampleA {mm} {pair --- pair} {(0,0)..(.75,0)---(1,.25)..(1,1)}
+
+\ShowSampleA {mm} {pair softjoin pair} {(0,0)..(.75,0) softjoin (1,.25)..(1,1)}
+\ShowSampleA {mp} {controls pair} {(0,0)..controls (.75,0)..(1,1)}
+\ShowSampleA {mp} {controls pair and pair} {(0,0)..controls (.75,0) and (1,.25)..(1,1)}
+\ShowSampleA {mp} {tension numeric} {(0,0)..(.75,0)..tension 2.5..(1,.25)..(1,1)}
+\ShowSampleA {mp} {tension num.. and num..} {(0,0)..(.75,0)..tension 2.5 and 1.5..(1,.25)..(1,1)}
+\ShowSampleA {mp} {tension atleast numeric} {(0,0)..(.75,0)..tension atleast 1..(1,.25)..(1,1)}
+
+\ShowSampleA {mp} {cycle} {(0,0)--(1,0)--(1,1)--cycle}
+\ShowSampleA {mp} {curl numeric} {(0,0){curl 1}..(.75,0)..(1,.25)..(1,1)}
+\ShowSampleA {mp} {dir numeric} {(0,0){dir 30}..(1,1)}
+\ShowSampleA {mm} {left} {(0,0){left}..(1,1)}
+\ShowSampleA {mm} {right} {(0,0){right}..(1,1)}
+\ShowSampleA {mm} {up} {(0,0){up}..(1,1)}
+\ShowSampleA {mm} {down} {(0,0){down}..(1,1)}
+
+\ShowSampleA {mp} {path \& path} {(0,0)..(.75,.25) \& (.75,.25)..(1,1)}
+
+\ShowSampleA {mv} {unitvector} {origin--unitvector(1,1)}
+\ShowSampleA {mp} {dir} {origin--dir(45)}
+\ShowSampleA {mp} {angle} {origin--dir(angle(1,1))}
+
+\ShowSampleA {mv} {fullcircle} {fullcircle}
+\ShowSampleA {fv} {unitcircle} {unitcircle}
+\ShowSampleA {fv} {fullsquare} {fullsquare}
+\ShowSampleA {mv} {unitsquare} {unitsquare}
+\ShowSampleA {fv} {fulltriangle}{fulltriangle}
+\ShowSampleA {fv} {unittriangle}{unittriangle}
+\ShowSampleA {fv} {fulldiamond} {fulldiamond}
+\ShowSampleA {fv} {unitdiamond} {unitdiamond}
+
+\ShowSampleA {mv} {halfcircle} {halfcircle}
+\ShowSampleA {mv} {quartercircle} {quartercircle}
+
+\ShowSampleA {fv} {llcircle} {llcircle}
+\ShowSampleA {fv} {lrcircle} {lrcircle}
+\ShowSampleA {fv} {urcircle} {urcircle}
+\ShowSampleA {fv} {ulcircle} {ulcircle}
+\ShowSampleA {fv} {tcircle} {tcircle}
+\ShowSampleA {fv} {bcircle} {bcircle}
+\ShowSampleA {fv} {lcircle} {lcircle}
+\ShowSampleA {fv} {rcircle} {rcircle}
+
+\ShowSampleA {fv} {triangle} {triangle}
+\ShowSampleA {fv} {righttriangle} {righttriangle}
+\ShowSampleA {fv} {uptriangle} {uptriangle}
+\ShowSampleA {fv} {lefttriangle} {lefttriangle}
+\ShowSampleA {fv} {downtriangle} {downtriangle}
+
+\ShowSampleA {fv} {lltriangle} {lltriangle}
+\ShowSampleA {fv} {lrtriangle} {lrtriangle}
+\ShowSampleA {fv} {urtriangle} {urtriangle}
+\ShowSampleA {fv} {ultriangle} {ultriangle}
+
+\ShowSampleA {mm} {flex(pair,pair,pair)}
+ {flex ((0,0),(1,1),(1,0))}
+\ShowSampleA {mm} {superellipse(pair,p..,p..,p..,num..)}
+ {superellipse((1,.5),(.5,1),(0,.5),(.5,0),.75)}
+
+\ShowSampleA {fm} {path smoothed numeric/pair} {unitsquare scaled 1.5 smoothed .2}
+\ShowSampleA {fm} {path cornered numeric/pair} {lltriangle scaled 1.5 cornered .2}
+\ShowSampleA {fm} {path superellipsed numeric} {unitsquare scaled 1.5 superellipsed .75}
+\ShowSampleA {fm} {path randomized numeric/pair} {unitsquare scaled 1.5 randomized (.2,.2)}
+\ShowSampleA {fm} {path randomizedcontrols numeric/pair} {fullcircle scaled 1.5 randomizedcontrols (.2,.2)}
+\ShowSampleA {fm} {path squeezed numeric/pair} {unitsquare scaled 1.5 squeezed (.2,.1)}
+\ShowSampleA {fm} {path snapped numeric/pair} {fullcircle scaled 1.5 snapped (.2,.1)}
+
+\ShowSampleB {fm} {punked path}
+ {unitcircle scaled 1.5}
+ {punked unitcircle scaled 1.5}
+
+\ShowSampleB {fm} {curved path}
+ {((0,0)--(.2,1)--(1,.2)--cycle)}
+ {curved ((0,0)--(.2,1)--(1,.2)--cycle)}
+
+\ShowSampleB {fm} {laddered path}
+ {((0,0)--(1.4,.8)--(2.8,1.2)--(6.2,1.6))}
+ {laddered ((0,0)--(1.4,.8)--(2.8,1.2)--(6.2,1.6))}
+
+\ShowSampleB {fm} {path paralleled distance}
+ {((0,0)--(5,1))}
+ {((0,0)--(5,1)) paralleled .25}
+
+\ShowSampleB {fm} {shortened path}
+ {((0,0)--(6,1))}
+ {((0,0)--(6,1)) shortened 1}
+
+\ShowSampleB {fm} {unspiked path}
+ {((0,0)--(1,0)--(1,1)--(2,1)--(1,1)--(0,1)) shifted (-3,0)}
+ {unspiked ((0,0)--(1,0)--(1,1)--(2,1)--(1,1)--(0,1))}
+
+\ShowSampleB {fm} {simplified path}
+ {((0,0)--(1,0)--(2,0)--(2,1)--(0,1)--cycle) shifted (-3,0)}
+ {simplified ((0,0)--(1,0)--(2,0)--(2,1)--(0,1)--cycle)}
+
+\ShowSampleB {fm} {path blownup numeric/pair}
+ {fullcircle scaled 1.5}
+ {(fullcircle scaled 1.5) blownup .1}
+
+\ShowSampleB {fm} {path stretched numeric/pair\quad (a)}
+ {fullcircle scaled 1.5}
+ {(fullcircle scaled 1.5) stretched (1.1,0.8)}
+
+\ShowSampleB {fm} {path stretched numeric\quad (b)}
+ {((0,0)--(1,1))}
+ {((0,0)--(1,1)) stretched 1.5}
+
+\ShowSampleB {fm} {path xstretched numeric}
+ {fullcircle}
+ {fullcircle xstretched 5}
+
+\ShowSampleB {fm} {path ystretched numeric}
+ {fullcircle}
+ {fullcircle ystretched 1.5}
+
+\ShowSampleB {fm} {path enlonged numeric}
+ {((0,0)--(1,1))}
+ {((0,0)--(1,1)) enlonged 1.5}
+
+\ShowSampleB {fm} {path shorted numeric}
+ {((0,0)--(2,2))}
+ {((0,0)--(2,2)) shortened 0.5}
+
+\ShowSampleA {fm} {roundedsquare(num..,num..,num..)}
+ {roundedsquare(2,1,.2)}
+
+\ShowSampleA {fm} {tensecircle(num..,num..,num..)}
+ {tensecircle(2,1,.2)}
+
+\ShowSampleA {fm} {pair crossed size}
+ {origin crossed 1}
+
+\ShowSampleA {fm} {path crossed size}
+ {fullcircle scaled 2 crossed .5}
+
+\ShowSampleA {fm} {(constructed)function}
+ {constructedfunction("--")("x","sin(x)",0,2pi,pi/10)}
+
+\ShowSampleA {fm} {curvedfunction}
+ {curvedfunction("x","sin(x)",0,2pi,pi/10)}
+
+\ShowSampleA {fm} {straightfunction}
+ {straightfunction("x","sin(x)",0,2pi,pi/10)}
+
+\ShowSampleA {fm} {constructedpath}
+ {constructedpath("..")((0,0),(1,2),(2,1),(3,2))}
+
+\ShowSampleA {fm} {curvedpath}
+ {curvedpath((0,0),(1,2),(2,1),(3,2))}
+
+\ShowSampleA {fm} {straightpath}
+ {straightpath((0,0),(1,2),(2,1),(3,2))}
+
+\ShowSampleA {fm} {leftarrow}
+ {leftarrow(fullcircle,3,2)}
+
+\ShowSampleA {fm} {rightarrow}
+ {rightarrow(fullcircle,3,2)}
+
+\ShowSampleA {fm} {centerarrow}
+ {centerarrow(fullcircle,3,2)}
+
+\ShowSampleX {fm} {arrowhead} {draw arrowhead fullcircle}
+\ShowSampleX {fm} {arrowpath} {draw arrowpath fullcircle}
+
+\ShowSampleA {mm} {buildcycle}
+ {buildcycle(fullcircle,fullsquare)}
+
+\ShowSampleA {fm} {circularpath} {circularpath(4)}
+\ShowSampleA {fm} {squarepath} {squarepath(4)}
+\ShowSampleA {fm} {linearpath} {linearpath(4)}
+
+\stopsection
+
+\startsection[title={Transformations}]
+
+\index{transformations}
+
+\ShowSampleB {mp} {path scaled numeric} {fullcircle} {fullcircle scaled .50}
+\ShowSampleB {mp} {path xscaled numeric} {fullcircle} {fullcircle xscaled .25}
+\ShowSampleB {mp} {path yscaled numeric} {fullcircle} {fullcircle yscaled .25}
+\ShowSampleB {mp} {path zscaled pair} {fullcircle} {fullcircle zscaled (2,.25)}
+\ShowSampleB {mp} {path xyscaled numeric/pair} {fullcircle} {fullcircle xyscaled (.5,.7)}
+\ShowSampleB {mp} {path xyscaled pair} {fullcircle} {fullcircle xyscaled (2,.25)}
+\ShowSampleB {mp} {path shifted pair} {fullcircle} {fullcircle shifted (2,.25)}
+
+\ShowSampleB {fm} {path leftenlarged numeric} {fullsquare} {fullsquare leftenlarged .25}
+\ShowSampleB {fm} {path topenlarged numeric} {fullsquare} {fullsquare topenlarged .25}
+\ShowSampleB {fm} {path rightenlarged numeric} {fullsquare} {fullsquare rightenlarged .25}
+\ShowSampleB {fm} {path bottomenlarged numeric} {fullsquare} {fullsquare bottomenlarged .25}
+
+\ShowSampleB {fm} {path enlarged numeric} {fullcircle} {fullcircle enlarged .25}
+\ShowSampleB {fm} {path enlarged pair} {fullcircle} {fullcircle enlarged (1,.25)}
+\ShowSampleB {fm} {path llenlarged numeric} {fullcircle} {fullcircle llenlarged .25}
+\ShowSampleB {fm} {path lrenlarged numeric} {fullcircle} {fullcircle lrenlarged .25}
+\ShowSampleB {fm} {path urenlarged numeric} {fullcircle} {fullcircle urenlarged .25}
+\ShowSampleB {fm} {path ulenlarged numeric} {fullcircle} {fullcircle ulenlarged .25}
+\ShowSampleB {fm} {path llenlarged pair} {fullcircle} {fullcircle llenlarged (1,.25)}
+\ShowSampleB {fm} {path lrenlarged pair} {fullcircle} {fullcircle lrenlarged (1,.25)}
+\ShowSampleB {fm} {path urenlarged pair} {fullcircle} {fullcircle urenlarged (1,.25)}
+\ShowSampleB {fm} {path ulenlarged pair} {fullcircle} {fullcircle ulenlarged (1,.25)}
+\ShowSampleB {fm} {path llmoved numeric} {fullcircle} {fullcircle llmoved .25}
+\ShowSampleB {fm} {path lrmoved numeric} {fullcircle} {fullcircle lrmoved .25}
+\ShowSampleB {fm} {path urmoved numeric} {fullcircle} {fullcircle urmoved .25}
+\ShowSampleB {fm} {path ulmoved numeric} {fullcircle} {fullcircle ulmoved .25}
+\ShowSampleB {fm} {path llmoved pair} {fullcircle} {fullcircle llmoved (1,.25)}
+\ShowSampleB {fm} {path lrmoved pair} {fullcircle} {fullcircle lrmoved (1,.25)}
+\ShowSampleB {fm} {path urmoved pair} {fullcircle} {fullcircle urmoved (1,.25)}
+\ShowSampleB {fm} {path ulmoved pair} {fullcircle} {fullcircle ulmoved (1,.25)}
+\ShowSampleB {mp} {path slanted numeric} {fullcircle} {fullcircle slanted .5}
+\ShowSampleB {mp} {path rotated numeric} {fullsquare} {fullsquare rotated 45}
+
+\ShowSampleB {mm} {path rotatedaround(pair,numeric)} {fullsquare} {fullsquare rotatedaround((.25,.5),45)}
+\ShowSampleB {mm} {path reflectedabout(pair,pair)} {fullcircle} {fullcircle reflectedabout((.25,-1),(.25,+1))}
+\ShowSampleB {mp} {reverse path} {fullcircle} {reverse fullcircle shifted(.5,0)}
+\ShowSampleB {mm} {counterclockwise path} {fullcircle} {counterclockwise fullcircle shifted(.5,0)}
+\ShowSampleB {mm} {tensepath path} {fullcircle} {tensepath fullcircle}
+
+\ShowSampleB {mp} {subpath (numeric,numeric) of path} {fullcircle} {subpath (1,5) of fullcircle}
+\ShowSampleB {mm} {path cutbefore pair} {fullcircle} {fullcircle cutbefore point 3 of fullcircle}
+\ShowSampleB {mm} {path cutafter pair} {fullcircle} {fullcircle cutafter point 3 of fullcircle}
+\ShowSampleB {mm} {path cutends .1} {fullcircle} {fullcircle cutends .5}
+
+\ShowSampleC {mp} {llcorner path} {fullcircle} {llcorner fullcircle}
+\ShowSampleC {mp} {lrcorner path} {fullcircle} {lrcorner fullcircle}
+\ShowSampleC {mp} {urcorner path} {fullcircle} {urcorner fullcircle}
+\ShowSampleC {mp} {ulcorner path} {fullcircle} {ulcorner fullcircle}
+\ShowSampleC {mm} {center path} {fullcircle} {center fullcircle}
+
+\ShowSampleD {fm} {boundingbox path} {fullcircle} {boundingbox fullcircle}
+\ShowSampleD {fm} {boundingcircle path} {fullsquare} {boundingcircle fullsquare}
+\ShowSampleD {fm} {innerboundingbox path} {fullcircle} {innerboundingbox fullcircle}
+\ShowSampleD {fm} {outerboundingbox path} {fullcircle} {outerboundingbox fullcircle}
+
+\ShowSampleDD {fm} {bottomboundary path} {fullcircle} {bottomboundary fullcircle}
+\ShowSampleDD {fm} {leftboundary path} {fullcircle} {leftboundary fullcircle}
+\ShowSampleDD {fm} {topboundary path} {fullcircle} {topboundary fullcircle}
+\ShowSampleDD {fm} {rightboundary path} {fullcircle} {rightboundary fullcircle}
+
+\ShowSampleP {fm} {bbwidth path} {draw textext(decimal bbwidth (fullcircle xscaled 100 yscaled 200))}
+\ShowSampleP {fm} {bbwidth path} {draw textext(decimal bbheight (fullcircle xscaled 100 yscaled 200))}
+
+\ShowSampleE {fm} {path/picture xsized numeric} {xsized 3cm} {currentpicture xsized 5cm}
+\ShowSampleE {fm} {path/picture ysized numeric} {ysized 2cm} {currentpicture ysized 2cm}
+\ShowSampleE {fm} {path/picture xysized numeric} {xysized (3cm,2cm)} {currentpicture xysized (3cm,2cm)}
+
+\ShowSampleP {fm}
+ {area path}
+ {draw area ((0,10)--(20,20)--(30,5)--(40,10)--(50,5)--(60,5))}
+
+\ShowSampleT {mp}
+ {setbounds picture}
+ {draw fullcircle ; setbounds currentpicture to unitsquare}
+ {draw fullcircle scaled .5 InGray; setbounds currentpicture to unitsquare scaled .5}
+
+\ShowSampleT {mm}
+ {clip path}
+ {fill fullcircle ; clip currentpicture to fullsquare scaled 0.9}
+ {fill fullcircle scaled 1 InRed ; clip currentpicture to fullsquare scaled 0.9}
+
+\ShowSampleT {mm}
+ {path peepholed path}
+ {fill (fullcircle peepholed fullsquare)}
+ {fill (fullcircle peepholed fullsquare) InRed}
+
+\ShowSampleT {fm}
+ {anchored}
+ {draw anchored.urt(textext("ll"),origin)}
+ {draw anchored.urt(textext("ll") xsized (5mm/Scale),origin) InRed ;}
+
+% \ShowSampleT {fm}
+% {autoalign}
+% {draw textext.autoalign(260)("260")}
+% {draw textext.autoalign(260)("260")}
+
+% draw textext.autoalign(260)("\strut oeps 3") ;
+
+\ShowSampleX {fm}
+ {path crossingunder path}
+ {draw (fullsquare rotated 45) crossingunder fullsquare}
+
+\stopsection
+
+\startsection[title={Points}]
+
+\index{points}
+
+%ShowSampleF {mp} {center path} {fullcircle} {center fullcircle}
+\ShowSampleF {mm} {top pair} {fullcircle} {top center fullcircle}
+\ShowSampleF {mm} {bot pair} {fullcircle} {bot center fullcircle}
+\ShowSampleF {mm} {lft pair} {fullcircle} {lft center fullcircle}
+\ShowSampleF {mm} {rt pair} {fullcircle} {rt center fullcircle}
+\ShowSampleF {mp} {point numeric of path} {fullcircle} {point 2 of fullcircle}
+\ShowSampleF {fm} {point numeric on path} {fullcircle} {point .5 on fullcircle}
+\ShowSampleF {fm} {point numeric along path} {fullcircle} {point 1cm along fullcircle}
+\ShowSampleF {mp} {precontrol numeric of path} {fullcircle} {precontrol 2 of fullcircle}
+\ShowSampleF {mp} {postcontrol numeric of path} {fullcircle} {postcontrol 2 of fullcircle}
+\ShowSampleF {mp} {directionpoint pair of path} {fullcircle} {directionpoint (2,3) of fullcircle}
+
+\ShowSampleG {mc} {numeric[pair,pair]} {(1,1)} {.5[(0,0),(1,1)]}
+
+\ShowSampleH {mm} {path intersectionpoint path} {fullcircle} {fulldiamond}
+ {fullcircle intersectionpoint fulldiamond}
+
+\ShowSampleHH {mm} {interpath(numeric,path,path}
+ {interpath(.8,fullcircle,fullsquare)}
+
+\ShowSampleHH {fm} {interpolated(numeric,path,path}
+ {interpolated(.8,fullcircle,fullsquare)}
+
+\ShowSampleO {mm} {right} {draw left}
+\ShowSampleO {mm} {up} {draw up}
+\ShowSampleO {mm} {left} {draw left}
+\ShowSampleO {mm} {down} {draw down}
+
+\stopsection
+
+\startsection[title={Colors}]
+
+\index{colors}
+
+\ShowSampleI {mp} {withcolor rgbcolor} {withcolor (.625,0,0)}
+\ShowSampleI {mp} {withrgbcolor rgbcolor} {withrgbcolor (.625,0,0)}
+\ShowSampleI {mp} {withcmykcolor cmykcolor} {withcmykcolor (.375,0,0,0)}
+\ShowSampleI {mp} {withgray / withgrey numeric} {withgray .625}
+\ShowSampleI {mp} {withcolor namedcolor} {withcolor namedcolor("darkblue")}
+\ShowSampleI {mp} {withcolor spotcolor} {withcolor spotcolor("tempone",red/2)}
+\ShowSampleI {mp} {withcolor multitonecolor} {withcolor .2 * multitonecolor("temptwo",blue/2,yellow/3)}
+
+Remark: at the time of this writing only Acrobat shows spot- and multitonecolors
+properly. Possible indications of a viewing problem are factors not being applied
+(in the page stream) or colors that are way off.
+
+\ShowSampleU {mp} {red} {fill fullcircle scaled 2 withcolor red/2}
+\ShowSampleU {mp} {green} {fill fullcircle scaled 2 withcolor green/2}
+\ShowSampleU {mp} {blue} {fill fullcircle scaled 2 withcolor blue/2}
+\ShowSampleU {mp} {cyan} {fill fullcircle scaled 2 withcolor cyan/2}
+\ShowSampleU {mp} {magenta} {fill fullcircle scaled 2 withcolor magenta/2}
+\ShowSampleU {mp} {yellow} {fill fullcircle scaled 2 withcolor yellow/2}
+\ShowSampleU {mp} {black} {fill fullcircle scaled 2 withcolor black/2}
+\ShowSampleU {mp} {white} {fill fullcircle scaled 2 withcolor white/2}
+
+\ShowSampleU {mp} {blackcolor} {fill fullcircle withcolor blackcolor red}
+
+%ShowSampleI {fm} {withcolor cmyk(c,m,y,k)} {withcolor cmyk(0,.625,.625,0)}
+%ShowSampleI {fm} {withcolor transparent(n.m,color)} {withcolor transparent(1,.625,red)}
+
+\ShowSampleI {fm} {withtransparency(num,num)} {withcolor red withtransparency (1,.625)}
+
+% \ShowSampleZ {fm} {withshade numeric} {Shades need to be declared before they can be (re)used.}
+
+\startMPinclusions
+ defineshade cshade withshademethod "circular" ;
+ defineshade lshade withshademethod "linear" ;
+\stopMPinclusions
+
+\ShowSampleW {fm} {shaded someshade }
+ {fill fullsquare shaded lshade}
+ {fill fullsquare scaled 2cm shaded lshade}
+
+This assumes the definition:
+
+\starttyping
+defineshade lshade withshademethod "linear" ;
+\stoptyping
+
+\ShowSampleW {fm} {shaded someshade}
+ {fill fullcircle shaded cshade}
+ {fill fullcircle scaled 2cm shaded cshade}
+
+This assumes the definition:
+
+\starttyping
+defineshade cshade withshademethod "circular" ;
+\stoptyping
+
+% withshadefactor 1
+% withshadedomain (0,1)
+% withshadecolors (black,white)
+% withtransparency (1,.5)
+
+% \startMPcode
+% fill fullcircle scaled 3cm
+% shaded myshade
+% withshadefactor 0.7
+% ;
+% \stopMPcode
+
+% \startMPcode
+% fill fullcircle scaled 3cm
+% shaded myshade
+% withshadecolors (red,green)
+% withshadefactor 1
+% withtransparency (1,.75)
+% ;
+% \stopMPcode
+
+% \startMPcode
+% fill fullcircle scaled 3cm
+% shaded myshade ;
+% withshadefactor 1
+% withshadedomain (0,1)
+% withshadecolors (green,blue)
+% withtransparency (1,.5)
+% ;
+% \stopMPcode
+
+% \startMPcode
+% fill fullcircle scaled 3cm
+% shaded myshade ;
+% withshadefactor 1
+% withshadedomain (0,1)
+% withcolor blue shadedinto yellow
+% withtransparency (1,.5)
+% ;
+% \stopMPcode
+
+\ShowSampleV {mp}
+ {basiccolors}
+ {for i=0 upto 21 : fill ... withcolor basiccolors[i] ; endfor}
+ {for i=0 upto 21 : fill fullcircle shifted (i,0) withcolor basiccolors[i] ; endfor}
+
+\stopsection
+
+\startsection[title={Attributes}]
+
+\index{attributes}
+
+\ShowSampleII {mp} {dashed withdots} {dashed withdots}
+\ShowSampleII {mp} {dashed evenly} {dashed evenly}
+\ShowSampleII {mp} {dashed oddly} {dashed oddly}
+\ShowSampleII {mp} {dashpattern} {dashed dashpattern (on .1 off .2 on .3 off .4)}
+\ShowSampleII {mp} {undashed} {dashed evenly undashed}
+
+\ShowSampleJ {mm} {pencircle transform} {pencircle}
+\ShowSampleJ {mm} {pensquare transform} {pensquare}
+\ShowSampleJ {mm} {penrazor transform} {penrazor}
+\ShowSampleK {mm} {penspeck transform} {penspeck}
+
+\ShowSampleL {mm} {draw} {fullcircle}
+\ShowSampleL {mm} {fill} {fullcircle}
+\ShowSampleL {mm} {filldraw} {fullcircle}
+\ShowSampleL {mm} {drawfill} {fullcircle}
+\ShowSampleL {mm} {drawdot} {origin}
+\ShowSampleL {mm} {drawarrow} {fullcircle}
+\ShowSampleL {mm} {drawdblarrow} {fullcircle}
+
+\ShowSampleL {fm} {eofill} {fullcircle}
+
+\ShowSampleM {mm} {undraw} {fullcircle}
+\ShowSampleM {mm} {unfill} {fullcircle}
+\ShowSampleM {mm} {unfilldraw} {fullcircle}
+\ShowSampleM {mm} {undrawfill} {fullcircle}
+\ShowSampleM {mm} {undrawdot} {origin}
+
+\ShowSampleQ {mm} {cutdraw} {origin--(1,1)}
+
+\ShowSampleN {mv} {butt} {linecap := butt} {(0,.5)--(.5,0)--(1,1)}
+\ShowSampleN {mv} {rounded} {linecap := rounded} {(0,.5)--(.5,0)--(1,1)}
+\ShowSampleN {mv} {squared} {linecap := squared} {(0,.5)--(.5,0)--(1,1)}
+
+\ShowSampleN {mv} {mitered} {linejoin := mitered} {(0,.5)--(.5,0)--(1,1)}
+\ShowSampleN {mv} {rounded} {linejoin := rounded} {(0,.5)--(.5,0)--(1,1)}
+\ShowSampleN {mv} {beveled} {linejoin := beveled} {(0,.5)--(.5,0)--(1,1)}
+
+\ShowSampleR {fm} {inverted picture} {inverted currentpicture}
+\ShowSampleR {fm} {picture uncolored color} {currentpicture uncolored green}
+\ShowSampleR {fm} {picture softened numeric} {currentpicture softened .8}
+\ShowSampleR {fm} {picture softened color} {currentpicture softened (.7,.8,.9)}
+\ShowSampleR {fm} {grayed picture} {grayed currentpicture}
+
+\stopsection
+
+\startsection[title={Text}]
+
+\index{text}
+
+\ShowSampleO {mm} {label} {label("MetaFun",origin)}
+\ShowSampleO {mm} {label.top} {label.top("MetaFun",origin)}
+\ShowSampleO {mm} {label.bot} {label.bot("MetaFun",origin)}
+\ShowSampleO {mm} {label.lft} {label.lft("MetaFun",origin)}
+\ShowSampleO {mm} {label.rt} {label.rt("MetaFun",origin)}
+\ShowSampleO {mm} {label.llft} {label.llft("MetaFun",origin)}
+\ShowSampleO {mm} {label.lrt} {label.lrt("MetaFun",origin)}
+\ShowSampleO {mm} {label.urt} {label.urt("MetaFun",origin)}
+\ShowSampleO {mm} {label.ulft} {label.ulft("MetaFun",origin)}
+
+\ShowSampleW {mp} {dotlabel}
+ {dotlabel.bot("\tttf metafun",(2cm,1cm))}
+ {dotlabel.bot("\tttf metafun",(2cm,1cm))}
+
+\ShowSampleW {mp} {dotlabels + range .. thru ..}
+ {z1 = ... ; dotlabels.bot(range 1 thru 3)}
+ {z1=(0,0); z2=(10mm,10mm); z3=(20mm,15mm); ; z4=(30mm,5mm); dotlabels.bot(range 1 thru 4)}
+
+\ShowSampleW {mp} {labels + range .. thru ..}
+ {z1 = ... ; labels.bot(range 1 thru 3)}
+ {z1=(0,0); z2=(10mm,10mm); z3=(20mm,15mm); ; z4=(30mm,5mm); labels.bot(range 1 thru 4)}
+
+\ShowSampleQQ {fm}
+ {thelabel(string,pair)}
+ {draw thelabel("MetaFun",(2cm,0))}
+
+\ShowSampleQQ {fm}
+ {formatted(string)}
+ {draw textext(formatted("@0.5f",1.234))}
+
+\ShowSampleQQ {fm}
+ {format(string) : graph package}
+ {draw textext(format("@5E-2",1.234))}
+
+\ShowSampleP {mp}
+ {btex text etex}
+ {draw btex MetaTeX etex}
+
+\ShowSampleQQ {fm}
+ {textext(string)}
+ {draw textext("MetaFun")}
+
+\ShowSampleQQ {fm}
+ {thetextext(string,pair)}
+ {draw thetextext("MetaFun",(2cm,0))}
+
+% \ShowSampleQQ {fm}
+% {graphictext string ...}
+% {graphictext "MetaFun"}
+
+\ShowSampleQQQ {fm}
+ {outlinetext.d("string")(d)}
+ {draw outlinetext.d("MetaFun")(InRed)}
+
+\ShowSampleQQQ {fm}
+ {outlinetext.f("string")(f)}
+ {draw outlinetext.f("MetaFun")(InYellow)}
+
+\ShowSampleQQQ {fm}
+ {outlinetext.b("string")(f)(d)}
+ {draw outlinetext.b("MetaFun")(InYellow)(InRed)}
+
+\ShowSampleQQQ {fm}
+ {outlinetext.r("string")(d)(f)}
+ {draw outlinetext.r("MetaFun")(InRed)(InYellow)}
+
+\ShowSampleUU {fm}
+ {outlinetext.p("string")}
+ {draw outlinetext.p("MetaFun")}
+
+\stopsection
+
+\startsection[title={Control}]
+
+\index{loops}
+
+\ShowSampleU {mp} {for (positive step) until} {for i=0 step 2 until 8: drawdot (i,0) ; endfor}
+\ShowSampleU {mp} {for (negative step) until} {for i=6 step -2 until 0: drawdot (i,0) ; endfor}
+\ShowSampleU {mm} {for upto} {for i=0 upto 12: drawdot (i,0) ; endfor}
+\ShowSampleU {mm} {for downto} {for i=10 downto 0: drawdot (i,0) ; endfor}
+\ShowSampleU {mm} {forsuffixes} {forsuffixes i=1,4,6,12: drawdot (i,0) ; endfor}
+
+\stopsection
+
+\startsection[title={Graphics}]
+
+\index{graphics}
+
+\ShowSampleS {fm}
+ {loadfigure string number numeric ...}
+ {loadfigure "mycow.mp" number 1 scaled .25}
+
+\ShowSampleS {fm}
+ {externalfigure string ...}
+ {draw externalfigure "mycow.pdf" scaled 3cm}
+
+\ShowSampleT {fm} {addbackground text}
+ {addbackground withcolor .625 yellow}
+ {fill fullcircle xyscaled (2,1) InRed; addbackground InYellow}
+
+\ShowSampleQQ {mm} {image (text)}
+ {draw image(draw fullcircle) xscaled 4cm yscaled 1cm}
+
+\ShowSampleT {mm} {decorated (text) text}
+ {draw decorated (....) withcolor red}
+ {draw decorated (fill fullcircle) InRed}
+
+\ShowSampleT {mm} {undecorated (text) text}
+ {draw undecorated (.... withcolor yellow) withcolor red}
+ {draw undecorated (fill fullcircle InYellow) InRed}
+
+\ShowSampleT {mm} {redecorated (text) text}
+ {draw redecorated (.... withcolor yellow) withcolor red}
+ {draw redecorated (fill fullcircle InYellow) InRed}
+
+\ShowSampleS {mm}
+ {bitmapimage (w,h,data)}
+ {draw bitmapimage (2,2,"114477AA") rotated 15 scaled 4cm}
+
+\ShowSampleT {mm}
+ {withmask string}
+ {draw externalfigure "m-1.png" scaled 2cm withmask "m-2.png"}
+ {Scale := 1 ;
+ draw externalfigure "m-2.png" scaled 2cm shifted (-3cm,0) ;
+ draw externalfigure "m-1.png" scaled 2cm shifted (-6cm,0) ;
+ draw externalfigure "m-1.png" scaled 2cm withmask "m-2.png"}
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
+
+%% draw leftpath fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625red ;
+%% draw reverse leftpath (reverse fullcircle scaled 2cm) withpen pencircle scaled 1mm withcolor .625yellow ;
+%% draw rightpath fullcircle scaled 3cm withpen pencircle scaled 1mm withcolor .625white ;
+%%
+%% path p ; p := (0,0) .. (1,2) .. cycle ;
+%% draw leftpath p scaled 1cm withpen pencircle scaled 1mm withcolor .625red ;
+%% draw reverse leftpath (reverse p scaled 2cm) withpen pencircle scaled 1mm withcolor .625yellow ;
+%% draw rightpath p scaled 3cm withpen pencircle scaled 1mm withcolor .625white ;
diff --git a/doc/context/sources/general/manuals/metafun/metafun-sneaky.tex b/doc/context/sources/general/manuals/metafun/metafun-sneaky.tex
new file mode 100644
index 000000000..02c502cf0
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-sneaky.tex
@@ -0,0 +1,60 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-conventions
+
+\environment metafun-environment
+
+\startchapter[title={Conventions}]
+
+\startsection[title={Suffixes}]
+
+One characteristic of using \METAFUN\ in \CONTEXT\ is that it is basically one
+long run. The code snippets become figures that then get converted to \PDF\ and
+embedded. If text is involved, each figure is actually processed twice, once to
+identify what needs to be typeset, and once with the result(ing metrics).
+Normally that gets unnoticed. You can check for the state by consulting the
+boolean \type {mfun_trial_run}.
+
+A consequence of the one run cq.\ multiple runs is that you need to be careful with
+undefined or special variables. Consider the following:
+
+\starttyping
+vardef foo@#(text t) =
+ save s ; string s ; s := str @# ;
+ if length(s) > 0 :
+ textext(s)
+ else :
+ nullpicture
+ fi
+enddef ;
+\stoptyping
+
+The following works ok in the first run when bar is undefined:
+
+\starttyping
+draw foo.bar("a") ;
+\stoptyping
+
+But if afterwards we say:
+
+\starttyping
+vardef bar(expr x) =
+ 123
+enddef ;
+\stoptyping
+
+and expand \type {foo.bar} again we will get an error message because this time
+\type {bar} expands. Suffixes are always expanded!
+
+The lesson is: when you get unexpected results or errors, check your variable
+definitions. You can use the \type {begingroup} and \type {endgroup} primitives
+to protect your variables but then you also need to explicitly use \type {save}
+to store their meanings and allocate new ones after that inside the group.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-styles.tex b/doc/context/sources/general/manuals/metafun/metafun-styles.tex
new file mode 100644
index 000000000..f82359117
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-styles.tex
@@ -0,0 +1,445 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-styles
+
+\environment metafun-environment
+
+\startchapter[title={Defining styles}]
+
+\index {layout}
+\index {styles}
+
+\startintro
+
+Since the integration of \METAPOST\ into \CONTEXT, a complete new range of layout
+fetaures became available. In this document we have introduced several ways to
+include graphics in your document definition. In this chapter we go one step
+further and make dynamic graphics part of a document style.
+
+\stopintro
+
+\startsection[title={Adaptive buttons}]
+
+So far we have seen a lot of graphic ingredients that you can use to make your
+documents more attractive. In this chapter we will define a simple document
+style. This style was written for the \PDFTEX\ presentations at the TUG 2000
+conference in Oxford (UK).
+
+This style exploits a few tricks, like graphics calculated using positional
+information. It also demonstrates how you can make menu buttons that dynamically
+adapt their shapes to the rest of the page layout.
+
+\startbuffer[screens]
+\startlinecorrection[blank]
+\setupcombinations[distance=.0125\textwidth]
+\startcombination[5*1]
+ {\typesetfile[mfun-77\ScrNum.tex][page=1,width=.19\textwidth]} {page 1}
+ {\typesetfile[mfun-77\ScrNum.tex][page=2,width=.19\textwidth]} {page 2}
+ {\typesetfile[mfun-77\ScrNum.tex][page=3,width=.19\textwidth]} {page 3}
+ {\typesetfile[mfun-77\ScrNum.tex][page=4,width=.19\textwidth]} {page 4}
+ {\typesetfile[mfun-77\ScrNum.tex][page=5,width=.19\textwidth]} {page 5}
+\stopcombination
+\stoplinecorrection
+\stopbuffer
+
+\def\ScrNum{1} \getbuffer[screens]
+
+Later we will see an instance with some more randomness in the graphics. While
+writing this style, the random alternative made me think of those organic
+buildings with non equal windows |<|we have a few of those in The Netherlands|>|,
+so I decided to label this style as \type {pre-organic}. If you use \CONTEXT, you
+can load this style with:
+
+\starttyping
+\usemodule[pre-organic]
+\stoptyping
+
+At the end of this file, there is a small test file, so when you process the file
+\type {s-pre-19.tex} \footnote {This style is the 19\high{th} presentation style.
+Those numbered styles are internally mapped onto more meaningful names like in
+this case \type {pre-organic}.} with the options \type {--mode=demo} and \type
+{--pdf}, you will get a demo document.
+
+We use one of the standard screen \quote {paper} sizes, and map it onto the same
+size, so that we get a nicely cropped page. Other screen sizes are \type {S4} and
+\type {S5}.
+
+\starttyping
+\setuppapersize[S6][S6]
+\stoptyping
+
+Like in this \METAFUN\ manual, we use the Palatino as main bodyfont. This font is
+quite readable on even low resolution screens, although I admit that this style
+is developed using an $1400\times1050$ pixel \kap {lcd} screen, so the author may
+be a little biased.
+
+\starttyping
+\setupbodyfont[ppl]
+\stoptyping
+
+The layout specification sets up a text area and a right edge area where the
+menus will go (see \in {chapter} [sec:page] for a more in depth discussion on the
+layout areas). Watch how we use a rather large edge distance. By setting the
+header and footer dimensions to zero, we automatically get rid of page body
+ornaments, like the page number.
+
+\starttyping
+\setuplayout
+ [topspace=48pt,
+ backspace=48pt,
+ cutspace=12pt,
+ width=400pt,
+ margin=0cm,
+ rightedge=88pt,
+ rightedgedistance=48pt,
+ header=0cm,
+ footer=0cm,
+ height=middle]
+\stoptyping
+
+We use a moderate, about a line height, inter||paragraph white space.
+
+\starttyping
+\setupwhitespace[big]
+\stoptyping
+
+Of course we use colors, since on computer displays they come for free.
+
+\starttyping
+\setupcolors[state=start]
+
+\definecolor [red] [r=.75]
+\definecolor [yellow] [r=.75,g=.75]
+\definecolor [gray] [s=.50]
+\definecolor [white] [s=.85]
+\stoptyping
+
+Because it is an interactive document, we have to enable hyperlinks and alike.
+However, in this style, we disable the viewer's \quote {highlight a hyperlink
+when it's clicked on} feature. We will use a menu, so we enable menus. Later we
+will see the contrast color |<|hyperlinks gets that color when we are already on
+the location|>| in action.
+
+\starttyping
+\setupinteraction
+ [state=start,
+ click=off,
+ color=red,
+ contrastcolor=gray,
+ menu=on]
+\stoptyping
+
+The menu itself is set up as follows. Because we will calculate menu buttons
+based on their position on the page, we have to keep track of the positions.
+Therefore, we set the \type {position} variable to \type {yes}.
+
+\starttyping
+\setupinteractionmenu
+ [right]
+ [frame=off,
+ position=yes,
+ align=middle,
+ topoffset=-.75cm,
+ bottomoffset=-.75cm,
+ color=gray,
+ contrastcolor=gray,
+ style=bold,
+ before=,
+ after=]
+\stoptyping
+
+The menu content is rather sober: just a list of topics and a close button. Later
+we will define the command that generates topic entries. The alternative \type
+{right} lets the topic list inherit its characteristics from the menu.
+
+\starttyping
+\startinteractionmenu[right]
+ \placelist[Topic][alternative=right]
+ \vfill
+ \but [CloseDocument] close \\
+\stopinteractionmenu
+\stoptyping
+
+We have now arrived at the more interesting part of the style definition: the
+graphic that goes in the page background. Because this graphic will change, we
+define a useable \METAPOST\ graphic. Page backgrounds are recalculated each page,
+opposite to the other backgrounds that are calculated when a new background is
+defined, or when repetitive calculation is turned on.
+
+\starttyping
+\setupbackgrounds [page] [background=page]
+\defineoverlay [page] [\useMPgraphic{page}]
+\setupMPvariables [page] [alternative=3]
+\stoptyping
+
+We will implement three alternative backgrounds. First we demonstrate the
+relatively simple super ellipsed one. The main complication is that we want the
+button shapes to follow the right edge of the curve that surrounds the text. We
+don't know in advance how many lines of text there will be in a button, and we
+also don't know at what height it will end up. Therefore, we need to calculate
+each button shape independently and for that purpose we need to know its position
+(see \in {chapter} [sec:positioning]). In \in {figure} [fig:style] you can see
+what lines we need in order to be calculate the button shapes.
+
+\startpostponing
+
+\startmode[screen]
+ \placefigure
+ [here][fig:style]
+ {The lines used to calculate the button shapes.}
+ {\externalfigure[mfun-774.pdf][page=1,height=.85\textheight]}
+\stopmode
+
+\startnotmode[screen]
+ \placefigure
+ [here][fig:style]
+ {The auxiliary lines used to calculate the button shapes.}
+ {\rotate{\externalfigure[mfun-774.pdf][page=1,height=\textwidth]}}
+\stopnotmode
+
+\page
+
+\stoppostponing
+
+We separate the calculation of the button shape from the rest by embedding it in
+its own usable graphic container. The \type {StartPage}||\type {StopPage} pair
+takes care of proper placement of the whole graphic.
+
+\starttyping
+\startuseMPgraphic{page}
+
+ \includeMPgraphic{rightsuperbutton}
+
+ StartPage ;
+
+ path p, q ; pickup pencircle scaled 3pt ;
+
+ p := Field[Text][Text] enlarged 36pt superellipsed .90 ;
+
+ fill Page withcolor \MPcolor{yellow} ;
+ fill p withcolor \MPcolor{white} ;
+ draw p withcolor \MPcolor{red} ;
+
+ p := Field[Text][Text] enlarged 48pt superellipsed .90 ;
+
+ def right_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) =
+ if (pp>0) and (rr>0) :
+ q := rightsuperbutton(p,xx,yy,RightEdgeWidth,hh) ;
+ fill q withcolor \MPcolor{white} ;
+ draw q withcolor if rr=2 : \MPcolor{gray}
+ else : \MPcolor{red} fi ;
+ fi ;
+ enddef ;
+
+ \MPmenubuttons{right}
+
+ StopPage ;
+\stopuseMPgraphic
+\stoptyping
+
+The \TEX\ macro \type {\MPmenubuttons} expands into a list of (in this case four)
+calls to the \METAPOST\ macro \type {right_menu_button}. This list is generated
+by \CONTEXT\ when it generates the menu. Because the page background is applied
+last, this list is available at that moment.
+
+\starttyping
+... (expr nn, rr, pp, xx, yy, ww, hh, dd) ...
+\stoptyping
+
+This rather long list of arguments represents the following variables: number,
+referred page, current page, x coordinate, y coordinate, width, height and depth.
+The last six variables originate from the positioning mechanism. Because the
+variables are only available after a second \TEX\ pass, we only draw a button
+shape when the test for the page numbers succeeds.
+
+\starttyping
+\startuseMPgraphic{rightsuperbutton}
+ vardef rightsuperbutton (expr pat, xpos, ypos, wid, hei) =
+
+ save p, ptop, pbot, t, b, edge, shift, width, height ;
+ path p, ptop, pbot ; pair t, b ;
+ numeric edge, shift, width, height ;
+
+ edge := xpos + wid ; shift := ypos + hei ;
+
+ p := rightpath pat ;
+
+ ptop := ((-infinity,shift)--(edge,shift)) ;
+ pbot := ((-infinity,shift-hei)--(edge,shift-hei)) ;
+
+ t := p intersectionpoint ptop ;
+ b := p intersectionpoint pbot ;
+
+ p := subpath(0,xpart (p intersectiontimes ptop)) of p ;
+ p := subpath(xpart (p intersectiontimes pbot),length(p)) of p ;
+
+ (p -- t -- point 1 of ptop &
+ point 1 of ptop -- point 1 of pbot &
+ point 1 of pbot -- b
+ -- cycle)
+
+ enddef ;
+\stopuseMPgraphic
+\stoptyping
+
+The calculation of the button itself comes down to combining segments of the main
+shape and auxiliary lines. The \type {rightpath} macro returns the right half of
+the path provided. This half is shown as a non dashed line.
+
+Topics are identified with \type {\Topic}, which is an instance of chapter
+headings. The number is made invisible. Since it still is a numbered section
+header, \CONTEXT\ will write the header to the table of contents.
+
+\starttyping
+\definehead [Topic] [chapter]
+\setuphead [Topic] [number=no]
+\stoptyping
+
+We will use a bold font in the table of contents. We also force a complete list.
+
+\starttyping
+\setuplist
+ [Topic]
+ [criterium=all,
+ style=bold,
+ before=,
+ after=]
+\stoptyping
+
+The \type {\TitlePage} macro looks horrible, because we want to keep the
+interface simple: a list of small sentences, separated by \type {\\}.
+
+\starttyping
+\def\TitlePage#1%
+ {\startstandardmakeup
+ \switchtobodyfont[big]
+ \def\\{\vfill\bfb\let\\=\par}
+ \bfd\setupinterlinespace\gray
+ \vskip.5cm#1\\\vskip.5cm % \\ is really needed -)
+ \stopstandardmakeup}
+\stoptyping
+
+A presentation that uses this style, may look like the one below. You can choose
+among three alternatives.
+
+\starttyping
+\useenvironment[pre-organic] \setupoutput[pdftex]
+
+\setupMPvariables[page][alternative=1]
+
+\starttext
+
+\TitlePage
+ {A Few Nice Quotes\\
+ A Simple Style Demo\\
+ Hans Hagen, August 2000}
+
+\Topic {Douglas R. Hofstadter} \input douglas \page
+\Topic {Donald E. Knuth} \input knuth \page
+\Topic {Edward R. Tufte} \input tufte \page
+\Topic {Hermann Zapf} \input zapf \page
+
+\stoptext
+\stoptyping
+
+We will not implement the two other alternative shapes: squeezed and randomized.
+
+\def\ScrNum{2} \getbuffer[screens]
+\def\ScrNum{3} \getbuffer[screens]
+
+We combine all alternatives into one page graphic. The alternative is chosen by
+setting the \type {alternative} variable, as we demonstrated in the example.
+
+\starttyping
+\startuseMPgraphic{page}
+
+ \includeMPgraphic{rightsuperbutton}
+
+ StartPage ;
+
+ numeric alternative, seed, superness, squeezeness, randomness ;
+ path p, q ; transform t ;
+\stoptyping
+
+This is one of those cases where a transform variable is useful. We need to store
+the random seed value because we want the larger path that is used in the
+calculations to have the same shape.
+
+\starttyping
+ alternative := \MPvar{alternative} ;
+ seed := uniformdeviate 100 ;
+
+ if alternative > 10 :
+ superness := .85 + ((\realfolio-1)/max(\lastpage,1)) * .25 ;
+ squeezeness := 12pt - ((\realfolio-1)/max(\lastpage,1)) * 10pt ;
+ else :
+ superness := .90 ;
+ squeezeness := 12pt ;
+ fi ;
+
+ randomness := squeezeness ;
+
+ alternative := alternative mod 10 ;
+\stoptyping
+
+If you read closely, you will notice that when we add 10 to the alternative, we
+get a page dependant graphic. So, in fact we have five alternatives. We use
+\CONTEXT\ macros to fetch the (real) page number and the number of the last page.
+In further calculations we use the lower alternative numbers, which is why we
+apply a \type {mod}.
+
+The rest of the code is not so much different from the previous definition. The
+hard coded point sizes match the page dimensions (600pt by 450pt) quite well.
+
+\starttyping
+ t := identity if alternative=3: shifted (9pt,-9pt) fi ;
+
+ randomseed := seed ;
+
+ p := Field[Text][Text] enlarged if
+ alternative = 1 : 36pt superellipsed superness elseif
+ alternative = 2 : 36pt squeezed squeezeness elseif
+ alternative = 3 : 36pt randomized randomness else
+ : 36pt fi ;
+
+ pickup pencircle scaled 3pt ;
+
+ fill Page withcolor \MPcolor{yellow} ;
+ fill p withcolor \MPcolor{white} ;
+ draw p withcolor \MPcolor{red} ;
+
+ randomseed := seed ;
+
+ p := ( Field[Text][Text] enlarged if
+ alternative = 1 : 48pt superellipsed superness elseif
+ alternative = 2 : 48pt squeezed squeezeness elseif
+ alternative = 3 : 36pt randomized randomness else
+ : 48pt fi ) transformed t ;
+
+ def right_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) =
+ if (pp>0) and (rr>0) :
+ q := rightsuperbutton(p,xx,yy,RightEdgeWidth,hh) ;
+ fill q withcolor \MPcolor{white} ;
+ draw q withcolor if rr=2 : \MPcolor{gray}
+ else : \MPcolor{red} fi ;
+ fi ;
+ enddef ;
+
+ \MPmenubuttons{right}
+
+ StopPage ;
+\stopuseMPgraphic
+\stoptyping
+
+When we choose the alternatives~21 and~22 we get this result:
+
+\def\ScrNum{5} \getbuffer[screens]
+\def\ScrNum{6} \getbuffer[screens]
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-syntax.tex b/doc/context/sources/general/manuals/metafun/metafun-syntax.tex
new file mode 100644
index 000000000..9407b1dd0
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-syntax.tex
@@ -0,0 +1,1130 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+% eoclip: no postscript possible yet
+%
+% mpprocset mpxbreak
+
+% path expression -> path
+
+% listsize
+% copylist
+% sortlist
+% shapedlist
+% listtocurves
+% listtolines
+
+\startcomponent metafun-syntax
+
+\environment metafun-environment
+
+\startchapter[title={\METAPOST\ syntax}]
+
+\index{syntax}
+\index{language}
+
+\startintro
+
+In the \METAFONT\ book as well as the \METAPOST\ manual, you can find the exact
+specification of the language. Below you find the full \METAPOST\ syntax, to
+which we add the basic \METAFUN\ extensions. If this page looks too cryptic, you
+can safely skip to the next chapter. We don't distinguish between primitives and
+functionality defined in the \METAPOST\ format, simply because the core is kept
+small and a macro package is supposed to extend that core.
+
+\stopintro
+
+% \startsection[title={Syntax diagrams}]
+
+The following syntax diagrams are derived from the diagrams in the \METAPOST\
+manual. The \mathematics {\rightarrow} represents \quote {means} and the
+\mathematics {\vert} symbol stands for \quote {or}.
+
+The diagrams describe the hard coded \METAPOST\ syntax as well as most of the
+macros and variables defined in the plain \METAPOST\ format that belongs to the
+core of the system. They also include most of the fundamental \METAFUN\ commands.
+We have omitted the \METAPOST\ and \METAFONT\ commands that make no sense any
+more or are irrelevant for common usage. Specific \METAFUN\ modules are not
+included here, only general tools, text helpers and extensions to the built||in
+capabilities like transparency. If you feel that something is missing that should
+be specified here, just let me know.
+
+\start \switchtobodyfont[8pt] % small]
+
+\StartSyntax
+\S{atom}
+ \M \S{variable} \S{argument}
+ \O \S{number or fraction}
+ \O \S{internal variable}
+ \O \( \S{expression} \)
+ \O \L{begingroup} \S{statement list} \S{expression} \L{endgroup}
+ \O \S{nullary op}
+ \O \L{btex} \S{typesetting command} \L{etex}
+ % \O \L{verbatimtex} \S{typesetting command} \L{etex}
+ \O \S{pseudo function}
+\StopSyntax
+
+\StartSyntax
+\S{primary}
+ \M \S{atom}
+ \O \( \S{numeric expression} \L{,} \S{numeric expression} \)
+ \O \( \S{numeric expression} \L{,} \S{numeric expression} \L{,} \S{numeric expression} \)
+ \O \( \S{numeric expression} \L{,} \S{numeric expression} \L{,} \S{numeric expression} \L{,} \S{numeric expression} \)
+ \O \S{of operator} \S{expression} \L{of} \S{primary}
+ \O \S{numeric expression} \S{expression} \FL{along} \S{path expression}
+ \O \S{numeric expression} \S{expression} \FL{on} \S{path expression}
+ \O \S{unary op} \S{primary}
+ \O \L{str} \S{suffix}
+ \O \L{z} \S{suffix}
+ \O \S{numeric atom} \[ \S{expression} \L{,} \S{expression} \]
+ \O \S{scalar multiplication op} \S{primary}
+ \O \S{color expression} \FL{shadedinto} \S{color expression}
+ \O \S{picture expression} \FL{asgroup} \S{string expression}
+ \O \S{picture expression} \FL{onlayer} \S{string expression}
+\StopSyntax
+
+\StartSyntax
+\S{secondary}
+ \M \S{primary}
+ \O \S{secondary} \S{primary binop} \S{primary}
+ \O \S{secondary} \S{transformer}
+\StopSyntax
+
+\StartSyntax
+\S{tertiary}
+ \M \S{secondary}
+ \O \S{tertiary} \S{secondary binop} \S{secondary}
+\StopSyntax
+
+\StartSyntax
+\S{subexpression}
+ \M \S{tertiary}
+ \O \S{path expression} \S{path join} \S{path knot}
+\StopSyntax
+
+\StartSyntax
+\S{expression}
+ \M \S{subexpression}
+ \O \S{expression} \S{tertiary binop} \S{tertiary}
+ \O \S{path subexpression} \S{direction specifier}
+ \O \S{path subexpression} \S{path join} \L{cycle}
+\StopSyntax
+
+\StartSyntax
+\S{path knot}
+ \M \S{tertiary}
+\StopSyntax
+
+\StartSyntax
+\S{path join}
+ \M \L{--}
+ \O \S{direction specifier} \S{basic path join} \S{direction specifier}
+\StopSyntax
+
+\StartSyntax
+\S {direction specifier}
+ \M \S{empty}
+ \O \{ \L{curl} \S{numeric expression} \}
+ \O \{ \S{pair expression} \}
+ \O \{ \S{numeric expression} \L{,} \S{numeric expression} \}
+\StopSyntax
+
+\StartSyntax
+\S{basic path join}
+ \M \L{..}
+ \O \L{...}
+ \O \L{..} \S{tension} \L{..}
+ %O \L{..} \S{tension} \L{..} % check what got lost here
+ \O \L{..} \S{controls} \L{..}
+\StopSyntax
+
+\StartSyntax % atleast added
+\S{tension}
+ \M \L{tension} \S{numeric primary}
+ \O \L{tension} \L{atleast} \S{numeric primary}
+ \O \L{tension} \S{numeric primary} \L{and} \S{numeric primary}
+\StopSyntax
+
+\StartSyntax
+\S{controls}
+ \M controls \S{pair primary}
+ \O controls \S{pair primary} \L{and} \S{pair primary}
+\StopSyntax
+
+\StartSyntax
+\S{argument}
+ \M \S{symbolic token}
+\StopSyntax
+
+\StartSyntax
+\S{number or fraction}
+ \M \S{number} \L{/} \S{number}
+ \O \S{number} \Q{not followed by} \L{/} \S{number}
+\StopSyntax
+
+\StartSyntax
+\S{scalar multiplication op}
+ \M \L{+} \O \L{-}
+ \O \S{number or fraction} \Q{not followed by} \S{add op} \S{number}
+\StopSyntax
+
+\StartSyntax
+\S{transformer}
+ \M \L {rotated} \S {numeric primary}
+ \O \L {scaled} \S {numeric primary}
+ \O \L {shifted} \S {pair primary}
+ \O \L {slanted} \S {numeric primary}
+ \O \L {transformed} \S {transform primary}
+ \O \L {xscaled} \S {numeric primary} \O \L {yscaled} \S {numeric primary} \O \FL{xyscaled} \S {numeric or pair primary}
+ \O \L {zscaled} \S {pair primary}
+ \O \L {reflectedabout} \L \( \S{pair expression} \L{,} \S{pair expression} \)
+ \O \L {rotatedaround} \L \( \S{pair expression} \L{,} \S{numeric expression} \)
+ \O \FL{xsized} \S {numeric primary} \O \FL{ysized} \S {numeric primary} \O \FL{xysized} \S {numeric or pair primary}
+ \O \FL{blownup} \S {numeric or pair primary}
+ \O \FL{enlarged} \S {numeric or pair primary}
+ \O \FL{xstretched} \S {numeric primary} \O \FL{ystretched} \S{numeric primary} \O \FL{stretched} \S{numeric or pair primary}
+ \O \FL{shortened} \S {numeric or pair primary}
+ \O \FL{enlonged} \S {numeric or pair primary}
+ \O \FL{crossed} \S {numeric primary}
+ \O \FL{paralelled} \S {numeric primary}
+ \O \FL{curved} \S {numeric primary}
+ \O \FL{laddered}
+ \O \FL{leftenlarged} \S{numeric primary} \O \FL{llenlarged} \S{numeric primary} \O \FL{llmoved} \S{numeric primary}
+ \O \FL{rightenlarged} \S{numeric primary} \O \FL{lrenlarged} \S{numeric primary} \O \FL{lrmoved} \S{numeric primary}
+ \O \FL{topenlarged} \S{numeric primary} \O \FL{urenlarged} \S{numeric primary} \O \FL{urmoved} \S{numeric primary}
+ \O \FL{bottomenlarged} \S{numeric primary} \O \FL{ulenlarged} \S{numeric primary} \O \FL{ulmoved} \S{numeric primary}
+ \O \FL{randomized} \S{numeric or pair or color primary}
+ \O \FL{randomizedcontrols} \S{numeric or pair}
+ \O \FL{snapped} \S{numeric or pair primary}
+ \O \FL{cornered} \S{numeric or pair}
+ \O \FL{peepholed} \S{path expression}
+ \O \FL{smoothed} \S{numeric or pair}
+ \O \FL{squeezed} \S{numeric or pair primary}
+ \O \FL{superellipsed} \S{numeric primary}
+ \O \FL{randomshifted} \S{numeric or pair primary}
+ \O \FL{uncolored} \S{color primary}
+ \O \FL{softened} \S{numeric or color primary}
+ \O \FL{asgroup} \S{string primary}
+ \O \L {gobbled} \S{primary}
+ %
+ \O \FL {insideof} \S{path expression}
+ \O \FL {outsideof} \S{path expression}
+ \O \FL {crossinunder} \S{path expression}
+\StopSyntax
+
+\StartSyntax
+\S{numeric or pair primary}
+ \M \S{numeric primary}
+ \O \S{pair primary}
+\StopSyntax
+
+\StartSyntax
+\S{numeric or pair or color primary}
+ \M \S{numeric primary}
+ \O \S{pair primary}
+ \O \S{color primary}
+\StopSyntax
+
+\StartSyntax
+\S{numeric or color primary}
+ \M \S{numeric primary}
+ \O \S{color primary}
+\StopSyntax
+
+\StartSyntax
+\S{nullary op}
+ \M \L{false} \O \L{true}
+ \O \L{normaldeviate}
+ \O \L{nullpen} \O \L{nullpicture} \O \L{pencircle}%
+ \O \L{whatever}
+\StopSyntax
+
+\StartSyntax
+\S{unary op}
+ \M \S{type}
+ \O \L {ASCII}
+ \O \FL{asin} \O \FL{asinh} \O \FL{acos} \O \FL{acosh} \O \FL{atan} \O \L {cosd} \O \FL{cos} \O \FL{cosh} \O \FL{cot} \O \FL{cotd} \O \L {sind} \O \FL{sin} \O \FL{sinh} \O \FL{tand} \O \FL{tan}
+ \O \L {inverse} \O \FL{inv} \O \FL{invcos} \O \FL{invsin} \O \FL{invtan}
+ \O \FL{sqr} \O \L {sqrt} \O \L {pow} \O \FL{exp} \O \L {mexp} \O \L {mlog} \O \FL{ln} \O \FL{log} \O \L {uniformdeviate}
+ \O \L {abs} \O \L {round} \O \L {odd} \O \L {ceiling} \O \L {floor}
+ \O \L {dir} \O \L {angle} \O \L {length} \O \L {arclength}
+ \O \L {bbox} \O \FL{bbwidth} \O \FL{bbheight}
+ \O \L {bot} \O \L {lft} \O \L {rt} \O \L {top} \O \L {center}
+ \O \FL{colordecimals} \O \L {decimal} \O \FL{ddecimal} \O \FL{dddecimal} \O \FL{ddddecimal} \O \FL{condition} \O \FL{tostring}
+ \O \FL{boundingbox} \O \FL{outerboundingbox} \O \FL{innerboundingbox} \O \L {bbox}
+ \O \L {colorpart} \O {fontpart} \O \L {pathpart} \O \L {penpart} \O \L {textpart} \O \L {dashpart}
+ \O \L {redpart} \O \L {greenpart} \O \L {bluepart} \O \L {greypart} \O \L {graypart}
+ \O \L {cyanpart} \O \L {magentapart} \O \L {yellowpart} \O \L {blackpart}
+ \O \L {postscriptpart} \O \L {prescriptpart}
+ \O \L {clipped} \O \L {bounded} \O \L {stroked} \O \L {filled} \O \L {textual}
+ \O \FL{punked} \O \L{paralleled}
+ \O \FL{leftboundary} \O \FL{rightboundary} \O \FL{topboundary} \O \FL{bottomboundary}
+ \O \L {xpart} \O \L {xxpart} \O \L {xypart} \O \L {ypart} \O \L {yxpart} \O \L {yypart}
+ \O \L {oct} \O \L {hex}
+ \O \L {colortype}
+ \O \FL{grayed} \O \FL{greyed}
+ \O \L {llcorner} \O \L {lrcorner} \O \L {ulcorner} \O \L {urcorner}
+ \O \L {not} \O \L {known} \O \L {unknown}
+ \O \FL{blackcolor} \O \FL{whitecolor} \O \L {colormodel}
+ \O \L {char} \O \L {fontsize}
+ \O \L {cycle} \O \L {reverse} \O \L {counterclockwise}
+ \O \L {makepath} \O \L {makepen}
+ \O \L {unitvector}
+ \O \L {turningnumber}
+ \O \L {circularpath} \O \L {squarepath} \O \L {linearpath}
+ % maybe pseudo functions:
+ \O \FL{area} \O \FL{inverted} \O \FL{simplified} \O \FL{unspiked}
+\StopSyntax
+
+\StartSyntax
+\S{type}
+ \M \L{boolean} \O \L{numeric} \O \L{pair} \O \L{path}
+ \O \L{pen} \O \L{picture} \O \L{string} \O \L{transform}
+ \O \L{color} \O \L{cmykcolor} \O \FL {greycolor} \FL {graycolor}\O \L{rgbcolor}
+ \O \FL{property}\O \FL{transparency}
+ \O \L{outer} \O \L{inner}
+\StopSyntax
+
+\StartSyntax
+\S{primary binop}
+ \M \L{*} \O \L{/} \O \L{**} \O \L{and}
+ \O \L{dotprod} \O \L{div} \O \L{infont} \O \L{mod}
+\StopSyntax
+
+\StartSyntax
+\S{secondary binop}
+ \M \L{+} \O \L{-} \O \L{++} \O \L{+-+} \O \L{or}
+ \O \L{intersectionpoint} \O \L{intersectiontimes}
+\StopSyntax
+
+\StartSyntax
+\S{tertiary binop}
+ \M \L{&} \O \L{<} \O \L{<=} \O \L{<>} \O \L{=} \O \L{>} \O \L{>=}
+ \O \L{cutafter} \O \L{cutbefore} \O \FL{cutends}
+ \O \L{softjoin}
+\StopSyntax
+
+\StartSyntax
+\S{of operator}
+ \M \L{arctime} \O \L{direction} \O \L{directiontime} \O \L{directionpoint}%
+ \O \L{penoffset} \O \L{point}
+ \O \L{postcontrol} \O \L{precontrol} \O \L{subpath} \O \L{substring}
+ \O \L{takepower}
+\StopSyntax
+
+\StartSyntax
+\S{variable}
+ \M \S{predefined numeric variable}
+ \O \S{predefined path variable}
+ \O \S{predefined picture variable}
+ \O \S{predefined transform variable}
+ \O \S{predefined pair variable}
+ \O \S{predefined pen variable}
+ \O \S{predefined string variable}
+ \O \S{predefined dashpattern}
+ \O \S{predefined rgbcolor variable}
+ \O \S{predefined macro}
+ \O \S{tag} \S{suffix}
+\StopSyntax
+
+\StartSyntax
+\S{predefined numeric variable}
+ \M \FL{nothing yet}
+\StopSyntax
+
+\StartSyntax
+\S{predefined picture variable}
+ \M \FL{blankpicture}
+ \O \L{currentpicture}
+\StopSyntax
+
+\StartSyntax
+\S{predefined transform variable}
+ \M \L{identity} \O \L{currenttransform}
+\StopSyntax
+
+\StartSyntax
+\S{predefined path variable}
+ \M \FL{originpath}
+ \O \FL{fullcircle} \O \FL{fullsquare} \O \FL{fulldiamond} \O \FL{fulltriangle}
+ \O \FL{unitcircle} \O \FL{unitsquare} \O \FL{unitdiamond} \O \FL{unittriangle}
+ \O \FL{halfcircle} \O \FL{quartercircle}
+ \O \FL{llcircle} \O \FL{lrcircle} \O \FL{urcircle} \O \FL{ulcircle}
+ \O \FL{bcircle} \O \FL{tcircle} \O \FL{lcircle} \O \FL{rcircle}
+ \O \FL{triangle}
+ \O \FL{righttriangle} \O \FL{uptriangle} \O \FL{lefttriangle} \O \FL{downtriangle}
+ \O \FL{lltriangle} \O \FL{lrtriangle} \O \FL{urtriangle} \O \FL{ultriangle}
+ \O \L{cuttings}
+\StopSyntax
+
+\StartSyntax
+\S{predefined pair variable}
+ \M \L{right} \O \L{up} \O \L{left} \O \L{down}
+ \M \L{shadedright} \O \L{shadedup} \O \L{shadedleft} \O \L{shadeddown}
+\StopSyntax
+
+\StartSyntax
+\S{predefined pen variable}
+ \M \FL{pensquare} \O \FL{penrazor} \O \FL{penspec}
+ \O \L{currentpen}
+\StopSyntax
+
+\StartSyntax
+\S{predefined string variable}
+ \M \FL{EOF}
+ \O \FL{CRLF} \O \FL{crlf}
+ \O \FL{DQUOTE} \O \FL{dquote} \O \L{ditto}
+ \O \FL{SPACE} \O \FL{space}
+ \O \FL{PERCENT} \O \FL{percent}
+ \O \L{defaultfont}
+ \O \L{extra_beginfig} \O \L {extra_endfig}
+ \O \FL{pathconnectors}
+\StopSyntax
+
+\StartSyntax
+\S{predefined dashpattern}
+ \M \L{evenly} \O \FL{oddly} \O \L{withdots}
+\StopSyntax
+
+\StartSyntax
+\S{predefined rgbcolor variable}
+ \M \L{red} \O \L{green} \O \L{blue} \O \L{white}
+ \O \L{cyan} \O \L{magenta} \O \L{yellow} \O \L{black}
+ \O \L{background}
+ \O \FL{basiccolors}
+\StopSyntax
+
+\StartSyntax
+\S{predefined macro}
+ \M \FL{shipit} \O \FL{bye}
+ \O \FL{resetdrawoptions}
+ \O \FL{visualizepaths} \O \FL{naturalizepaths}
+\StopSyntax
+
+\StartSyntax
+\S{suffix}
+ \M \S{empty}
+ \O \S{suffix} \S{subscript}
+ \O \S{suffix} \S{tag}
+ \O \S{suffix parameter}
+\StopSyntax
+
+\StartSyntax
+\S{subscript}
+ \M \S{number}
+ \O \[ \S{numeric expression} \]
+\StopSyntax
+
+\StartSyntax
+\S{internal variable}
+ \M \L{ahangle} \O \L{ahlength}
+ \O \L{bboxmargin} \O \L{labeloffset}
+ \O \L{charcode}
+ \O \L{defaultcolormodel} \O \L{defaultpen} \O \L{defaultscale}
+ \O \L{linecap} \O \L{linejoin} \O \L{miterlimit}
+ \O \L{outputformat} \O \L{outputtemplate} \O \O \L{prologues}
+ \O \L{showstopping} \L{pausing}
+ \O \L{tracingoutput} \O \L{tracingcapsules} \O \L{tracingchoices} \O \L{tracingcommands} \O \L{tracingequations}
+ \O \L{tracinglostchars} \O \L{tracingmacros} \O \L{tracingonline} \O \L{tracingrestores} \O \L{tracingspecs}
+ \O \L{tracingstats} \O \L{tracingtitles}
+ \O \L{truecorners} \O \L{warningcheck}
+ \O \L{dotlabeldiam}
+ \O \L{day} \O \L{month} \O \L{year} \O \L{hour} \O \L{minute} \O \L{time}
+ \O \L{mm} \O \L{pt} \O \L{dd} \O \L{bp} \O \L{cm} \O \L{pc} \O \L{cc} \O \L{in}
+ \O \L{butt} \O \L{rounded} \O \L{squared} \O \L{mitered} \O \L{beveled}
+ \O \FL{pi} \O \FL{radian} \O \FL{eps} \O \FL{epsilon}
+ \O \FL{nocolormodel} \O \FL{greycolormodel} \O \FL{graycolormodel} \O \FL{rgbcolormodel} \O \FL{cmykcolormodel}
+ % \O \FL{shadefactor}
+ \O \FL{textextoffset}
+ \O \FL{maxdimensions}
+ \O \L{infinity}
+ \O \FL{charscale}
+ \O \FL{metapostversion}
+ \O \FL{normaltransparent} \O \FL{multiplytransparent} \O \FL{screentransparent} \O \FL{overlaytransparent}
+ \O \FL{softlighttransparent} \O \FL{hardlighttransparent} \O \FL{colordodgetransparent} \O \FL{colorburntransparent}
+ \O \FL{darkentransparent} \O \FL{lightentransparent} \O \FL{differencetransparent} \O \FL{exclusiontransparent}
+ \O \FL{huetransparent} \O \FL{saturationtransparent} \O \FL{colortransparent} \O \FL{luminositytransparent}
+ \O \S{symbolic token defined by \L{newinternal}}
+ \O \L{ahangle} \O \L{ahlength}
+ \O \L{bboxmargin}
+ \O \L{pen_bot} \O \L{pen_top} \O \L{pen_lft} \O \L{pen_rt}
+ \O \L{join_radius}
+ \O \L{crossingscale} \O \L{crossingoption}
+\StopSyntax
+
+\StartSyntax
+\S{pseudo function}
+ \M \L {min} \( \S{expression list} \)%
+ \O \L {max} \( \S{expression list} \)
+ \O \L {incr} \( \S{numeric variable} \)%
+ \O \L {decr} \( \S{numeric variable} \)
+ \O \L {dashpattern} \( \S{on/off list} \)
+ \O \L {interpath} \( \S{numeric expression} \L{,} \S{path expression} \L{,} \S{path expression} \)
+ \O \FL{interpolated} \( \S{numeric expression} \L{,} \S{path expression} \L{,} \S{path expression} \)
+ \O \L {buildcycle} \( \S{path expression list} \)
+ \O \L {thelabel} \S{label suffix} \( \S{expression} \L{,} \S{pair expression} \)
+ \O \FL{thefreelabel} \( \S{expression}\L{,} \S{pair expression} \L{,} \S{pair expression} \)
+ \O \FL{anglebetween} \( \S{path expression} \L{,} \S{path expression} \L{,} \S{expression} \)
+ \O \L {flex} \( \S{text} \)
+ \O \L {hide} \( \S{text} \)
+ \O \L {gobble} \S{primary}
+ \O \L {clearit}
+ \O \L {clearpen}
+ \O \L {clearxy}
+ \O \FL{pointarrow} \( \S{path expression} \L{,} \S{numeric or pair primary} \L{,} \S{numeric expression} \)
+ \O \FL{centerarrow} \( \S{path expression} \L{,} \S{numeric or pair primary} \L{,} \S{numeric expression} \)
+ \O \FL{leftarrow} \( \S{path expression} \L{,} \S{numeric or pair primary} \L{,} \S{numeric expression} \)
+ \O \FL{rightarrow} \( \S{path expression} \L{,} \S{numeric or pair primary} \L{,} \S{numeric expression} \)
+ \O \FL{paired} \( \S{numeric or pair} \)%
+ \O \FL{tripled} \( \S{numeric or color} \)
+ \O \FL{remappedcolor} \( \S{color expression} \)
+ \O \FL{superellipse} \( \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \L{,} \L{numeric primary} \L{,} \N \L{numeric primary} \)
+ \O \FL{roundedsquare} \( \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \)
+ \O \FL{tensecircle} \( \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \)
+ \O \FL{tensepath} \( \S{path primary} \)
+ \O \FL{(constructed)function}%
+ \( \S{string expression} \)%
+ \( \S{string primary} \L{,} \S{string primary} \L{,} \S{numeric primary} \L{,}
+ \N \S{numeric primary} \L{,} \S{numeric primary} \)
+ \O \FL{straightfunction} \( \S{string primary} \L{,} \S{string primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \L{,}
+ \N \S{numeric primary} \)
+ \O \FL{curvedfunction} \( \S{string primary} \L{,} \S{string primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \L{,}
+ \N \S{numeric primary} \)
+ %\O \FL{punkedfunction} \( \S{string primary} \L{,} \S{string primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \)
+ %\O \FL{tightfunction} \( \S{string primary} \L{,} \S{string primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \)
+ \O \FL{constructedpairs} \( \S{string expression} \) \( \S{pair array} \)
+ \O \FL{straightpairs} \( \S{pair array} \)
+ \O \FL{curvedpairs} \( \S{pair array} \)
+ %\O \FL{punkedpairs} \( \S{pair array} \)
+ %\O \FL{tightpairs} \( \S{pair array} \)
+ \O \FL{constructedpath} \( \S{string expression} \) \( \S{text} \)
+ \O \FL{straightpath} \( \S{text} \)
+ \O \FL{curvedpath} \( \S{text} \)
+ %\O \FL{punkedpath} \( \S{text} \)
+ %\O \FL{tightpath} \( \S{text} \)
+ \O \FL{epsed} \S{numeric primary}
+ \O \FL{arrowhead} \S{path primary}
+ \O \FL{arrowpath} \S{path primary}
+ \O \FL{infinite} \S{path primary}
+ %
+ \O \FL{tolist} \( \S{pair array} \) \( \S{text} \)
+ \O \FL{topath} \( \S{pair array} \) \( \S{text} \)
+ \O \FL{tocycle} \( \S{pair array} \) \( \S{text} \)
+ \O \FL{pencilled} \( \S{path expression} \) \( \S{pen expression} \)
+\StopSyntax
+
+\StartSyntax
+\S{color expression}
+ \M \S{basic color expression}
+ \O \S{string primary}
+ \O \FL{namedcolor} \( \S{string primary} \)
+ \O \FL{spotcolor} \( \S{string primary} \L{,} \S{basic color expression} \)
+ \O \FL{multitonecolor} \( \S{string primary} \L{,} \S{basic color expression list} \)
+\StopSyntax
+
+\StartSyntax
+\S{basic color expression}
+ \M \S{rgb color expression}
+ \O \S{cmyk color expression}
+ \O \S{gray color expression}
+\StopSyntax
+
+\StartSyntax
+\S{basic color expression list}
+ \M \S{basic color expression}
+ \O \S{basic color expression list} \L{,} \S{basic color expression}
+\StopSyntax
+
+\StartSyntax
+\S{rgb color expression}
+ \M \S\( \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \S\)
+\StopSyntax
+
+\StartSyntax
+\S{cmyk color expression}
+ \M \S\( \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \S\)
+\StopSyntax
+
+\StartSyntax
+\S{gray color expression}
+ \M \S\( \S{numeric primary} \S\)
+ \O \S{numeric primary}
+\StopSyntax
+
+\StartSyntax
+\S{path expression list}
+ \M \S{path expression}
+ \O \S{path expression list} \L{,} \S{path expression}
+\StopSyntax
+
+\StartSyntax
+\S{on/off list}
+ \M \S{on/off list} \S{on/off clause}
+ \O \S{on/off clause}
+\StopSyntax
+
+\StartSyntax
+\S{on/off clause}
+ \M \L{on} \S{numeric tertiary}
+ \O \L{off} \S{numeric tertiary}
+\StopSyntax
+
+\StartSyntax
+\S{boolean expression} \M \S{expression}
+\S{cmyk expression} \M \S{expression}
+\S{color expression} \M \S{expression}
+\S{numeric atom} \M \S{atom}
+\S{numeric expression} \M \S{expression}
+\S{numeric primary} \M \S{primary}
+\S{numeric tertiary} \M \S{tertiary}
+\S{numeric variable} \M \S{variable} \O \S{internal variable}
+\S{pair expression} \M \S{expression}
+\S{pair primary} \M \S{primary}
+\S{path expression} \M \S{expression}
+\S{path subexpression} \M \S{subexpression}
+\S{pen expression} \M \S{expression}
+\S{picture expression} \M \S{expression}
+\S{picture variable} \M \S{variable}
+\S{rgb expression} \M \S{expression}
+\S{string expression} \M \S{expression}
+\S{suffix parameter} \M \S{parameter}
+\S{transform primary} \M \S{primary}
+\StopSyntax
+
+\StartSyntax
+\S{program}
+ \M \S{statement list} \L{end}
+\StopSyntax
+
+\StartSyntax
+\S{statement list}
+ \M \S{empty}
+ \O \S{statement list} \L{;} \S{statement}
+\StopSyntax
+
+\StartSyntax
+\S{statement}
+ \M \S{empty}
+ \O \S{equation}
+ \O \S{assignment}
+ \O \S{declaration}
+ \O \S{macro definition}
+ \O \S{compound}
+ \O \S{pseudo procedure}
+ \O \S{command}
+\StopSyntax
+
+\StartSyntax
+\S{compound}
+ \M \L{begingroup} \S{statement list} \L{endgroup}
+ \O \L{beginfig} \( \S{numeric expression} \) \L{;} \S{statement list} \S{;} \L{endfig}
+ \O \FL{beginglyph} \( \S{glyph property list} \) \L{;} \S{statement list} \S{;} \L{endglyph}
+ \O \L{image builder} \( \S{statement list} \)
+\StopSyntax
+
+\StartSyntax
+\S{image builder}
+ \M {image} \O \FL {decorated} \O \FL {redecorated} \O \FL {undecorated}
+\StopSyntax
+
+\StartSyntax
+\S{glyph property list}
+ \M \S{numeric expression} \L{,} \S{numeric expression} \L{,} \S{numeric expression} \L{,} \S{numeric expression}
+\StopSyntax
+
+\StartSyntax
+\S{equation}
+ \M \S{expression} \L{=} \S{right-hand side}
+\StopSyntax
+
+\StartSyntax
+\S{assignment}
+ \M \S{variable} \L{:=} \S{right-hand side}
+ \O \S{internal variable} \L{:=} \S{right-hand side}
+\StopSyntax
+
+\StartSyntax
+\S{right-and side}
+ \M \S{expression}
+ \O \S{equation}
+ \O \S{assignment}
+\StopSyntax
+
+\StartSyntax
+\S{declaration}
+ \M \S{type} \S{declaration list}
+\StopSyntax
+
+\StartSyntax
+\S{declaration list}
+ \M \S{generic variable}
+ \O \S{declaration list} \L{,} \S{generic variable}
+\StopSyntax
+
+\StartSyntax
+\S{generic variable}
+ \M \S{Symbolic token} \S{generic suffix}
+\StopSyntax
+
+\StartSyntax
+\S{generic suffix}
+ \M \S{empty}
+ \O \S{generic suffix} \S{tag}
+ \O \S{generic suffix} \L{[]}
+\StopSyntax
+
+\StartSyntax
+\S{macro definition}
+ \M \S{macro heading} \L{=} \S{replacement text} \L{enddef}
+\StopSyntax
+
+\StartSyntax
+\S{macro heading}
+ \M \L{def} \S{Symbolic token} \S{delimited part} \S{undelimited part}
+ \O \L{vardef} \S{generic variable} \S{delimited part} \S{undelimited part}
+ \O \L{vardef} \S{generic variable} \L{@#} \S{delimited part} \S{undelimited part}
+ \O \S{binary def} \S{parameter} \S {symbolic token} \S{parameter}
+\StopSyntax
+
+\StartSyntax
+\S{delimited part}
+ \M \S{empty}
+ \O \S{delimited part} \( \S{parameter type} \S{parameter tokens} \)
+\StopSyntax
+
+\StartSyntax
+\S{parameter type}
+ \M \L{expr}
+ \O \L{suffix}
+ \O \L{text}
+\StopSyntax
+
+\StartSyntax
+\S{parameter tokens}
+ \M \S{parameter}
+ \O \S{parameter tokens} \L{,} \S{parameter}
+\StopSyntax
+
+\StartSyntax
+\S{parameter}
+ \M \S{Symbolic token}
+\StopSyntax
+
+\StartSyntax
+\S{undelimited part}
+ \M \S{empty}
+ \O \S{parameter type} \S{parameter}
+ \O \S{precedence level} \S{parameter}
+ \O \L{expr} \S{parameter} \L{of} \S{parameter}
+\StopSyntax
+
+\StartSyntax
+\S{precedence level}
+ \M \L{primary}
+ \O \L{secondary}
+ \O \L{tertiary}
+\StopSyntax
+
+\StartSyntax
+\S{binary def}
+ \M \S{primarydef}
+ \O \S{secondarydef}
+ \O \S{tertiarydef}
+\StopSyntax
+
+\StartSyntax
+\S{pseudo procedure}
+ \M \L {drawoptions} \( \S{option list} \)
+ \O \L {label} \S{label suffix} \( \S{expression} \L{,} \S{pair expression} \)
+ \O \L {thelabel} \S{label suffix} \( \S{expression} \L{,} \S{pair expression} \)
+ \O \L {dotlabel} \S{label suffix} \( \S{expression} \L{,} \S{pair expression} \)
+ \O \L {makelabel} \S{makelabel}
+ \O \L {labels} \S{label suffix} \( \S{point number list} \)
+ \O \L {dotlabels} \S{label suffix} \( \S{point number list} \)
+ \O \FL{textext} \S{label suffix} \( \S{expression} \)
+ \O \FL{infotext} \S{label suffix} \( \S{expression}, \S{numeric expression} \)
+ \O \FL{thetextext} \S{label suffix} \( \S{expression}, \S{pair expression} \)
+ \O \FL{rawtextext} \( \S{expression} \)
+ \O \FL{verbatim} \S{string expression}
+ \O \FL{freelabel} \( \S{expression} \L{,} \S{pair expression} \L{,} \S{pair expression} \)
+ \O \FL{freedotlabel} \( \S{expression} \L{,} \S{pair expression} \L{,} \S{pair expression} \)
+ \O \FL{remapcolor} \( \S{color expression} \L{,} \S{color expression} \)
+ \O \FL{resetcolormap}
+ \O \FL{recolor} \S{picture expression}
+ \O \FL{bitmapimage} \( \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{string primary} \)
+ \O \FL{pushboundingbox} \O \FL{popboundingbox}
+ \O \FL{pushcurrentpicture} \O \FL{popcurrentpicture}
+ \O \FL{externalfigure} \S{string expression} \S{transformer}
+ \O \FL{loadfigure} \S{string expression} \L{number} \S{numeric expression} \S{transformer}
+ \O \FL{properties}
+ \O \L {anchored} \S{label suffix} \( \S{expression} \L{,} \S{pair expression} \)
+\StopSyntax
+
+\StartSyntax
+\S{point number list}
+ \M \S{suffix} \O \S{point number list} \L{,} \S{suffix}
+\StopSyntax
+
+\StartSyntax
+\S{label suffix}
+ \M \S{empty}
+ \O \L{lft} \O \L{rt}\O \L{top} \O \L{bot} \O \L{ulft} \O \L{urt}%
+ \O \L{llft} \O \L{lrt} \O \FL{raw} \O \FL{origin}
+\StopSyntax
+
+\StartSyntax
+\S{command}
+ \M \L{clip} \S{picture variable} \L{to} \S{path expression}
+ \O \L{interim} \S{internal variable} \L{:=} \S{right-hand side}
+ \O \L{let} \S{symbolic token} \L{=} \S{symbolic token}
+ \O \L{pickup} \S{expression}
+ \O \L{randomseed} \L{:=} \S{numeric expression}
+ \O \L{save} \S{symbolic token list}
+ \O \L{delimiters} \S{character} \S{character}
+ \O \L{setbounds} \S{picture variable} \L{to} \S{path expression}
+ \O \L{shipout} \S{picture expression}
+ \O \L{special} \S{string expression}
+ \O \L{endinput}
+ \O \L{expandafter}
+ \O \S{addto command}
+ \O \S{drawing command}
+ \O \S{font metric command}
+ \O \S{newinternal command}
+ \O \S{message command}
+ \O \S{mode command}
+ \O \S{show command}
+ \O \S{special command}
+ \O \S{tracing command}
+ \O \S{scantokens} \S{string expression}
+ \O \FL{defineshade} \S{symbolic token} \S{shading expression}
+ \O \L{write} \S{string expression} \L{to} \S{string expression}
+ \O \L{readfrom} \S{string expression}
+ \O \FL{readfile} \S{string expression}
+ \O \L{readstring}
+ \O \L{restoreclipcolor}
+ \O \L{savepen}
+ \O \L{runscript}
+ \O \L{relax}
+\StopSyntax
+
+\StartSyntax
+\S{show command}
+ \M \L{show} \S{expression list}
+ \O \L{showvariable} \S{symbolic token list}
+ \O \L{showtoken} \S{symbolic token list}
+ \O \L{showdependencies}
+\StopSyntax
+
+\StartSyntax
+\S{symbolic token list}
+ \M \S{symbolic token}
+ \O \S{symbolic token} \L{,} \S{symbolic token list}
+\StopSyntax
+
+\StartSyntax
+\S{expression list}
+ \M \S{expression}
+ \O \S{expression list} \L{,} \S{expression}
+\StopSyntax
+
+\StartSyntax
+\S{addto command}
+ \M \L{addto} \S{picture variable} \L{also} \S{picture expression} \S{option list}
+ \O \L{addto} \S{picture variable} \L{contour} \S{path expression} \S{option list}
+ \O \L{addto} \S{picture variable} \L{doublepath} \S{path expression} \S{option list}
+\StopSyntax
+
+\StartSyntax
+\S{option list}
+ \M \S{empty}
+ \O \S{drawing option} \S{option list}
+\StopSyntax
+
+\StartSyntax
+\S{drawing option}
+ \M \L {withcolor} \S{color expression}%
+ \O \FL {withgrey} \S{numeric expression}%
+ \O \FL {withgray} \S{numeric expression}
+ \O \L {withrgbcolor} \S{rgb expression}%
+ \O \L {withcmykcolor} \S{cmyk expression}%
+ \O \L {withgreyscale} \S{numeric expression}
+ \O \L {withoutcolor}
+ \O \L {withprescript} \S{string expression}%
+ \O \L {withpostscript} \S{string expression}
+ \O \L {withpen} \S{pen expression}
+ \O \L {dashed} \S{picture expression}
+ \O \FL{undashed}
+ \O \FL{withshade} \S{numeric expression} \O \FL{shaded} \S{shading expression}
+ \O \FL{withproperties} \S{property primary}
+ \O \FL{withtransparency} \S{pair primary}
+ \O \FL{withlinearshade} \(%
+ \S{path expression} \L{,}%
+ \S{path expression} \L{,}%
+ \S{color expression} \L{,}%
+ \S{color expression} \)
+ \O \FL{withcircularshade} \(%
+ \S{path ex} \L{,}%
+ \S{path ex} \L{,}%
+ \S{numeric ex} \L{,}%
+ \S{numeric ex} \L{,}%
+ \S{color ex} \L{,}%
+ \S{color ex} \)
+ \O \S{shading expression}
+ \O \FL{onlayer} \S{string expression}
+ \O \FL{withmask} \S{string expression}
+\StopSyntax
+
+\StartSyntax
+\S{property expression}
+ \M \( {drawing option} \)
+\StopSyntax
+
+\StartSyntax
+\S{shading expression}
+ \M \FL{withshademethod} \L{string expression}
+ \O \FL{withshadefactor} \L{numeric expression}
+ \O \FL{withshadedomain} \L{pair expression}
+ \O \FL{withshadevector} \L{pair expression}
+ \O \FL{withshaderadius} \L{pair expression}
+ \O \FL{withshadeorigin} \L{pair expression}
+ \O \FL{withshadecolors} \( \S{color expression} \L{,} \S{color expression} \)
+ \O \FL{withshadecenter} \L{pair expression}
+\StopSyntax
+
+\StartSyntax
+\S{drawing command}
+ \M \L{draw} \S{picture expression} \S{option list}
+ \O \S{fill type} \S{path expression} \S{option list}
+\StopSyntax
+
+\StartSyntax
+\S{fill type}
+ \M \L {fill} \O \L{unfill} \O \FL{refill}
+ \O \L {draw} \O \L{undraw} \O \FL{redraw}
+ \O \L {filldraw} \O \FL{drawfill} \O \L{undrawfill} \O \L{unfilldraw}
+ \O \FL{eofill} \O \FL{nofill} \O \FL{fillup}
+ \O \L {drawdot}
+ \O \L {drawarrow} \O \L{drawdblarrow}
+ \O \L {cutdraw}
+ \O \L {visualizer}
+ \O \FL{normaldraw} \O \FL{normalfill}
+\StopSyntax
+
+\StartSyntax
+\S{visualizer}
+ \M \FL{drawboundary} \O \FL{drawboundingbox} \O \FL{drawboundoptions}
+ \O \FL{drawcontrollines} \O \FL{drawcontroloptions} \O \FL{drawcontrolpoints}
+ \O \FL{drawlabeloptions} \O \FL{drawlineoptions} \O \FL{drawoptions}
+ \O \FL{draworigin} \O \FL{draworiginoptions}
+ \O \FL{drawpath} \O \FL{drawpathoptions}
+ \O \FL{drawpoint} \O \FL{drawpointlabels} \O \FL{drawpointoptions}
+ \O \FL{drawpoints} \O \FL{drawwholepath}
+ \O \FL{visualizeddraw} \O \FL{visualizedfill}
+\StopSyntax
+
+\StartSyntax
+\S{newinternal command}
+ \M \L{newinternal} \S{internal type} \S{symbolic token list}
+ \O \S{newinternal} \S{symbolic token list}
+\StopSyntax
+
+\StartSyntax
+\S{message command}
+ \M \L{errhelp} \S{string expression}
+ \O \L{errmessage} \S{string expression}
+ \O \L{filenametemplate} \S{string expression}
+ \O \L{message} \S{string expression}
+\StopSyntax
+
+\StartSyntax
+\S{mode command}
+ \M \L{batchmode}
+ \O \L{nonstopmode}
+ \O \L{scrollmode}
+ \O \L{errorstopmode}
+ \O \L{interact}
+\StopSyntax
+
+\StartSyntax
+\S{special command}
+ \M \L{fontmapfile} \S{string expression}
+ \O \L{fontmapline} \S{string expression}
+ \O \L{special} \S{string expression}
+ \O \L{input} \S{string expression}
+ \O \L{prologies} \S{numeric expression}
+ \O \L{outputtemplate} \S{string expression}
+ \O \L{outputformat} \S{string expression}
+\StopSyntax
+
+\StartSyntax
+\S{tracing command}
+ \M \L{tracingall}
+ \O \L{loggingall}
+ \O \L{tracingnone}
+\StopSyntax
+
+\StartSyntax
+\S{if test}
+ \M \L{if} \S{boolean expression} \L{:} \S{balanced tokens} \S{alternatives} \L{fi}
+\StopSyntax
+
+\StartSyntax
+\S{alternatives}
+ \M \S{empty}
+ \O \L{else} \L{:} \S{balanced tokens}
+ \O \L{elseif} \S{boolean expression} \S{:} \S{balanced tokens} \S{alternatives}
+ \O \L{exit} \O \L{exitif} \S{boolean expression} \O \L{exitunless} \S{boolean expression}
+ \O \L{break}
+\StopSyntax
+
+\StartSyntax
+\S{loop}
+ \M \S{loop header} \L{:} \S{loop text} \L{endfor}
+\StopSyntax
+
+\StartSyntax
+\S{loop header}
+ \M \L{for} \S{symbolic token} \L{=} \S{progression}
+ \O \L{for} \S{symbolic token} \L{=} \S{for list}
+ \O \L{for} \S{symbolic token} \L{within} \S{picture expression}
+ \O \L{forsuffixes} \S{symbolic token} \L{=} \S{suffix list}
+ \O \L{forever}
+\StopSyntax
+
+\StartSyntax
+\S{progression}
+ \M \S{numeric expression} \L{upto} \S{numeric expression}
+ \O \S{numeric expression} \L{downto} \S{numeric expression}
+ \O \S{numeric expression} \L{step} \S{numeric expression} \L{until} \S{numeric expression}
+ \O \L{range} \S{numeric expression} \L{thru} \S{numeric expression}
+\StopSyntax
+
+\StartSyntax
+\S{for list}
+ \M \S{expression}
+ \O \S{for list} \L{,} \S{expression}
+\StopSyntax
+
+\StartSyntax
+\S{suffix list}
+ \M \S{suffix}
+ \O \S{suffix list} \L{,} \S{suffix}
+\StopSyntax
+
+\stop
+
+% \stopsection
+
+\stopchapter
+
+\stopcomponent
+
+% \startsection[title={Left overs}]
+
+% There are a few more concepts and commands available in \METAFUN, like color
+% remapping, shading and graphic inclusion. Because they have their own small
+% syntax world, we present them here.
+%
+% You may consider shades to be internally represented by a hidden datastructure.
+% The end user has access to a shade by means of a pointer, expressed in a numeric.
+%
+% \start \switchtobodyfont[small]
+%
+% \StartSyntax
+% \S{pseudo procedure}
+% \M \FL{linear_shade}%
+% \( \S{path expression} \L{,} \S{numeric expression}%
+% \L{,} \S{color expression} \L{,} \S{color expression} \)
+% \O \FL{circular_shade}%
+% \( \S{path expression} \L{,} \S{numeric expression}%
+% \L{,} \S{color expression} \L{,} \S{color expression} \)
+% \StopSyntax
+%
+% \StartSyntax
+% \S{pseudo function}
+% \M \FL{define_linear_shade}%
+% \( \S{pair expr} \L{,} \S{pair expr}%
+% \L{,} \S{color expr} \L{,} \S{color expr} \)
+% \O \FL{define_circular_shade}%
+% \( \S{pair expr} \L{,} \S{pair expr}%
+% \L{,} \S{path expr} \L{,} \S{path expr}%
+% \L{,} \S{color expr} \L{,} \S{color expr} \)
+% \O \FL{predefined_linear_shade}%
+% \( \S{path expr} \L{,} \S{numeric expr}%
+% \L{,} \S{color expr} \L{,} \S{color expr} \)
+% \O \FL{predefined_circular_shade}%
+% \( \S{path expr} \L{,} \S{numeric expr}%
+% \L{,} \S{color expr} \L{,} \S{color expr} \)
+% \StopSyntax
+%
+% \stop
+
+% External figures are just files, so the string passed as first argument needs to
+% be a valid filename. Additionally, they need to be given dimensions.
+
+% \start \switchtobodyfont[small]
+%
+% \StartSyntax
+% \S{pseudo procedure}
+% \M \FL{externalfigure} \S{string expression} \S{transformer}
+% \StopSyntax
+%
+% \stop
+
+% An external \METAPOST\ graphic can be loaded by filename and figure number. The
+% normal transformations can be applied.
+%
+% \start \switchtobodyfont[small]
+%
+% \StartSyntax
+% \S{pseudo procedure}
+% \M \FL{loadfigure} \S{string expression} \L{number} \S{numeric expression} \S{transformer}
+% \StopSyntax
+%
+% \stop
+
+% A graphic text is (normally) an outline representation of a snippet of text
+% typeset by \TEX. This procedure has a couple of dedicated options.
+
+% \start \switchtobodyfont[small]
+
+% \StartSyntax
+% \S{pseudo procedure}
+% \M \FL{graphictext} \S{string expression} \S{transformer} \S{text option list}
+% \O \FL{regraphictext} \S{transformer} \S{text option list}
+% \StopSyntax
+
+% \StartSyntax
+% \S{text option list}
+% \M \S{empty}
+% \O \S{text drawing option} \S{text option list}
+% \StopSyntax
+
+% \StartSyntax
+% \S{text drawing option}
+% \M \S{drawing option}
+% \O \FL{reversefill}
+% \O \FL{outlinefill}
+% \O \FL{withdrawcolor} \S{color expression}
+% \O \FL{withfillcolor} \S{color expression}
+% \StopSyntax
+
+% \StartSyntax
+% \S{pseudo procedure}
+% \M \FL{resetgraphictextdirective}
+% \O \FL{graphictextdirective} \S {string expression}
+% \StopSyntax
+
+% \StartSyntax
+% \S{internal variable}
+% \M \FL{graphictextformat}
+% \StopSyntax
+
+% \stop
+
+% \stopsection
+
+% \stopchapter
+
+% \stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-text.tex b/doc/context/sources/general/manuals/metafun/metafun-text.tex
new file mode 100644
index 000000000..f70f53ac3
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-text.tex
@@ -0,0 +1,1784 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-text
+
+\environment metafun-environment
+
+\startchapter[reference=sec:typesetting,title={Typesetting in \METAPOST}]
+
+\startintro
+
+It is said that a picture tells more than a thousand words. So you might expect
+that text in graphics becomes superfluous. Out of experience we can tell you that
+this is not the case. In this chapter we explore the ways to add text to
+\METAPOST\ graphics, and let you choose whether or not to have it typeset by
+\TEX.
+
+\stopintro
+
+\startsection[title={The process}]
+
+\index{text}
+
+You can let \METAPOST\ process text that is typeset by \TEX. Such text is first
+embedded in the \METAPOST\ file in the following way:
+
+\starttyping
+btex Some text to be typeset by \TEX etex
+\stoptyping
+
+This returns a picture, but only after \METAPOST\ has made sure that \TEX\ has
+converted it into something useful. This process of conversion is slightly system
+dependent and even a bit obscure. Traditional \METAPOST\ calls a program that
+filters the \type {btex}|\unknown|\type {etex} commands, next it calls \TEX\ by
+passing the output routine, in order to make sure that each piece of text ends up
+on its own page, and afterwards it again calls a program that converts the \DVI\
+pages into \METAPOST\ pictures. In \LUATEX's \MPLIB\ a different route is
+followed.
+
+In \CONTEXT\ \MKII, when using \WEBC, you can generate the graphics at run||time.
+This takes more time than processing the graphics afterwards, but has the
+advantage that \TEX\ knows immediately what graphic it is dealing with. When
+enabled, \CONTEXT\ will call either \METAPOST, or, when the graphic contains
+\type {btex}||\type {etex} commands, call \TEXEXEC, which in turn makes sure that
+the right auxiliary programs are executed.
+
+In \CONTEXT\ \MKIV\ you won't notice this at all because everything is tightly
+integrated with \LUATEX's \MPLIB. This has an enormous speed gain: when this
+manual had about 425 pages, on my laptop with mobile 3840QM processor, one run of
+this document takes 18 seconds (14.5 with \LUAJITTEX) and that includes loadint a
+bunch of (outline) fonts and processing some 2200 \METAPOST\ images. While
+writing the first version of this manual runtime was upto 50 times slower for
+half the number of pages so compared to \MKII\ we have gained a lot.
+
+\startFLOWchart[metatex]
+ \startFLOWcell
+ \name {script 1}
+ \location {1,1}
+ \shape {action}
+ \text {\type{context}}
+ \connection [rl] {context 1}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {context 1}
+ \location {2,1}
+ \shape {action}
+ \text {\CONTEXT}
+ \connection [bt] {metapost 1}
+ \connection [rl] {script 2}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {metapost 1}
+ \location {2,2}
+ \shape {action}
+ \text {\METAPOST}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {script 2}
+ \location {3,1}
+ \shape {action}
+ \text {\type{context}}
+ \connection [rl] {context 2}
+ \connection [bt] {metapost 2}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {context 2}
+ \location {4,1}
+ \shape {action}
+ \text {\CONTEXT}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {metapost 2}
+ \location {3,2}
+ \shape {action}
+ \text {\METAPOST}
+ \stopFLOWcell
+\stopFLOWchart
+
+\startplacefigure[title={How \TEX\ and \METAPOST\ work together.}]
+ \FLOWchart[metatex]
+\stopplacefigure
+
+\stopsection
+
+\startsection[title={Environments}]
+
+\index{environments}
+
+In case you want to pass code that is shared by all \type {btex}||\type {etex}
+pictures, \METAPOST\ provides:
+
+\starttyping
+verbatimtex \DefineSomeCommands etex ;
+\stoptyping
+
+However, in \CONTEXT\ one has a better mechanism available. In \CONTEXT\ \MKII\
+the advised method is passing environments. The best way to pass them is the
+following. As an example we switch to the 15 basic \POSTSCRIPT\ fonts.
+
+\startbuffer[pos]
+\startMPenvironment
+ \usetypescript[palatino][texnansi] % mkii has encodings
+ \setupbodyfont[palatino]
+\stopMPenvironment
+\stopbuffer
+
+\typebuffer[pos]
+
+This means that in code like the following, a Palatino font will be used.
+
+\starttyping
+\startMPcode
+draw btex Meta is a female lion! etex
+ xysized (\the\textwidth,\the\textheight) ;
+\stopMPcode
+\stoptyping
+
+However, in \CONTEXT\ \MKIV\ this method is no longer recomended as all
+processing happens in the same run anyway.
+
+% beware: extensive scaling can make acrobat crash and okular drop the !
+
+\startbuffer[lioncode]
+\startMPcode
+numeric w, h ; w := \the\textwidth ; h := w/2 ;
+
+picture p ; p := btex \colored[r=.375,g=.375]{Meta is a female lion!} etex
+ xysized (w,h) ;
+picture q ; q := btex \colored[r=.625] {Meta is a female lion!} etex
+ xysized (w,h) ;
+
+path b ; b := boundingbox p ; draw p ;
+
+for i=(.28w,.90h),(.85w,.90h),(w,.05h) :
+ picture r ; r := q ;
+ path s ; s := (fullsquare xscaled .05w yscaled .4h) shifted i ;
+ clip r to s ; draw r ; % draw s ;
+endfor ;
+
+setbounds currentpicture to b ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[lioncode]
+
+\in {Figure} [lionclip] shows the previous sentence in a slightly different look.
+You may consider coloring the dots to be an exercise in clipping.
+
+\getbuffer[pos]
+
+\placefigure
+ [here][lionclip]
+ {An example of clipping.}
+ {\getbuffer[lioncode]}
+
+\resetMPenvironment
+
+An environment can be reset with \typ {\resetMPenvironment} or by passing \type
+{reset} to \typ {\startMPenvironment}.
+
+\starttyping
+\startMPenvironment[reset]
+ \usetypescript[postscript][texnansi] % mkii
+ \setupbodyfont[postscript]
+\stopMPenvironment
+\stoptyping
+
+So, to summarize: if you're using \CONTEXT\ \MKIV\ you might as well forgot what
+you just read.
+
+\stopsection
+
+\startsection[title={Labels}]
+
+\index{labels}
+
+In \METAPOST\ you can use the \type {label} macro to position text at certain
+points.
+
+\starttyping
+label("x", origin) ;
+\stoptyping
+
+The font and scale are determined by two variables, \type {defaultfont} and \type
+{defaultscale}, the former expecting the name of a font in the form of a string,
+the latter expecting a numeric to be used in the scaling of the font. Should you
+choose not to set these yourself, they default to \type {"Mono"} and \type
+{1.0}, respectively. However, you can change the defaults as follows:
+
+\starttyping
+defaultfont := "texgyrepagella-regular*default" ;
+defaultscale := 1.2 ;
+\stoptyping
+
+These settings selects Pagella at about 12pt. You can also set these variables
+to \CONTEXT\ related values. For \CONTEXT\ graphics they are set to:
+
+\starttyping
+defaultfont := "\truefontname{Regular}*default" ;
+defaultscale := \the\bodyfontsize/10 ;
+\stoptyping
+
+This means that they will adapt themselves to the current body font (in this
+document we get \truefontname{Regular}) and the current size of the bodyfont
+(here \the\bodyfontsize/10).
+
+\stopsection
+
+\startsection[title={\TeX\ text}]
+
+\index{text}
+
+In the next example we will use a special mechanism for building graphics step by
+step. The advantage of this method is that we can do intermediate calculations in
+\TEX. Our objective is to write a macro that draws text along a circular path.
+While doing so we want to achieve the following:
+
+\startitemize[packed]
+\item the text should be properly kerned, i.e.\ the
+ spacing between characters should be optimal,
+\item the position on the circle should vary, and
+\item the radius of the circle should vary.
+\stopitemize
+
+This implementation is not the most straightforward one, but by doing it step by
+step, at least we see what is involved. Later, we will see a better method. If
+you run these examples yourself, you must make sure that the \TEX\ environment of
+your document matches the one used by \METAPOST.
+
+We let the bodyfont match the font used in this document, and define \type
+{RotFont} to be the regular typeface, the one you are reading right now, but
+bold.
+
+\startbuffer
+\definefont[RotFont][RegularBold*default]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Since \METAPOST\ is unaware of kerning, we have to use \TEX\ to keep track of the
+positions. We will split the text into tokens (often characters) and store the
+result in an array of pictures (\type {pic}). We will also store the accumulated
+width in an array (\type {len}). The number of characters is stored in~\type {n}.
+In a few paragraphs we will see why the other arrays are needed.
+
+While defining the graphic, we need \TEX\ to do some calculations. Therefore, we
+will use \type {\startMPdrawing} to stepwise construct the definition. The basic
+pattern we will follow is:
+
+\starttyping
+\resetMPdrawing
+\startMPdrawing
+ metapost code
+\stopMPdrawing
+tex code
+\startMPdrawing
+ metapost code
+\stopMPdrawing
+\MPdrawingdonetrue
+\getMPdrawing
+\stoptyping
+
+In the process, we will use a few variables. We will store the individual
+characters of the text in the variable \type {pic}, its width in \type {wid} and
+the length of the string so far in \type {len}. Later we will use the \type {pos}
+array to store the position where a character ends up. The variable \type {n}
+holds the number of tokens.
+
+\startbuffer[init]
+\resetMPdrawing
+\startMPdrawing
+ picture pic[] ;
+ numeric wid[], len[], pos[], n ;
+ wid[0] := len[0] := pos[0] := n := 0 ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[init]
+
+We also started fresh by resetting the drawing. From now on, each start command
+will add some more to this graphic. The next macro is responsible for collecting
+the data. Each element is passed on to \TEX, using the \type {btex} construct.
+So, \METAPOST\ itself will call \TEX !
+
+\startbuffer[toks]
+\def\whatever#1%
+ {\appendtoks#1\to\MPtoks
+ \setbox\MPbox=\hbox{\bfd\the\MPtoks}%
+ \startMPdrawing
+ n := n + 1 ; len[n] := \the\wd\MPbox ;
+ \stopMPdrawing
+ \startMPdrawing[-]
+ pic[n] := textext("\bfd\setstrut\strut#1") ;
+ pic[n] := pic[n] shifted - llcorner pic[n] ;
+ \stopMPdrawing}
+
+\handletokens MetaPost is Fun!\with\whatever
+\stopbuffer
+
+\typebuffer[toks]
+
+We use the low level \CONTEXT\ macro \type {\appendtoks} to extend the token list
+\type {\MPtoks}. The \type {\handletokens} macro passes each token (character) of
+\typ {MetaPost is Fun!} to the macro \type {\whatever}. The tokens are appended
+to the token register \type {\MPtoks} (already defined). Then we typeset the
+content of \type {\MPtoks} in \type {\MPbox} (also already defined). The width of
+the box is passed to \METAPOST\ and stored in \type {len}.
+
+By default the content of the drawing is expanded, which means that the macro is
+replaced by its current meaning, so the current width ends up in the \METAPOST\
+file. The next part of the drawing, starting with \type {btex}, puts the token in
+a picture. This time we don't expand the drawing, since we want to pass font
+information. Here, the \type {[-]} suppresses expansion of \typ {btex \bfd #1
+etex}. The process is iterated by \type {\handletokens} for each character of the
+text \typ {MetaPost is Fun!}.
+
+Before we typeset the text, now available in pieces in \type {pic}, in a circle,
+we will first demonstrate what they look like. You may like to take a look at the
+file \type {mpgraph.mp} to see what is passed to \METAPOST.
+
+\startbuffer[test]
+\startMPdrawing
+ pair len ; len := origin ;
+ for i=1 upto n :
+ draw pic[i] shifted len ;
+ draw boundingbox pic[i] shifted len
+ withpen pencircle scaled .25pt withcolor red ;
+ len := len+(xpart urcorner pic[i]-xpart llcorner pic[i],0) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[test]
+
+\startbuffer[show]
+\MPdrawingdonetrue\getMPdrawing
+\stopbuffer
+
+We can call up this drawing with \type {\getMPdrawing}, but first we inform the
+compiler that our \METAPOST\ drawing is completed.
+
+\typebuffer[show]
+
+This results in:
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,test,show]
+\stoplinecorrection
+
+Compare this text with the text as typeset by \TEX:
+
+\blank \start \bfd MetaPost is Fun!\par \stop \blank
+
+and you will see that the text produced by \METAPOST\ is not properly kerned.
+When putting characters after each other, \TEX\ uses the information available in
+the font, to optimize the spacing between characters, while \METAPOST\ looks at
+characters as separate entities. But, since we have stored the optimal spacing in
+\type {len}, we can let \METAPOST\ do a better job. Let's first calculate the
+correction needed.
+
+\startbuffer[kern]
+\startMPdrawing
+ for i=1 upto n :
+ wid[i] := abs(xpart urcorner pic[i] - xpart llcorner pic[i]) ;
+ pos[i] := len[i]-wid[i] ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[kern]
+
+This compares well to the text as typeset by \TEX:
+
+\blank \start \bfd MetaPost is Fun!\par \stop \blank
+
+We can now use the values in \type {pos} to position the pictures according to
+what \TEX\ considered to be the best (relative) position.
+
+\startbuffer[test]
+\startMPdrawing
+ for i=1 upto n :
+ draw pic[i] shifted (pos[i],0) ;
+ draw boundingbox pic[i] shifted (pos[i],0)
+ withpen pencircle scaled .25pt withcolor red ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[test]
+
+That this correction is adequate, is demonstrated in the next graphic. If you
+look closely, you will see that for instance the \quote {o} is moved to the left,
+under the capital \quote {P}.
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,test,show]
+\stoplinecorrection
+
+When we want to position the pictures along a circle, we need to apply some
+rotations, especially because we want to go clockwise. Since we don't want to use
+\quote {complicated} math or more advanced \METAPOST\ code yet, we will do it in
+steps.
+
+\startbuffer[swap]
+\startMPdrawing
+ for i=1 upto n:
+ pic[i] := pic[i] rotatedaround(origin,-270) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[swap]
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,swap,test,show]
+\stoplinecorrection
+
+\startbuffer[cent]
+\startMPdrawing
+ for i=1 upto n :
+ pic[i] := pic[i]
+ shifted (0,ypart -.5[ulcorner pic[i],llcorner pic[i]]) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+We will now center the pictures around the baseline. Centering comes down to
+shifting over half the height of the picture. This can be expressed by:
+
+\starttyping
+ypart -.5[ulcorner pic[i],llcorner pic[i]]
+\stoptyping
+
+but different ways of calculating the distance are possible
+too.
+
+\typebuffer[cent]
+
+So, now we have:
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,swap,cent,test,show]
+\stoplinecorrection
+
+When we typeset on a (half) circle, we should map the actual length onto a
+partial circle. We denote the radius with an~\type {r} and shift the pictures to
+the left.
+
+\startbuffer[shif]
+\startMPdrawing
+ numeric r ; r := len[n]/pi ;
+ for i=1 upto n :
+ pic[i] := pic[i] shifted (-r,0) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[shif]
+
+You can now use the following code to test the current state of the pictures. Of
+course this code should not end up in the final definitions.
+
+\startbuffer[test]
+\startMPdrawing
+ draw origin
+ withpen pencircle scaled 5pt withcolor red ;
+ for i=1 upto n :
+ draw pic[i] ;
+ draw boundingbox pic[i]
+ withpen pencircle scaled .25pt withcolor red ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[test]
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,swap,cent,shif,test,show]
+\stoplinecorrection
+
+Later we will write a compact, efficient macro to take care of rotation. However,
+for the moment, so as not to overwhelm you with complicated code, we will rotate
+each individual picture with the following code fragment.
+
+\startbuffer[rots]
+\startMPdrawing
+ numeric delta, extra, radius, rot[] ;
+
+ delta := extra := radius := 0 ;
+
+ for i=1 upto n :
+ rot[i] := extra+delta-((pos[i]+.5wid[i])/len[n])*(180+2delta) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[rots]
+
+Here we introduce a few variables that we can use later to tune the result a bit.
+With \type {delta}, the space between the characters can be increased, while
+\type {extra} rotates the whole string around the origin. The \type {radius}
+variable can be used to increase the distance to the origin. Without these
+variables, the assignment would have been:
+
+\starttyping
+rot[i] := ((pos[i]+.5wid[i])/len[n])*180 ;
+\stoptyping
+
+Placing the pictures is now rather easy:
+
+\startbuffer[done]
+\startMPdrawing
+ for i=1 upto n :
+ draw pic[i] shifted (-radius,0) rotatedaround(origin,rot[i]) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[done]
+
+The pictures are now positioned on half a circle, properly kerned.
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,swap,cent,shif,rots,done,show]
+\stoplinecorrection
+
+A bit more insight is given in the next picture:
+
+\startbuffer[test]
+\startMPdrawing
+ def moved(expr i) =
+ shifted (-radius,0) rotatedaround(origin,rot[i])
+ enddef ;
+ pickup pencircle scaled .5pt ;
+ for i=1 upto n :
+ draw pic[i] moved(i) ;
+ draw boundingbox pic[i] moved(i) withcolor red ;
+ draw origin -- center pic[i] moved(i) withcolor green ;
+ endfor ;
+ draw tcircle scaled 2r withcolor blue ;
+\stopMPdrawing
+\stopbuffer
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,swap,cent,shif,rots,test,show]
+\stoplinecorrection
+
+This was defined as follows. The path variable \type {tcycle} is predefined to
+the top half of a fullcircle.
+
+\typebuffer[test]
+
+We will now package all of this into a nice, efficient macro, using, of course,
+the predefined scratch registers \type {\MPtoks} and \type {\MPbox}. First we
+define the token processor. Note again the expansion inhibition switch \type
+{[-]}.
+
+\startbuffer
+\def\processrotationtoken#1%
+ {\appendtoks#1\to\MPtoks
+ \setbox\MPbox=\hbox{\RotFont\the\MPtoks}%
+ \startMPdrawing
+ n := n + 1 ; len[n] := \the\wd\MPbox ;
+ \stopMPdrawing
+ \startMPdrawing[-]
+ pic[n] := textext("\RotFont\setstrut\strut#1") ;
+ pic[n] := pic[n] shifted - llcorner pic[n] ;
+ \stopMPdrawing}
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+The main macro is a bit more complicated but by using a few scratch numerics, we
+can keep it readable.
+
+\startbuffer
+\def\rotatetokens#1#2#3#4% delta extra radius tokens
+ {\vbox\bgroup
+ \MPtoks\emptytoks
+ \resetMPdrawing
+ \startMPdrawing
+ picture pic[] ;
+ numeric wid, len[], rot ;
+ numeric delta, extra, radius, n, r ;
+ len[0] := n := 0 ;
+ delta := #1 ; extra := #2 ; radius := #3 ;
+ \stopMPdrawing
+ \handletokens#4\with\processrotationtoken
+ \startMPdrawing
+ r := len[n]/pi ;
+ for i=1 upto n :
+ wid := abs(xpart lrcorner pic[i] -
+ xpart llcorner pic[i]) ;
+ rot := extra + delta -
+ ((len[i]-.5wid)/len[n]) * (180+2delta) ;
+ draw pic[i]
+ rotatedaround (origin,-270) shifted (-r-radius,
+ ypart -.5[ulcorner pic[i], llcorner pic[i]])
+ rotatedaround (origin,rot) ;
+ endfor ;
+ \stopMPdrawing
+ \MPdrawingdonetrue
+ \getMPdrawing
+ \resetMPdrawing
+ \egroup}
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+\startbuffer
+\startcombination[3*1]
+ {\rotatetokens {0} {0}{0}{Does it work ok?}} {A}
+ {\rotatetokens{20} {0}{0}{Does it work ok?}} {B}
+ {\rotatetokens{20}{30}{0}{Does it work ok?}} {C}
+\stopcombination
+\stopbuffer
+
+We can use this macro as follows:
+
+\typebuffer
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+The previous macro is not really an example of generalization, but we used it for
+demonstrating how to build graphics in a stepwise way. If you put the steps in
+buffers, you can even combine steps and replace them at will. This is how we made
+the previous step by step examples: We put each sub||graphic in a buffer and then
+called the ones we wanted.
+
+We now present a more general approach to typesetting along a given path. This
+method is not only more robust and general, it is also a more compact definition,
+especially if we omit the tracing and testing code. We use a familiar auxiliary
+definition. The \type {\setstrut} and \type {\strut} commands ensure that the
+lines have the proper depth and height.
+
+\startbuffer
+\def\processfollowingtoken#1%
+ {\appendtoks#1\to\MPtoks
+ \setbox\MPbox=\hbox{\RotFont\setstrut\strut\the\MPtoks}%
+ \startMPdrawing
+ n := n + 1 ; len[n] := \the\wd\MPbox ;
+ \stopMPdrawing
+ \startMPdrawing[-]
+ pic[n] := btex \RotFont\setstrut\strut#1 etex ;
+ pic[n] := pic[n] shifted -llcorner pic[n] ;
+ \stopMPdrawing}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+In \MKII\ the previous code is collected in the macro \type {\followtokens} but
+in \MKIV\ we use a different approach. There we use a mix of \TEX, \METAPOST, and
+\LUA\ to define that macro. The principles remain the same but the code is more
+robust.
+
+\input meta-imp-txt.mkiv % we need to force a reload \useMPlibrary[txt]
+
+So, how does this compare to earlier results? The original, full text as typeset
+by \TEX, looks like:
+
+\blank \start \RotFont We now follow some arbitrary path ... \stop \blank
+
+In the examples, the text is typeset along the path with:
+
+\startbuffer[toks]
+\followtokens{We now follow some arbitrary path ...}
+\stopbuffer
+
+\typebuffer[toks]
+
+\startlinecorrection[blank]
+\getbuffer[toks]
+\stoplinecorrection
+
+Since we did not set a path, a dummy path is used. We can provide a path by
+(re)defining the graphic \type {followtokens}.
+
+\startbuffer[trac]
+\startMPinclusions
+ boolean TraceRot ; TraceRot := true ;
+\stopMPinclusions
+\stopbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := fullcircle ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer
+\typebuffer[draw]
+\startlinecorrection[blank]
+\hbox
+ {\getbuffer[draw,toks]\hskip1cm
+ \getbuffer[trac,draw,toks]}
+\stoplinecorrection
+\stopbuffer
+
+\getbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := reverse fullcircle ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := (-3cm,-1cm)--(0,1cm)--(3cm,-1cm) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := (-3cm,0)--(3cm,1cm) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := (-3cm,0)..(-1cm,1cm)..(3cm,0) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := (-3cm,0)..(-1cm,1cm)..(0cm,-2cm)..(3cm,0) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer
+
+When turned on, tracing will produce bounding boxes as well as draw the path.
+Tracing can be turned on by saying:
+
+\typebuffer[trac]
+
+% let's turn it off now
+
+\startMPinclusions
+ boolean TraceRot ; TraceRot := false ;
+\stopMPinclusions
+
+The next example is dedicated to Giuseppe Bilotta who wants to handle multiple
+strings and uses a patched version of \type {\followtokens}. To avoid a
+complicated explanation, we will present an alternative here that uses overlays.
+This method also avoids complicated path definitions.
+
+\startbuffer
+\startoverlay
+ {\startuseMPgraphic{followtokens}
+ draw fullcircle scaled 5cm .
+ withpen pencircle scaled 1pt withcolor .625yellow ;
+ draw fullsquare scaled 5.25cm
+ withpen pencircle scaled 1pt withcolor .625red ;
+ drawoptions (withcolor .625red) ;
+ path RotPath ; RotPath := halfcircle scaled 5cm ;
+ setbounds currentpicture to boundingbox fullcircle scaled 5.25cm ;
+ \stopuseMPgraphic
+ \followtokens { Met{\`a} superiore }}
+ {\startuseMPgraphic{followtokens}
+ drawoptions (withcolor .625red) ;
+ path RotPath ; RotPath := halfcircle rotated 90 scaled 5cm ;
+ setbounds currentpicture to boundingbox fullcircle scaled 5.25cm ;
+ \stopuseMPgraphic
+ \followtokens { {$\star$} }}
+ {\startuseMPgraphic{followtokens}
+ drawoptions (withcolor .625red) ;
+ path RotPath ; RotPath := halfcircle rotated 180 scaled 5cm ;
+ setbounds currentpicture to boundingbox fullcircle scaled 5.25cm ;
+ \stopuseMPgraphic
+ \followtokens { Met{\`a} inferiore }}
+ {\startuseMPgraphic{followtokens}
+ drawoptions (withcolor .625red) ;
+ path RotPath ; RotPath := halfcircle rotated 270 scaled 5cm ;
+ setbounds currentpicture to boundingbox fullcircle scaled 5.25cm ;
+ \stopuseMPgraphic
+ \followtokens { {$\star$} }}
+\stopoverlay
+\stopbuffer
+
+\typebuffer
+
+In order to fool the overlay macro that each graphic has the same size, we force
+a bounding box.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Talking to \TEX}]
+
+Sometimes, others may say oftentimes, we are in need for some fancy typesetting.
+If we want to typeset a paragraph of text in a non standard shape, like a circle,
+we have to fall back on \type {\parshape}. Unfortunately, \TEX\ is not that
+strong in providing the specifications of more complicated shapes, unless you are
+willing to do some complicated arithmetic \TEX. Given that \METAPOST\ knows how
+to deal with shapes, the question is: \quotation {Can \METAPOST\ be of help?}
+
+In the process of finding out how to deal with this, we first define a simple
+path. Because we are going to replace pieces of code, we will compose the graphic
+from components. First, we create the path.
+
+\startbuffer
+\startuseMPgraphic{text path}
+ path p ; p := ((0,1)..(-1,0)..(1,0)--cycle) scaled 65pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This shape is not that beautiful, but it has a few characteristics that will help
+us to identify bordercases.
+
+\startbuffer
+\startuseMPgraphic{text draw}
+ drawarrow p withpen pencircle scaled 1pt withcolor red ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Now we use \CONTEXT's \type {\includeMPgraphic} command to build our graphic from
+the previously defined components.
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text path}
+ \includeMPgraphic{text draw}
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+When called with \type {\useMPgraphic{text}}, we get:
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+For the moment we start the path at $(x=0,y>0)$, but later using more complicated
+macros, we will see that we can use arbitrary paths.
+
+We are going to split the path in two, and will use the points that make up the
+bounding box as calcutated by \METAPOST. The next graphic shows one of these
+points, the lower left corner, available as point \typ {llcorner p}.
+
+\startbuffer
+\startuseMPgraphic{text draw}
+ draw p withpen pencircle scaled 3pt withcolor red ;
+ draw boundingbox p withpen pencircle scaled 1pt ;
+ draw llcorner p withpen pencircle scaled 5pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+The five points that \METAPOST\ can report for each path or picture are:
+
+\starttabulate[|Tl|l|]
+\NC llcorner \NC lower left corner \NC \NR
+\NC lrcorner \NC lower right corner \NC \NR
+\NC urcorner \NC upper right corner \NC \NR
+\NC ulcorner \NC upper left corner \NC \NR
+\NC center \NC intersection of the diagonals \NC \NR
+\stoptabulate
+
+If we want to typeset text inside this circle, we need to know where a line
+starts and ends. Given that lines are horizontal and straight, we therefore need
+to calculate the intersection points of the lines and the path. As a first step,
+we calculate the top and bottom of the path and after that we split off the left
+and right path.
+
+\startbuffer
+\startuseMPgraphic{text split}
+ pair t, b ; path l, r ;
+
+ t := (ulcorner p -- urcorner p) intersectionpoint p ;
+ b := (llcorner p -- lrcorner p) intersectionpoint p ;
+
+ l := p cutbefore t ; l := l cutafter b ;
+ r := p cutbefore b ; r := r cutafter t ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The \type {intersectionpoint} macro returns the point where two paths cross. If
+the paths don't cross, an error is reported, when the paths cross more times,
+just one point is returned. The \type {cutafter} and \type {cutbefore} commands
+do as their names say and return a path.
+
+In the \type {text split} code fragment, \type {t} and \type {b} are the top
+points of the main path, while \type {l} and \type {r} become the left and right
+half of path \type {p}.
+
+We now draw the original path using a thick pen and both halves with a thinner
+pen on top of the original. The arrows show the direction.
+
+\startbuffer
+\startuseMPgraphic{text draw}
+ draw p withpen pencircle scaled 3pt withcolor red ;
+ drawarrow l withpen pencircle scaled 1pt withcolor green ;
+ drawarrow r withpen pencircle scaled 1pt withcolor blue ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We use \type {\includeMPgraphic} to assemble the components:
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text path}
+ \includeMPgraphic{text split}
+ \includeMPgraphic{text draw}
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This graphic is typeset with \type {\useMPgraphic{text}}:
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+Before we are going to use them, we define some variables that specify the text.
+We use a baseline distance of 8~points. The part of the line above the baseline
+is 7.2~points, while the (maximum) depth is 2.8~points. These ratios are the ones
+we use in \CONTEXT. Because we don't want the text to touch the circle so we
+define an offset too.
+
+\startbuffer
+\startuseMPgraphic{text vars}
+ baselineskip := 8pt ;
+ strutheight := (7.2/10) * baselineskip ;
+ strutdepth := (2.8/10) * baselineskip ;
+ offset := baselineskip/2 ;
+ topskip := strutheight ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We more or less achieve the offset by scaling the path. In doing so, we use the
+width and height, which we call \type {hsize} and \type {vsize}, thereby
+conforming to the \TEX\ naming scheme.
+
+First we calculate both dimensions from the bounding box of the path. Next we
+down scale the path to compensate for the offset. When done, we recalculate the
+dimensions.
+
+\startbuffer
+\startuseMPgraphic{text move}
+ pair t, b ; path q, l, r ;
+
+ hsize := xpart lrcorner p - xpart llcorner p ;
+ vsize := ypart urcorner p - ypart lrcorner p ;
+
+ q := p xscaled ((hsize-2offset)/hsize)
+ yscaled ((vsize-2offset)/vsize) ;
+
+ hsize := xpart lrcorner q - xpart llcorner q ;
+ vsize := ypart urcorner q - ypart lrcorner q ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startuseMPgraphic{text split}
+ t := (ulcorner q -- urcorner q) intersectionpoint q ;
+ b := (llcorner q -- lrcorner q) intersectionpoint q ;
+
+ l := q cutbefore t ; l := l cutafter b ;
+ r := q cutbefore b ; r := r cutafter t ;
+\stopuseMPgraphic
+\stopbuffer
+
+We adapt the \type {text split} code to use the reduced path
+instead of the original.
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startuseMPgraphic{text draw}
+ drawarrow p withpen pencircle scaled 1pt withcolor red ;
+ draw t withpen pencircle scaled 2pt ;
+ draw b withpen pencircle scaled 2pt ;
+ drawarrow l withpen pencircle scaled 1pt withcolor green ;
+ drawarrow r withpen pencircle scaled 1pt withcolor blue ;
+\stopuseMPgraphic
+\stopbuffer
+
+In order to test what we have reached so far, we draw the original path, the left
+and right part of the reduced path, and both the top and bottom point.
+
+\typebuffer \getbuffer
+
+Again we use \type {\includeMPgraphic} to combine the
+components into a graphic.
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text path} \includeMPgraphic{text vars}
+ \includeMPgraphic{text move} \includeMPgraphic{text split}
+ \includeMPgraphic{text draw}
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Then we use \type {\useMPgraphic{text}} to call up the picture.
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+The offset is not optimal. Note the funny gap at the top. We could try to fix
+this, but there is a better way to optimize both paths.
+
+We lower the top edge of \type {q}'s bounding box by \type {topskip}, then cut
+any part of the left and right pieces of \type {q} that lie above it. Similarly,
+we raise the bottom edge and cut off the pieces that fall below this line.
+
+\startbuffer
+\startuseMPgraphic{text cutoff}
+ path tt, bb ;
+
+ tt := (ulcorner q -- urcorner q) shifted (0,-topskip) ;
+ bb := (llcorner q -- lrcorner q) shifted (0,strutdepth) ;
+
+ l := l cutbefore (l intersectionpoint tt) ;
+ l := l cutafter (l intersectionpoint bb) ;
+ r := r cutbefore (r intersectionpoint bb) ;
+ r := r cutafter (r intersectionpoint tt) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Because we use \type {\includeMPgraphic} to construct the graphic, we can
+redefine \type {text draw} to show the result of this effort.
+
+\startbuffer
+\startuseMPgraphic{text draw}
+ drawarrow p withpen pencircle scaled 1pt withcolor red ;
+ drawarrow l withpen pencircle scaled 1pt withcolor green ;
+ drawarrow r withpen pencircle scaled 1pt withcolor blue ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The \type {text} graphic now becomes:
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text path} \includeMPgraphic{text vars}
+ \includeMPgraphic{text move} \includeMPgraphic{text split}
+ \includeMPgraphic{text cutoff} \includeMPgraphic{text draw}
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Or, as graphic:
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+We are now ready for an attempt to calculate the shape of the text. For each
+line, we have to calculate the left and right intersection points, and since a
+line has a height and depth, we have to determine which part touches first.
+
+\startbuffer
+\startuseMPgraphic{text calc}
+ vardef found_point (expr lin, pat, sig) =
+ pair a, b ;
+ a := pat intersection_point (lin shifted (0,strutheight)) ;
+ if intersection_found :
+ a := a shifted (0,-strutheight) ;
+ else :
+ a := pat intersection_point lin ;
+ fi ;
+ b := pat intersection_point (lin shifted (0,-strutdepth)) ;
+ if intersection_found :
+ if sig :
+ if xpart b > xpart a : a := b shifted (0,strutdepth) fi ;
+ else :
+ if xpart b < xpart a : a := b shifted (0,strutdepth) fi ;
+ fi ;
+ fi ;
+ a
+ enddef ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Instead of using \METAPOST's \type {intersectionpoint} macro, we use one that
+comes with \CONTEXT. That way we don't get an error message when no point is
+found, and can use a boolean flag to take further action. Since we use a \type
+{vardef}, all calculations are hidden and the~\type {a} at the end is returned,
+so that we can use this macro in an assignment. The \type {sig} variable is used
+to distinguish between the beginning and end of a line (the left and right
+subpath).
+
+\startbuffer
+\startuseMPgraphic{text step}
+ path line; pair lll, rrr ;
+
+ for i=topskip step baselineskip until vsize :
+
+ line := (ulcorner q -- urcorner q) shifted (0,-i) ;
+
+ lll := found_point(line,l,true ) ;
+ rrr := found_point(line,r,false) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Here we divide the available space in lines. The first line starts at \type
+{strutheight} from the top.
+
+We can now finish our graphic by visualizing the lines. Both the height and depth
+of the lines are shown.
+
+\startbuffer
+\startuseMPgraphic{text line}
+ fill (lll--rrr--rrr shifted (0,strutheight)--lll
+ shifted (0,strutheight)--cycle) withcolor .5white ;
+ fill (lll--rrr--rrr shifted (0,-strutdepth)--lll
+ shifted (0,-strutdepth)--cycle) withcolor .7white ;
+ draw lll withpen pencircle scaled 2pt ;
+ draw rrr withpen pencircle scaled 2pt ;
+ draw (lll--rrr) withpen pencircle scaled .5pt ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{text done}
+ endfor ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The result is still a bit disappointing.
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text path} \includeMPgraphic{text vars}
+ \includeMPgraphic{text move} \includeMPgraphic{text split}
+ \includeMPgraphic{text cutoff} \includeMPgraphic{text draw}
+ \includeMPgraphic{text calc} \includeMPgraphic{text step}
+ \includeMPgraphic{text line} \includeMPgraphic{text done}
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+In order to catch the overflow at the bottom, we need to change the \type
+{for}||loop a bit, so that the number of lines does not exceed the available
+space. The test that surrounds the assignment of \type {vvsize} makes sure that
+we get better results when we (on purpose) take a smaller height.
+
+\startbuffer
+\startuseMPgraphic{text step}
+ path line; pair lll, rrr ; numeric vvsize ;
+
+ if (strutheight+strutdepth<baselineskip) :
+ vvsize := vsize ;
+ else :
+ vvsize := (vsize div baselineskip) * baselineskip ;
+ fi ;
+
+ for i=topskip step baselineskip until vvsize :
+
+ line := (ulcorner q -- urcorner q) shifted (0,-i) ;
+
+ lll := found_point(line,l,true ) ;
+ rrr := found_point(line,r,false) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+We can manipulate the heigth and depth of the lines to give different (and maybe
+better) results.
+
+\startbuffer
+\startuseMPgraphic{text vars}
+baselineskip := 8pt ;
+strutheight := 4pt ;
+strutdepth := 2pt ;
+offset := 4pt ;
+topskip := 3pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+This kind of graphic trickery in itself is not enough to get \TEX\ into
+typesetting within the bounds of a closed curve. Since \METAPOST\ can write
+information to a file, and \TEX\ can read such a file, a natural way to handle
+this is to let \METAPOST\ write a \type {\parshape} specification.
+
+\startbuffer
+\startuseMPgraphic{text macro}
+ def provide_parshape (expr p, offset, baselineskip,
+ strutheight, strutdepth, topskip) =
+
+ \includeMPgraphic{text move}
+ \includeMPgraphic{text split}
+ \includeMPgraphic{text cutoff}
+ \includeMPgraphic{text draw}
+ \includeMPgraphic{text calc}
+ \includeMPgraphic{text loop}
+ \includeMPgraphic{text save}
+
+ enddef ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We have to adapt the for||loop to register the information about the lines. After
+the loop we write those values to a file using another loop.
+
+\startbuffer
+\startuseMPgraphic{text loop}
+ path line; pair lll, rrr ; numeric vvsize, n ; n := 0 ;
+
+ if (strutheight+strutdepth<baselineskip) :
+ vvsize := vsize ;
+ else :
+ vvsize := (vsize div baselineskip) * baselineskip ;
+ fi ;
+
+ for i=topskip step baselineskip until vvsize :
+
+ line := (ulcorner q -- urcorner q) shifted (0,-i) ;
+
+ lll := found_point(line,l,true ) ;
+ rrr := found_point(line,r,false) ;
+
+ n := n + 1 ;
+
+ indent[n] := abs(xpart lll - xpart llcorner q) ;
+ width[n] := abs(xpart rrr - xpart lll) ;
+
+ endfor ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{text save}
+ write "\parshape " & decimal n to "mfun-mp-data.txt" ;
+ for i=1 upto n:
+ write decimal indent[i]&"bp " &
+ decimal width[i]&"bp " to "mfun-mp-data.txt" ;
+ endfor ;
+ write EOF to "mfun-mp-data.txt" ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We can call this macro using the part we used in the previous examples.
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text macro}
+
+ path p ; p := ((0,1)..(-1,0)..(1,0)--cycle) scaled 65pt ;
+
+ provide_parshape
+ (p, % shape path
+ .5*\baselinedistance, % offset
+ \baselinedistance, % distance between lines
+ \strutheight, % height of a line
+ \strutdepth, % depth of a line
+ \strutheight) ; % height of first line
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+After we called \type {\useMPgraphic{text}}, the resulting file looks as follows.
+You can call up this file by its anonymous name \type {\MPdatafile}, since this
+macro gets the value of the graphic at hand.
+
+\startnointerference
+ \useMPgraphic{text}
+\stopnointerference
+
+\typefile{mfun-mp-data.txt}
+
+% \blank{\em todo: mp data file}\blank
+% \writestatus{!!!!}{todo: mp data file}
+
+So, reading in this file at the start of a paragraph will setup \TEX\ to follow
+this shape.
+
+The final implementation is a bit more complicated since it takes care of paths
+that are not centered around the origin and don't start at the top point. We
+achieve this by moving the path to the center:
+
+\starttyping
+cp := center p ; q := p shifted - cp ;
+\stoptyping
+
+The arbitrary starting point is taken care of by a slightly more complicated path
+cutter. First we make sure that the path runs counterclockwise.
+
+\starttyping
+if xpart directionpoint t of q < 0 : q := reverse q fi ;
+\stoptyping
+
+Knowing this, we can split the path in two, using a slightly different splitter:
+
+\starttyping
+l := q cutbefore t ;
+l := l if xpart point 0 of q < 0 : & q fi cutafter b ;
+r := q cutbefore b ;
+r := r if xpart point 0 of q > 0 : & q fi cutafter t ;
+\stoptyping
+
+As always, when implementing a feature like this, some effort goes into a proper
+user interface. In doing so, we need some \TEX\ trickery that goes beyond this
+text, like collecting text and splitting of the part needed. Also, we want to be
+able to handle multiple shapes at once, like the next example demonstrates.
+
+\stopsection
+
+\startsection[title={Libraries}]
+
+\index{graphics+libraries}
+
+The macro discussed in the previous section is included in one of the \METAPOST\
+libraries, so we first have to say:
+
+\startbuffer
+\useMPlibrary[txt]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+We define four shapes. They are not really beautiful, but they demonstrate what
+happens in border cases. For instance, too small first lines are ignored. First
+we define a circle. Watch how the dimensions are set in the graphic. The
+arguments passed to \type {build_parshape} are: path, an offset, an additional
+horizontal and vertical displacement, the baseline distance, the height and depth
+of the line, and the height of the first line (topskip in \TEX\ terminology). The
+height and depth of a line are often called strut height and depth, with a strut
+being an invisible character with maximum dimensions.
+
+\startbuffer
+\startuseMPgraphic{test 1}
+ path p ; p := fullcircle scaled 6cm ;
+
+ build_parshape(p,6pt,0,0,\baselinedistance,
+ \strutheight,\strutdepth,\strutheight) ;
+
+ draw p withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The second shape is a diamond. This is a rather useless shape, unless the text
+suits the small lines at the top and bottom.
+
+\startbuffer
+\startuseMPgraphic{test 2}
+ path p ; p := fullsquare rotated 45 scaled 5cm ;
+
+ build_parshape(p,6pt,0,0,\baselinedistance,
+ \strutheight,\strutdepth,\strutheight) ;
+
+ draw p withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The third and fourth shape demonstrate that providing a suitable offset is not
+always trivial.
+
+\startbuffer
+\startuseMPgraphic{test 3}
+ numeric w, h ; w := h := 6cm ;
+ path p ; p := (.5w,h) -- (0,h) -- (0,0) -- (w,0) &
+ (w,0) .. (.75w,.5h) .. (w,h) & (w,h) -- cycle ;
+
+ build_parshape(p,6pt,0,0,\baselinedistance,
+ \strutheight,\strutdepth,\strutheight) ;
+
+ draw p withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Contrary to the first three shapes, here we use a different path for the
+calculations and the drawing. Watch carefully! If, instead of an offset, we pass
+a path, \METAPOST\ is able to calculate the right dimensions and offsets. This is
+needed, since we need these later on.
+
+\startbuffer
+\startuseMPgraphic{test 4}
+ numeric w, h, o ;
+
+ def shape = (o,o) -- (w-o,o) & (w-o,o) .. (.75w-o,.5h) ..
+ (w-2o,h-o) & (w-2o,h-o) -- (o,h-o) -- cycle
+ enddef ;
+
+ w := h := 6cm ; o := 6pt ; path p ; p := shape ;
+ w := h := 6cm ; o := 0pt ; path q ; q := shape ;
+
+ build_parshape(p,q,6pt,6pt,\baselinedistance,
+ \strutheight,\strutdepth,\strutheight) ;
+
+ draw q withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Since we also want these graphics as backgrounds, we define them as overlays. If
+you don't want to show the graphic, you may omit this step.
+
+\startbuffer
+\defineoverlay[test 1][\useMPgraphic{test 1}]
+\defineoverlay[test 2][\useMPgraphic{test 2}]
+\defineoverlay[test 3][\useMPgraphic{test 3}]
+\defineoverlay[test 4][\useMPgraphic{test 4}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+As text, we use a quote from Douglas R.~Hofstadter's book \quotation {Metamagical
+Themas, Questing for the Essence of Mind and Pattern}. Watch how we pass a list
+of shapes.
+
+\startbuffer[text]
+\startshapetext[test 1,test 2,test 3,test 4]
+ \forgetall % as it says
+ \setupalign[verytolerant,stretch,normal]%
+ \input douglas % Douglas R. Hofstadter
+\stopshapetext
+\stopbuffer
+
+\typebuffer[text]
+
+Finally we combine text and shapes. Since we also want a background, we use \type
+{\framed}. The macros \type {\parwidth} and \type {\parheight} are automatically
+set to the current shape dimensions. The normal result is shown in \in {figure}
+[fig:shapes].
+
+\startbuffer[shapes]
+\startbuffer
+\setupframed
+ [offset=overlay,align=normal,frame=off,
+ width=\parwidth,height=\parheight]
+\startcombination[2*2]
+ {\framed[background=test 1]{\getshapetext}} {test 1}
+ {\framed[background=test 2]{\getshapetext}} {test 2}
+ {\framed[background=test 3]{\getshapetext}} {test 3}
+ {\framed[background=test 4]{\getshapetext}} {test 4}
+\stopcombination
+\stopbuffer
+\stopbuffer
+
+\typebuffer[shapes]
+
+\getbuffer[shapes]
+
+By using a buffer we keep \type {\placefigure} readable.
+
+\startbuffer[a]
+\placefigure
+ [here][fig:shapes]
+ {A continuous text, typeset in a non||standard shape,
+ spread over four areas, and right aligned.}
+ {\getbuffer}
+\stopbuffer
+
+\startbuffer[b]
+\placefigure
+ [here][fig:shapes]
+ {A continuous text, typeset in a non||standard shape,
+ spread over four areas.}
+ {\scale[factor=max,height=.9\textheight]{\getbuffer}}
+\stopbuffer
+
+\typebuffer[a]
+
+\doifmodeelse{screen}{\getbuffer[text,b]}{\getbuffer[text,a]}
+
+The traced alternative is shown in \in {figure} [fig:traced shapes]. This one is
+defined as:
+
+\startbuffer[a]
+\placefigure
+ [here][fig:traced shapes]
+ {A continuous text, typeset in a non||standard shape,
+ spread over four areas (tracing on).}
+ {\startMPinclusions
+ boolean trace_parshape ; trace_parshape := true ;
+ \stopMPinclusions
+ \getbuffer}
+\stopbuffer
+
+\startbuffer[b]
+\placefigure
+ [here][fig:traced shapes]
+ {A continuous text, typeset in a non||standard shape,
+ spread over four areas (tracing on).}
+ {\startMPinclusions
+ boolean trace_parshape ; trace_parshape := true ;
+ \stopMPinclusions
+ \scale[factor=max,height=.9\textheight]{\getbuffer}}
+\stopbuffer
+
+\typebuffer[a]
+
+\doifmodeelse{screen}{\getbuffer[text,b]}{\getbuffer[text,a]}
+
+% {\em This mechanism is still somewhat experimental and will be optimized and
+% extended with name spaces and more.}
+
+\blank
+
+We can combine all those tricks, although the input is somewhat fuzzy. First we
+define a quote typeset in a circular paragraph shape.
+
+\startbuffer[shape]
+\startuseMPgraphic{center}
+ build_parshape(fullcircle scaled 8cm,0,0,0,\baselinedistance,
+ \strutheight,\strutdepth,\strutheight) ;
+\stopuseMPgraphic
+
+\startshapetext[center]
+ \input douglas
+\stopshapetext
+
+\defineoverlay[center][\useMPgraphic{center}]
+\stopbuffer
+
+\typebuffer[shape]
+
+We will surround this text with a circular line, that we define as follows. By
+using a buffer we keep things organized.
+
+\startbuffer
+\startbuffer[circle]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := reverse fullcircle
+ rotatedaround(origin,90)
+ xscaled \overlaywidth yscaled \overlayheight ;
+ drawoptions (withcolor .625red) ;
+\stopuseMPgraphic
+
+\followtokens
+ {This is just a dummy text, kerned by \TeX\ and typeset
+ in a circle using \MetaPost.\quad}
+\stopbuffer
+
+\defineoverlay[edge][{\getbuffer[circle]}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The text and graphics come together in a framed text:
+
+\startbuffer
+\startbuffer[quote]
+\framed
+ [offset=24pt,
+ background=edge,
+ frame=off,
+ backgroundoffset=-18pt]
+ {\getshapetext}
+\stopbuffer
+
+\placefigure
+ {One more time Hofstadter's quotation (normal).}
+ {\getbuffer[shape,quote]}
+
+\placefigure
+ {One more time Hofstadter's quotation (traced).}
+ {\startMPinclusions
+ boolean TraceRot ; TraceRot := true ;
+ \stopMPinclusions
+ \getbuffer[shape,quote]}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+% {\em Here also, I will rewrite things a bit so that we can avoid \type
+% {\startMPdrawing} outside the macro, and thereby avoid problems. I can also add
+% the maps cdrom cover as example.}
+
+\stopsection
+
+% \startsection[title={Visualizing \TEX}]
+%
+% The next example is a bit out of place in this manual, but nevertheless
+% demonstrates how one can use \METAPOST\ to get insight in what \TEX\ is doing
+% inside.
+%
+% The author of \PDFTEX, \THANH, has extended the paragraph builder with a
+% provision for protruding characters and glyphs substitution, also known as {\it
+% hz} (which stands for Hermann Zapf). The {\it hz} optimization involves an
+% additional pass over the lines and|/|or paragraph, in order to determine how
+% inconsistency in gaps can be reduced by substituting an \quote {\scale [sx=1.01]
+% {a}} by an \quote {\scale [sx=5] {a}} or \quote {\scale [sx=.5] {a}}. In \in
+% {figure} [fig:hz] you can find the visualization in action. By means of colors we
+% indicate in what way glyphs are substituted by slightly larger or smaller values.
+% More details on how the {\it hz} optimization works can be found in \THANH's
+% thesis.
+%
+% \placefigure
+% [page][fig:hz]
+% {When we feed \TEX\ code into \METAPOST\ and back, we
+% can visualize {\it hz}||optimization in a colorful way.}
+% {\doifmodeelse{screen}
+% {\externalfigure[mfun-hzs.pdf][height=.8\textheight]}
+% {\externalfigure[mfun-hzp.pdf][height=.8\textheight]}}
+%
+% In order to avoid a complicated discussion about how to set up \PDFTEX\ to use
+% {\it hz} |<|this can best be left over to the macro package that you use|>| we
+% will illustrate the method behind this kind of visualizations in a more simple
+% case.
+%
+% When you include a \METAPOST\ graphic in \PDFTEX, the output produced by
+% \METAPOST\ is interpreted by a bunch of macros and converted into raw \PDF\ code.
+% In the process special extensions, like shading, transparency, graphic inclusion,
+% are taken care of. When the converter encounters a font inclusion directive,
+% i.e.\ the \POSTSCRIPT\ \type {fshow} operator, it uses the \TEX\ font handler to
+% take care of the font. A benefit of this approach is that \TEX\ and \METAPOST\
+% share the same font resources and therefore the inclusion is done in the way
+% expected.
+%
+% The low level macro that takes care of the font inclusion provides a couple of so
+% called hooks, that permit us to do additional manipulations with the character
+% sequences that are encountered.
+%
+% \startbuffer[demo]
+% draw
+% btex \definedfont[cmr10]%
+% Combine the power of \TeX\ and \MetaPost !
+% etex scaled 2 ;
+% \stopbuffer
+%
+% \typebuffer[demo]
+%
+% When processed, this gives the graphic:
+%
+% \startlinecorrection[blank]
+% \processMPbuffer[demo]
+% \stoplinecorrection
+%
+% The result is not spectacular, and there is no indication that \METAPOST\ has
+% been in action. The following line of code sets the hook \type {\MPfshowcommand}
+% |<|this commands takes one argument|>| to produce a ruled horizontal box.
+%
+% \startbuffer
+% \let\MPfshowcommand\ruledhbox
+% \stopbuffer
+%
+% \typebuffer
+%
+% \startlinecorrection[blank]
+% \getbuffer \processMPbuffer[demo]
+% \stoplinecorrection
+%
+% If you watch closely, you will see that the ruled boxes contain one or more
+% characters (or more precise glyphs). This is a result from \TEX\ explicitely
+% kerning characters.
+%
+% A second hook is provided in the macro that takes care of the font switch. This
+% command is defined as follows:
+%
+% \starttyping
+% \def\setMPfshowfont#1#2%
+% {\font\temp=#1\space at #2\relax\temp}
+% \stoptyping
+%
+% The first argument is the raw font name, and the second argument specifies the
+% desired size. If we want to see what fonts are involved, we can redefine the
+% hooks as follows.
+%
+% \starttyping
+% \def\setMPfshowfont#1#2%
+% {\message{[using #1 at #2 in mp graphic]}%
+% \font\temp=#1\space at #2\relax\temp}
+% \stoptyping
+%
+% It happens that two fonts are used: \type {cmr10} and \type {logo10}. Once we
+% know this, we can apply some magic: we set the color to the fontname and define a
+% couple of colors that match the name.
+%
+% \startbuffer
+% \definecolor [cmr10] [darkred]
+% \definecolor [logo10] [darkyellow]
+%
+% \def\setMPfshowfont#1#2%
+% {\color[#1]\font\temp=#1\space at #2\relax\temp}
+% \stopbuffer
+%
+% \typebuffer
+%
+% In the case of the \type {\it hz} examples we had to define a couple of more
+% colors, but the principle remains.
+%
+% \startlinecorrection[blank]
+% \getbuffer \processMPbuffer[demo]
+% \stoplinecorrection
+%
+% We don't expect the user to use tricks like this on a daily basis, but it
+% demonstrates that with a bit of knowlegde of the internals of \CONTEXT, you can
+% produce nice examples of typographic programming.
+%
+% \stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-titlepage-paper.tex b/doc/context/sources/general/manuals/metafun/metafun-titlepage-paper.tex
new file mode 100644
index 000000000..558e3b798
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-titlepage-paper.tex
@@ -0,0 +1,23 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\doifmode{book}{\endinput}
+
+\startcomponent mfun-titlepage-paper
+
+\environment metafun-environment
+
+\setupbackgrounds
+ [rightpage]
+ [background=title page]
+
+\startstandardmakeup
+ % title page
+\stopstandardmakeup
+
+\setupbackgrounds
+ [rightpage]
+ [background=]
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-titlepage-screen.tex b/doc/context/sources/general/manuals/metafun/metafun-titlepage-screen.tex
new file mode 100644
index 000000000..6350bdbda
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-titlepage-screen.tex
@@ -0,0 +1,30 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-titlepage-screen
+
+\environment metafun-environment
+
+\startstandardmakeup[topstate=empty]
+
+ \definefont[Big] [RegularBold*default at 60pt]
+ \definefont[Medium][RegularBold*default at 48pt]
+ \definefont[Small] [RegularBold*default at 32pt]
+ \definefont[Tiny] [RegularBold*default at 24pt]
+
+% \showstruts
+
+ \startcolor[darkyellow]
+
+ \Big METAFUN \par
+ \Tiny \setstrut \strut context mkiv \par
+ \vfill
+ \Tiny \setstrut \hfill \strut \currentdate \par
+ \Small \setstrut \hfill \strut Hans Hagen \par
+
+ \stopcolor
+
+\stopstandardmakeup
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-welcome.tex b/doc/context/sources/general/manuals/metafun/metafun-welcome.tex
new file mode 100644
index 000000000..425d15796
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-welcome.tex
@@ -0,0 +1,3502 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-welcome
+
+\environment metafun-environment
+
+\startchapter[reference=sec:welcome,title={Welcome to MetaPost}]
+
+\startintro
+
+In this chapter, we will introduce the most important \METAPOST\ concepts as well
+as demonstrate some drawing primitives and operators. This chapter does not
+replace the \METAFONT\ book or \METAPOST\ manual, both of which provide a lot of
+explanations, examples, and (dirty) tricks.
+
+As its title says, the \METAFONT\ book by Donald.\ E.\ Knuth is about fonts.
+Nevertheless, buying a copy is worth the money, because as a \METAPOST\ user you
+can benefit from the excellent chapters about curves, algebraic expressions, and
+(linear) equations. The following sections are incomplete in many aspects. More
+details on how to define your own macros can be found in both the \METAFONT\ book
+and \METAPOST\ manual, but you will probably only appreciate the nasty details if
+you have written a few simple figures yourself. This chapter will give you a
+start.
+
+A whole section is dedicated to the basic extensions to \METAPOST\ as provided by
+\METAFUN. Most of them are meant to make defining graphics like those shown in
+this document more convenient.
+
+Many of the concepts introduced here will be discussed in more detail in later
+chapters. So, you may consider this chapter to be an appetizer for the following
+chapters. If you want to get started quickly, you can safely skip this chapter
+now.
+
+\stopintro
+
+\startsection[title={Paths}]
+
+\index{paths}
+
+Paths are the building blocks of \METAPOST\ graphics. In its simplest form, a
+path is a single point.
+
+\startuseMPgraphic{axis}
+ tickstep := 1cm ; ticklength := 2mm ;
+ drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ;
+ tickstep := tickstep/2 ; ticklength := ticklength/2 ;
+ drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ;
+\stopuseMPgraphic
+
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ drawpoint "1cm,1.5cm" ;
+\stopMPcode
+\stoplinecorrection
+
+Such a point is identified by two numbers, which represent the horizontal and
+vertical position, often referred to as $x$ and $y$, or $(x,y)$. Because there
+are two numbers involved, in \METAPOST\ this point is called a pair. Its related
+datatype is therefore \type {pair}. The following statements assigns the point we
+showed previously to a pair variable.
+
+\starttyping
+pair somepoint ; somepoint := (1cm,1.5cm) ;
+\stoptyping
+
+A pair can be used to identify a point in the two dimensional coordinate space,
+but it can also be used to denote a vector (being a direction or displacement).
+For instance, \type {(0,1)} means \quote {go up}. Looking through math glasses,
+you may consider them vectors, and if you know how to deal with them, \METAPOST\
+may be your friend, since it knows how to manipulate them.
+
+You can connect points and the result is called a path. A path is a straight or
+bent line, and is not necessarily a smooth curve. An example of a simple
+rectangular path is: \footnote {In the next examples we use the debugging
+features discussed in \in {chapter} [sec:debugging] to visualize the points,
+paths and bounding boxes.}
+
+\startuseMPgraphic{path}
+ path p ;
+ p := unitsquare xyscaled (2cm,1cm) shifted (.5cm,.5cm) ;
+\stopuseMPgraphic
+
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ drawpath p ;
+\stopMPcode
+\stoplinecorrection
+
+This path is constructed out of four points:
+
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ swappointlabels := true ; drawpath p ; drawpoints p ;
+\stopMPcode
+\stoplinecorrection
+
+Such a path has both a beginning and end and runs in a certain direction:
+
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ autoarrows := true ;
+ swappointlabels := true ; drawarrowpath p ; drawpoints p ;
+\stopMPcode
+\stoplinecorrection
+
+A path can be open or closed. The previous path is an example of a closed path.
+An open path looks like this:
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,1.5cm)..(2cm,0cm) ;
+\stopuseMPgraphic
+
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ swappointlabels := true ; drawpath p ; drawpoints p ;
+\stopMPcode
+\stoplinecorrection
+
+When we close this path |<|and in a moment we will see how to do this|>| the path
+looks like:
+
+\startbuffer
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ p := p .. cycle ;
+ swappointlabels := true ; drawpath p ; drawpoints p ;
+\stopMPcode
+\stoplinecorrection
+\stopbuffer
+
+\getbuffer
+
+The open path is defined as:
+
+\starttyping
+(1cm,1cm)..(1.5cm,1.5cm)..(2cm,0cm)
+\stoptyping
+
+The \quote {double period} connector \type {..} tells \METAPOST\ that we want to
+connect the lines by a smooth curve. If you want to connect points with straight
+line segments, you should use \type {--}.
+
+Closing the path is done by connecting the first and last point, using the \type
+{cycle} command.
+
+\starttyping
+(1cm,1cm)..(1.5cm,1.5cm)..(2cm,0cm)..cycle
+\stoptyping
+
+Feel free to use \type {..} or \type {--} at any point in your path.
+
+\starttyping
+(1cm,1cm)--(1.5cm,1.5cm)..(2cm,0cm)..cycle
+\stoptyping
+
+\startuseMPgraphic{path}
+path p ; p := (1cm,1cm)--(1.5cm,1.5cm)..(2cm,0cm)..cycle ;
+\stopuseMPgraphic
+
+This path, when drawn, looks like this:
+
+\getbuffer
+
+As you can see in some of the previous examples, \METAPOST\ is capable of drawing
+a smooth curve through the three points that make up the path. We will now
+examine how this is done.
+
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ p := p .. cycle ; swappointlabels := true ;
+ drawpath p ; drawcontrollines p ; drawpoints p ; drawcontrolpoints p ;
+\stopMPcode
+\stoplinecorrection
+
+The six small points are the so called control points. These points pull their
+parent point in a certain direction. The further away such a point is, the
+stronger the pull.
+
+Each point has at most two control points. As you can see in the following
+graphic, the endpoints of a non closed curve have only one control point.
+
+\startuseMPgraphic{path}
+path p ; p := (1.5cm,1.5cm)..(2cm,0cm)..(1cm,1cm) ;
+\stopuseMPgraphic
+
+\startbuffer[path]
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ swappointlabels := true ;
+ drawpath p ; drawcontrollines p ; drawpoints p ; drawcontrolpoints p ;
+\stopMPcode
+\stoplinecorrection
+\stopbuffer
+
+\getbuffer[path]
+
+This time we used the path:
+
+\starttyping
+(1.5cm,1.5cm)..(2cm,0cm)..(1cm,1cm)
+\stoptyping
+
+When you connect points by a smooth curve, \METAPOST\ will calculate the control
+points itself, unless you specify one or more of them.
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,1.5cm)..controls (3cm,2cm)..(2cm,0cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+This path is specified as:
+
+\starttyping
+(1cm,1cm)..(1.5cm,1.5cm)..controls (3cm,2cm)..(2cm,0cm)
+\stoptyping
+
+In this path, the second and third point share a control point. Watch how the
+curve is pulled in that direction. It is possible to pull a bit less by choosing
+a different control point:
+
+\starttyping
+(1cm,1cm)..(1.5cm,1.5cm)..controls (2.75cm,1.25cm)..(2cm,0cm)
+\stoptyping
+
+Now we get:
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,1.5cm)..controls (2.75cm,1.25cm)..(2cm,0cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+We can also specify a different control point for each connecting segment.
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..controls (.5cm,2cm) and (2.5cm,2cm)..(2cm,.5cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+This path is defined as:
+
+\starttyping
+(1cm,1cm)..controls (.5cm,2cm) and (2.5cm,2cm)..(2cm,.5cm)
+\stoptyping
+
+\stopsection
+
+\startsection[title={Transformations}]
+
+\index{transformations}
+
+We can store a path in a path variable. Before we can use such a variable, we
+have to allocate its memory slot with \type {path}.
+
+\starttyping
+path p ; p := (1cm,1cm)..(1.5cm,2cm)..(2cm,0cm) ;
+\stoptyping
+
+Although we can manipulate any path in the same way, using a variable saves us
+the effort to key in a path more than once.
+
+\startuseMPgraphic{axis}
+ tickstep := 1cm ; ticklength := 2mm ;
+ drawticks unitsquare xscaled 8cm yscaled 4cm ;
+ tickstep := tickstep/2 ; ticklength := ticklength/2 ;
+ drawticks unitsquare xscaled 8cm yscaled 4cm ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,2cm)..(2cm,0cm)..cycle ;
+ path q ; q := p shifted (4cm,2cm) ;
+\stopuseMPgraphic
+
+\startbuffer[path]
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ swappointlabels := true ;
+ drawpath p ; drawcontrollines p ; drawpoints p ; drawcontrolpoints p ;
+ drawpath q ; drawcontrollines q ; drawpoints q ; drawcontrolpoints q ;
+\stopMPcode
+\stoplinecorrection
+\stopbuffer
+
+\getbuffer[path]
+
+In this graphic, the path stored in \type {p} is drawn twice, once in its
+displaced form. The displacement is defined as:
+
+\starttyping
+p shifted (4cm,2cm)
+\stoptyping
+
+In a similar fashion you can rotate a path. You can even combine shifts and
+rotations. First we rotate the path 15 degrees counter||clockwise around the
+origin.
+
+\starttyping
+p rotated 15
+\stoptyping
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,2cm)..(2cm,0cm)..cycle ;
+ path q ; q := p rotated 15 ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+This rotation becomes more visible when we also shift the path to the right by
+saying:
+
+\starttyping
+rotated 15 shifted (4cm,0cm)
+\stoptyping
+
+Now we get:
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,2cm)..(2cm,0cm)..cycle ;
+ path q ; q := p rotated 15 shifted (4cm,0cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+Note that \type {rotated 15} is equivalent to \typ {p rotatedaround (origin,
+15)}.
+
+It may make more sense to rotate the shape around its center. This can easily be
+achieved with the \type {rotatedaround} command. Again, we move the path to the
+right afterwards.
+
+\starttyping
+p rotatedaround(center p, 15) shifted (4cm,0cm)
+\stoptyping
+
+\startuseMPgraphic{axis}
+ tickstep := 1cm ; ticklength := 2mm ;
+ drawticks unitsquare xscaled 10cm yscaled 3cm ;
+ tickstep := tickstep/2 ; ticklength := ticklength/2 ;
+ drawticks unitsquare xscaled 10cm yscaled 3cm ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,2cm)..(2cm,0cm)..cycle ;
+ path q ; q := p rotatedaround(center p, 15) shifted (4cm,0cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+Yet another transformation is slanting. Just like characters can be upright or
+slanted, a graphic can be:
+
+\starttyping
+p slanted 1.5 shifted (4cm,0cm)
+\stoptyping
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,2cm)..(2cm,0cm)..cycle ;
+ path q ; q := p slanted 1.5 shifted (4cm,0cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+The slant operation's main application is in tilting fonts. The $x$||coodinates
+are increased by a percentage of their $y$||coordinate, so here every $x$ becomes
+$x+1.5y$. The $y$||coordinate is left untouched. The following table summarizes
+the most important primitive transformations that \METAPOST\ supports.
+
+\starttabulate[|lT|l|]
+\HL
+\NC \METAPOST\ code \NC mathematical equivalent \NC \NR
+\HL
+\NC (x,y) shifted (a,b) \NC $(x+a,y+b)$ \NC \NR
+\NC (x,y) scaled s \NC $(sx,sy)$ \NC \NR
+\NC (x,y) xscaled s \NC $(sx,y)$ \NC \NR
+\NC (x,y) yscaled s \NC $(x,sy)$ \NC \NR
+\NC (x,y) zscaled (u,v) \NC $(xu-yv,xv+yu)$ \NC \NR
+\NC (x,y) slanted s \NC $(x+sy,y)$ \NC \NR
+\NC (x,y) rotated r \NC $(x\cos(r)-y\sin(r),x\sin(r)+y\cos(r))$ \NC \NR
+\HL
+\stoptabulate
+
+The previously mentioned \type {rotatedaround} is not a primitive but a macro,
+defined in terms of shifts and rotations. Another transformation macro is
+mirroring, or in \METAPOST\ terminology, \type {reflectedabout}.
+
+\startbuffer[path]
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ swappointlabels := true ;
+ drawpath p ; drawpoints p ;
+ drawpath q ; drawpoints q ;
+\stopMPcode
+\stoplinecorrection
+\stopbuffer
+
+\startuseMPgraphic{path}
+ path p ; p := unitsquare scaled 2cm shifted (2cm,.5cm) ;
+ path q ; q := unitsquare scaled 2cm shifted (2cm,.5cm) reflectedabout((2.4cm,-.5),(2.4cm,3cm)) ;
+ draw (2.4cm,-.5cm)--(2.4cm,3cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+The reflection axis is specified by a pair of points. For example, in the graphic
+above, we used the following command to reflect the square about a line through
+the given points.
+
+\starttyping
+p reflectedabout((2.4cm,-.5),(2.4cm,3cm))
+\stoptyping
+
+The line about which the path is mirrored. Mirroring does not have to be parallel
+to an axis.
+
+\starttyping
+p reflectedabout((2.4cm,-.5),(2.6cm,3cm))
+\stoptyping
+
+The rectangle now becomes:
+
+\startuseMPgraphic{path}
+ path p ; p := unitsquare scaled 2cm shifted (2cm,.5cm) ;
+ path q ; q := unitsquare scaled 2cm shifted (2cm,.5cm) reflectedabout((2.4cm,-.5),(2.6cm,3cm)) ;
+ draw (2.4cm,-.5cm)--(2.6cm,3cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+\pagereference [zscaled]The table also mentions \type {zscaled}.
+
+\startuseMPgraphic{path}
+path p ; p := unitsquare scaled (1cm) shifted (1cm,.5cm) ;
+path q ; q := unitsquare scaled (1cm) zscaled (2,.5) shifted (1cm,.5cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+A \type {zscaled} specification takes a vector as argument:
+
+\starttyping
+p zscaled (2,.5)
+\stoptyping
+
+The result looks like a combination of scaling and rotation, and conforms to the
+formula in the previous table.
+
+Transformations can be defined in terms of a transform matrix. Such a matrix is
+stored in a transform variable. For example:
+
+\starttyping
+transform t ; t := identity scaled 2cm shifted (4cm,1cm) ;
+\stoptyping
+
+We use the associated keyword \type {transformed} to apply this matrix to a path
+or picture.
+
+\starttyping
+p transformed t
+\stoptyping
+
+In this example we've taken the \type {identity} matrix as starting point but you
+can use any predefined transformation. The identity matrix is defined in such a
+way that it scales by a factor of one in both directions and shifts over the
+zero||vector.
+
+Transform variables can save quite some typing and may help you to force
+consistency when many similar transformations are to be done. Instead of changing
+the scaling, shifting and other transformations you can then stick to just
+changing the one transform variable.
+
+\stopsection
+
+\startsection[title={Constructing paths}]
+
+\index{paths}
+
+In most cases, a path will have more points than the few shown here. Take for
+instance a so called {\em super ellipse}.
+
+\startlinecorrection[blank]
+\startMPcode
+path p ; p := fullsquare xyscaled (5cm,3cm) superellipsed .85 ;
+drawpath p ; drawpoints p ;
+visualizepaths ; draw p shifted (6cm,0cm) withcolor .625yellow ;
+\stopMPcode
+\stoplinecorrection
+
+These graphics provide a lot of information. In this picture the crosshair in the
+center is the {\em origin} and the dashed rectangle is the {\em bounding box} of
+the super ellipse. The bounding box specifies the position of the graphic in
+relation to the origin as well as its width and height.
+
+In the graphic on the right, you can see the points that make up the closed path
+as well as the control points. Each point has a number with the first point
+numbered zero. Because the path is closed, the first and last point coincide.
+
+\startuseMPgraphic{axis}
+ tickstep := 1cm ; ticklength := 2mm ;
+ drawticks unitsquare xscaled 8cm yscaled 3cm ;
+ tickstep := tickstep/2 ; ticklength := ticklength/2 ;
+ drawticks unitsquare xscaled 8cm yscaled 3cm ;
+\stopuseMPgraphic
+
+\startbuffer
+\startlinecorrection[blank]
+\startMPcode
+ string tmp ; defaultfont := "\truefontname{Mono}" ;
+ \includeMPgraphic{axis}
+ \includeMPgraphic{points}
+ \includeMPgraphic{path}
+ label.lft(verbatim(tmp),(14.5cm,2.5cm)) ;
+ drawwholepath scantokens(tmp) ;
+\stopMPcode
+\stoplinecorrection
+\stopbuffer
+
+We've used the commands \type {..} and \type {--} as path connecting directives.
+In the next series of examples, we will demonstrate a few more. However, before
+doing that, we define a few points, using the predefined \type {z} variables.
+
+\startuseMPgraphic{points}
+ z0 = (0.5cm,1.5cm) ; z1 = (2.5cm,2.5cm) ;
+ z2 = (6.5cm,0.5cm) ; z3 = (3.0cm,1.5cm) ;
+\stopuseMPgraphic
+
+\starttyping
+z0 = (0.5cm,1.5cm) ; z1 = (2.5cm,2.5cm) ;
+z2 = (6.5cm,0.5cm) ; z3 = (3.0cm,1.5cm) ;
+\stoptyping
+
+Here \type {z1} is a short way of saying \type {(x1,y1)}. When a \type {z}
+variable is called, the corresponding \type {x} and \type {y} variables are
+available too. Later we will discuss \METAPOST\ capability to deal with
+expressions, which are expressed using an \type {=} instead of \type {:=}. In
+this case the expression related to \type {z0} is expanded into:
+
+\starttyping
+z0 = (x0,y0) = (0.5cm,1.5cm) ;
+\stoptyping
+
+But for this moment let's forget about their expressive nature and simply see
+them as points which we will now connect by straight line segments.
+
+\startuseMPgraphic{path}
+ tmp := "z0--z1--z2--z3--cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+The smooth curved connection, using \type {..} looks like:
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2..z3..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+If we replace the \type {..} by \type {...}, we get a tighter path.
+
+\startuseMPgraphic{path}
+ tmp := "z0...z1...z2...z3...cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Since there are \type {..}, \type {--}, and \type {...}, it will be no surprise
+that there is also \type {---}.
+
+\startuseMPgraphic{path}
+ tmp := "z0---z1---z2---z3---cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+If you compare this graphic with the one using \type {--} the result is the same,
+but there is a clear difference in control points. As a result, combining \type
+{..} with \type {--} or \type {---} makes a big difference. Here we get a
+non||smooth connection between the curves and the straight line.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2--z3..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+As you can see in the next graphic, when we use \type {---}, we get a smooth
+connection between the straight line and the rest of the curve.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2---z3..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+So far, we have joined the four points as one path. Alternatively, we can
+constrict subpaths and connect them using the ampersand symbol, \type {&}.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2 & z2..z3..z0 & cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+So far we have created a closed path. Closing is done by \type {cycle}. The
+following path may look closed but is in fact open.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2..z3..z0" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Only a closed path can be filled. The closed alternative looks as follows. We
+will see many examples of filled closed paths later on.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2..z3..z0..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Here the final \type {..} will try to make a smooth connection, but because we
+already are at the starting point, this is not possible. However, the \type
+{cycle} command can automatically connect to the first point. Watch the
+difference between the previous and the next path.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2..z3..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+It is also possible to combine two paths into one that don't have common head and
+tails. First we define an open path:
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+The following path is a closed one, and crosses the previously shown path.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z3..z1..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+With \type {buildcycle} we can combine two paths into one.
+
+\startuseMPgraphic{path}
+ tmp := "buildcycle(z0..z1..z2 , z0..z3..z1..cycle)" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+We would refer readers to the \METAFONT\ book and the \METAPOST\ manual for an
+explanation of the intricacies of the \type {buildcycle} command. It is an
+extremely complicated command, and there is just not enough room here to do it
+justice. We suffice with saying that the paths should cross at least once before
+the \type {buildcycle} command can craft a combined path from two given paths. We
+encourage readers to experiment with this command.
+
+In order to demonstrate another technique of joining paths, we first draw a few
+strange paths. The last of these three graphics demonstrates the use of \type
+{softjoin}.
+
+\startuseMPgraphic{path}
+ tmp := "z0--z1..z2--z3" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2--z3" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Watch how \type {softjoin} removes a point in the process of smoothing a
+connection. The smoothness is accomplished by adapting the control points of the
+neighbouring points in the appropriate way.
+
+\startuseMPgraphic{path}
+ tmp := "z0--z1 softjoin z2--z3" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Once a path is known, you can cut off a slice of it. We will demonstrate a few
+alternative ways of doing so, but first we show one more time the path that we
+take as starting point.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2..z3..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+This path is made up out of five points, where the cycle duplicates the first
+point and connects the loose ends. The first point has number zero.
+
+We can use these points in the \type {subpath} command, which takes two
+arguments, specifying the range of points to cut of the path specified after the
+keyword \type {of}.
+
+\startuseMPgraphic{path}
+ tmp := "subpath(2,4) of (z0..z1..z2..z3..cycle)" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+The new (sub|)|path is a new path with its own points that start numbering at
+zero. The next graphic shows both the original and the subpath from point 1
+upto~3.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..z2..z3..cycle)" ;
+ sub := "subpath(1,3)" ;
+\stopuseMPgraphic
+
+\startbuffer[sub]
+\startlinecorrection[blank]
+\startMPcode
+ string tmp, sub ; defaultfont := "\truefontname{Mono}" ;
+ \includeMPgraphic{axis}
+ \includeMPgraphic{points}
+ \includeMPgraphic{path}
+ label.lft(verbatim(tmp),(14.5cm,2.5cm)) ;
+ label.lft(verbatim(sub),(14.5cm,2.0cm)) ;
+ sub := sub & " of " & tmp ;
+ path p ; p := scantokens(tmp) ;
+ path q ; q := scantokens(sub) ;
+ drawwholepath p ; swappointlabels := true ;
+ drawpath q withcolor .625yellow ;
+ drawpoints q withcolor .625red ;
+ drawpointlabels q ;
+\stopMPcode
+\stoplinecorrection
+\stopbuffer
+
+\getbuffer[sub]
+
+In spite of what you may think, a point is not fixed. This is why in \METAPOST\ a
+point along a path is officially called a time. The next example demonstrates
+that we can specify any time on the path.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..z2..z3..cycle)" ;
+ sub := "subpath(2.45,3.85)" ;
+\stopuseMPgraphic
+
+\getbuffer[sub]
+
+Often we want to take a slice starting at a specific point. This is provided by
+\type {cutafter} and its companion \type {cutbefore}. Watch out, this time we use
+a non||cyclic path.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..z2..z3)" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+When you use \type {cutafter} and \type {cutbefore} it really helps if you know
+in what direction the path runs.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..z2..z3) cutafter z2" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..z2..z3) cutbefore z1" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Here is a somewhat silly way of accomplishing the same thing, but it is a nice
+introduction to \METAPOST's \type {point} operation. In order to use this command
+effectively, you need to know how many points make up the path.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..z2..z3) cutbefore point 2 of (z0..z1..z2..z3)" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+As with \type {subpath}, you can use fractions to specify the time on the path,
+although the resulting point is not necessarily positioned linearly along the
+curve.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..z2..z3) cutbefore point 2.5 of (z0..z1..z2..z3)" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+If you really want to know the details of where fraction points are positioned,
+you should read the \METAFONT\ book and study the source of \METAFONT\ and
+\METAPOST, where you will find the complicated formulas that are used to
+calculate smooth curves.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Like any closed path, this path has points where the tangent is horizontal or
+vertical. Early in this chapter we mentioned that a pair (or point) can specify a
+direction or vector. Although any angle is possible, we often use one of four
+predefined directions:
+
+\starttabulate[|Tl|Tl|]
+\HL
+\NC right \NC ( 1, 0) \NC \NR
+\NC up \NC ( 0, 1) \NC \NR
+\NC left \NC (-1, 0) \NC \NR
+\NC down \NC ( 0,-1) \NC \NR
+\HL
+\stoptabulate
+
+We can use these predefined directions in combination with \type {directionpoint}
+and \type {cutafter}. The following command locates the first point on the path
+that has a tangent that points vertically upward, and then feeds this point to
+the \type {cutafter} command.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..cycle) cutafter directionpoint up of (z0..z1..cycle)" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+You are not limited to predefined direction vectors. You can provide a pair to
+indicate a direction. In the next example we use the following cyclic path:
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Using \type {( )} is not mandatory but makes the expression look less
+complicated.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..cycle) cutafter directionpoint (1,1) of (z0..z1..cycle)" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+We will apply these commands in the next chapters, but first we will finish our
+introduction in \METAPOST. We have seen how a path is constructed and what can be
+done with it. Now it is time to demonstrate how such a path is turned into a
+graphic.
+
+\stopsection
+
+\startsection[title={Angles}]
+
+\index{angles}
+\index{rotation}
+
+You can go from angles to vectors and vice versa using the \type {angle} and
+\type {dir} functions. The next example show both in action.
+
+\startbuffer
+pickup pencircle scaled 2mm ;
+draw (origin -- dir(45) -- dir(0) -- cycle)
+ scaled 3cm withcolor .625red ;
+draw (origin -- dir(angle(1,1)) -- dir(angle(1,0)) -- cycle)
+ scaled 3cm shifted (3.5cm,0) withcolor .625yellow ;
+draw (origin -- (1,1) -- (1,0) -- cycle)
+ scaled 3cm shifted (7cm,0) withcolor .625white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The \type {dir} command returns an unit vector, which is why the first two shapes
+look different and are smaller than the third one. We can compensate for that by
+an additional scaling:
+
+\startbuffer
+pickup pencircle scaled 2mm ;
+draw (origin -- dir(45) -- dir(0) -- cycle)
+ scaled sqrt(2) scaled 3cm withcolor .625red ;
+draw (origin -- dir(angle(1,1)) -- dir(angle(1,0)) -- cycle)
+ scaled sqrt(2) scaled 3cm shifted (4.5cm,0) withcolor .625yellow ;
+draw (origin -- (1,1) -- (1,0) -- cycle)
+ scaled 3cm shifted (9cm,0) withcolor .625white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Drawing pictures}]
+
+\index{drawing}
+
+Once a path is defined, either directly or as a variable, you can turn it into a
+picture. You can draw a path, like we did in the previous examples, or you can
+fill it, but only if it is closed.
+
+\startlinecorrection[blank]
+\startMPcode
+visualizepaths ;
+path p ; p := (0cm,1cm)..(2cm,2cm)..(4cm,0cm)..cycle ;
+draw p withcolor .625red ;
+fill p shifted (7cm,0) withcolor .625white ;
+\stopMPcode
+\stoplinecorrection
+
+Drawing is done by applying the \type {draw} command to a path, as in:
+
+\starttyping
+draw (0cm,1cm)..(2cm,2cm)..(4cm,0cm)..cycle ;
+\stoptyping
+
+The rightmost graphic was made with \type {fill}:
+
+\starttyping
+fill (0cm,1cm)..(2cm,2cm)..(4cm,0cm)..cycle ;
+\stoptyping
+
+If you try to duplicate this drawing, you will notice that you will get black
+lines instead of red and a black fill instead of a gray one. When drawing or
+filling a path, you can give it a color, use all kinds of pens, and achieve
+special effects like dashes or arrows.
+
+\startlinecorrection[blank]
+\startMPcode
+visualizepaths ;
+path p ; p := (0cm,1cm)..(2cm,2cm)..(4cm,0cm)..(2.5cm,1cm)..cycle ;
+drawarrow p withcolor .625red ;
+draw p shifted (7cm,0) dashed withdots withcolor .625yellow ;
+\stopMPcode
+\stoplinecorrection
+
+These two graphics were defined and drawn using the following commands. Later we
+will explain how you can set the line width (or penshape in terms of \METAPOST).
+
+\starttyping
+path p ; p := (0cm,1cm)..(2cm,2cm)..(4cm,0cm)..(2.5cm,1cm)..cycle ;
+drawarrow p withcolor .625red ;
+draw p shifted (7cm,0) dashed withdots withcolor .625yellow ;
+\stoptyping
+
+Once we have drawn one or more paths, we can store them in a picture variable.
+The straightforward way to store a picture is to copy it from the current
+picture:
+
+\starttyping
+picture pic ; pic := currentpicture ;
+\stoptyping
+
+The following command effectively clears the picture memory and allows us to
+start anew.
+
+\starttyping
+currentpicture := nullpicture ;
+\stoptyping
+
+We can shift, rotate and slant the picture stored in \type {pic} as we did with
+paths. We can say:
+
+\starttyping
+draw pic rotated 45 withcolor red ;
+\stoptyping
+
+A picture can hold multiple paths. You may compare a picture to grouping as
+provided by drawing applications.
+
+\starttyping
+draw (0cm,0cm)--(1cm,1cm) ; draw (1cm,0cm)--(0cm,1cm) ;
+picture pic ; pic := currentpicture ;
+draw pic shifted (3cm,0cm) ; draw pic shifted (6cm,0cm) ;
+pic := currentpicture ; draw pic shifted (0cm,2cm) ;
+\stoptyping
+
+We first draw two paths and store the resulting \quote {cross} in a picture
+variable. Then we draw this picture two times, so that we now have three copies
+of the cross. We store the accumulated drawing again, so that after duplication,
+we finally get six crosses.
+
+\startlinecorrection[blank]
+\startMPcode
+path p ; p := (0cm,0cm)--(1cm,1cm) ;
+path q ; q := (1cm,0cm)--(0cm,1cm) ;
+for i=p,q :
+ drawpath i ; drawcontrollines i ; drawpoints i ; drawcontrolpoints i ;
+endfor ;
+picture pic ; pic := currentpicture ;
+draw pic shifted (3cm,0cm) ;
+draw pic shifted (6cm,0cm) ;
+pic := currentpicture ;
+draw pic shifted (0cm,2cm) ;
+\stopMPcode
+\stoplinecorrection
+
+You can often follow several routes to reach the same solution. Consider for
+instance the following graphic.
+
+\startbuffer[points]
+w := 4cm ; h := 2cm ; ww := 1cm ; hh := 1.5cm ;
+\stopbuffer
+
+\startbuffer[common]
+drawoptions(withcolor .625white) ;
+\stopbuffer
+
+\startbuffer[background]
+fill (unitsquare xscaled w yscaled h) enlarged 2mm withcolor .625yellow ;
+\stopbuffer
+
+\startbuffer[shape]
+fill (0,0)--(ww,0)--(ww,hh)--(w,hh)--(w,h)--(0,h)--cycle ;
+fill (ww,0)--(w,0)--(w,hh)--cycle ;
+\stopbuffer
+
+\typebuffer[shape]
+
+\startlinecorrection[blank]
+\processMPbuffer[common,points,shape]
+\stoplinecorrection
+
+The points that are used to construct the paths are defined using the constants
+\type {w}, \type {h}, \type {ww} and \type {hh}. These are defined as follows:
+
+\typebuffer[points]
+
+In this case we draw two shapes that leave part of the rectangle uncovered. If
+you have a background, this technique allows the background to \quote {show
+through} the graphic.
+
+\startlinecorrection[blank]
+\processMPbuffer[common,points,background,shape]
+\stoplinecorrection
+
+A not uncommon practice when making complicated graphics is to use unfill
+operations. Since \METAPOST\ provides one, let us see what happens if we apply
+this command.
+
+\startbuffer[shape]
+fill (0,0)--(w,0)--(w,h)--(0,h)--cycle ;
+unfill (ww,0)--(w,hh)--(ww,hh)--cycle ;
+\stopbuffer
+
+\typebuffer[shape]
+
+\startlinecorrection[blank]
+\processMPbuffer[common,points,background,shape]
+\stoplinecorrection
+
+This does not always give the desired effect, because \METAPOST's \type {unfill}
+is not really an unfill, but a \type {fill} with color \type {background}. Since
+this color is white by default, we get what we just showed. So, if we set \type
+{background} to \type {black}, using \typ {background := black}, we get:
+
+\startbuffer[back]
+background := black ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[back,common,points,background,shape]
+\stoplinecorrection
+
+Of course, you can set the variable \type {background} to a different color, but
+this does not hide the fact that \METAPOST\ lacks a real unfill operation.
+
+\startbuffer[shape]
+fill (0,0)--(0,h)--(w,h)--(w,0)--(ww,0)--(w,hh)--(ww,hh)--
+ (ww,0)--cycle ;
+\stopbuffer
+
+\startbuffer[path]
+autoarrows := true ;
+path p ; p := (0,0)--(0,h)--(w,h)--(w,0)--(ww,0)--(w,hh)--(ww,hh)--
+ (ww,0)--cycle ;
+draw p withpen pencircle scaled 1mm withcolor .625red;
+numeric l ; l := length(p)-1 ;
+for i=0 upto l :
+ drawarrow subpath(i,i+1) of p
+ withpen pencircle scaled 1mm
+ withcolor (.5+.5(i/l))*red ;
+endfor ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[common,points,background,shape]
+\stoplinecorrection
+
+Since we don't consider this \type {unfill} a suitable operator, you may wonder
+how we achieved the above result.
+
+\typebuffer[shape]
+
+\startlinecorrection[blank]
+\processMPbuffer[common,points,background,shape,path]
+\stoplinecorrection
+
+This feature depends on the \POSTSCRIPT\ way of filling closed paths, which comes
+down to filling either the left or the right hand side of a curve. The following
+alternative works too.
+
+\startbuffer[shape]
+fill (0,0)--(0,h)--(w,h)--(w,hh)--(ww,hh)--(ww,0)--(w,hh)--
+ (w,0)--cycle ;
+\stopbuffer
+
+\typebuffer[shape]
+
+\startlinecorrection[blank]
+\processMPbuffer[common,points,background,shape]
+\stoplinecorrection
+
+The next alternative will fail. This has to do with the change in direction at
+point \type {(0,0)} halfway through the path. Sometimes changing direction can
+give curious but desirable effects, but here it brings no good.
+
+\startbuffer[shape]
+fill (0,0)--(0,h)--(w,h)--(w,0)--(0,0)--(ww,0)--(ww,hh)--
+ (w,hh)--(ww,0)--cycle ;
+\stopbuffer
+
+\typebuffer[shape]
+
+This path fails because of the way \POSTSCRIPT\ implements its fill operator.
+More details on how \POSTSCRIPT\ defines fills can be found in the reference
+manuals.
+
+\startlinecorrection[blank]
+\processMPbuffer[common,points,background,shape]
+\stoplinecorrection
+
+Some of the operations we have seen are hard coded into \METAPOST\ and are called
+primitives. Others are defined as macros, that is, a sequence of \METAPOST\
+commands. Since they are used often, you may expect \type {draw} and \type {fill}
+to be primitives, but they are not. They are macros defined in terms of
+primitives.
+
+Given a path \type {pat}, you can consider a \type {draw} to be defined in terms
+of:
+
+\starttyping
+addto currentpicture doublepath pat
+\stoptyping
+
+The \type {fill} command on the other hand is defined as:
+
+\starttyping
+addto currentpicture contour pat
+\stoptyping
+
+Both macros are actually a bit more complicated but this is mainly due to the
+fact that they also have to deal with attributes like the pen and color they draw
+with.
+
+You can use \type {doublepath} and \type {contour} directly, but we will use
+\type {draw} and \type {fill} whenever possible.
+
+Given a picture \type {pic}, the following code is valid:
+
+\starttyping
+addto currentpicture also pic
+\stoptyping
+
+You can add pictures to existing picture variables, where \type {currentpicture}
+is the picture that is flushed to the output file. Watch the subtle difference
+between adding a \type {doublepath}, \type {contour} or \type {picture}.
+
+\stopsection
+
+\startsection[title={Variables}]
+
+\index{variables}
+
+At this point you may have noted that \METAPOST\ is a programming language.
+Contrary to some of today's languages, \METAPOST\ is a simple and clean language.
+Actually, it is a macro language. Although \METAPOST\ and \TEX\ are a couple, the
+languages differ in many aspects. If you are using both, you will sometimes wish
+that features present in one would be available in the other. When using both
+languages, in the end you will understand why the conceptual differences make
+sense.
+
+Being written in \PASCAL, it will be no surprise that \METAPOST\ has some
+\PASCAL||like features, although some may also recognize features from \ALGOL68\
+in it.
+
+First there is the concept of variables and assignments. There are several data
+types, some of which we already have seen.
+
+\starttabulate
+\HL
+\NC numeric \NC real number in the range $-4096 \ldots +4096$ \NC \NR
+\NC boolean \NC a variable that takes one of two states: true or false \NC \NR
+\NC pair \NC point or vector in 2||dimensional space \NC \NR
+\NC path \NC a piecewise collection of curves and line segments \NC \NR
+\NC picture \NC collection of stroked or filled paths \NC \NR
+\NC string \NC sequence of characters, like \type {"metapost"} \NC \NR
+\NC color \NC vector of three (rgb) or four (cmyk) numbers \NC \NR
+\HL
+\stoptabulate
+
+There are two additional types, \type {transform} and \type {pen}, but we will
+not discuss these in depth.
+
+\starttabulate
+\HL
+\NC transform \NC transformation vector with six elements \NC \NR
+\NC pen \NC pen specification \NC \NR
+\HL
+\stoptabulate
+
+You can achieve interesting effects by using pens with certain shapes. For the
+moment you may consider a pen to be a path itself that is applied to the path
+that is drawn.
+
+The \type {numeric} data type is used so often that it is the default type of any
+non declared variable. This means that
+
+\starttyping
+n := 10 ;
+\stoptyping
+
+is the same as
+
+\starttyping
+numeric n ; n := 10 ;
+\stoptyping
+
+When writing collections of macros, it makes sense to use the second method,
+because you can never be sure if \type {n} isn't already declared as a picture
+variable, and assigning a numeric to a picture variable is not permitted.
+
+Because we often deal with collections of objects, such as a series of points,
+all variables can be organized in arrays. For instance:
+
+\starttyping
+numeric n[] ; n[3] := 10 ; n[5] := 13 ;
+\stoptyping
+
+An array is a collection of variables of the same type that are assigned and
+accessed by indexing the variable name, as in \type {n[3] := 5}.
+Multi||dimensional arrays are also supported. Since you need a bit of imagination
+to find an application for 5||dimensional arrays, we restrict ourselves to a
+two||dimensional example.
+
+\starttyping
+numeric n[][] ; n[2][3] := 10 ;
+\stoptyping
+
+A nice feature is that the bounds of such an array needs not to be set
+beforehand. This also means that each cell that you access is reported as {\em
+unknown} unless you have assigned it a value.
+
+Behind the screens there are not really arrays. It's just a matter of creating
+hash entries. It might not be obvious, but the following assignments are all
+equivalent:
+
+\startbuffer
+i_111_222 := 1cm ;
+i_[111]_[222] := 1cm ;
+i_[111][222] := 1cm ;
+draw
+ image (
+ draw (0cm,i_111_222) ;
+ draw (1cm,i_[111]_[222]) ;
+ draw (2cm,i_[111][222]) ;
+ )
+ withpen pencircle scaled 5mm
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+Sometimes \METAPOST\ ways are mysterious:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Conditions}]
+
+\index{conditions}
+
+The existence of boolean variables indicates the presence of conditionals.
+Indeed, the general form of \METAPOST's conditional follows:
+
+\starttyping
+if n=10 : draw p ; else : draw q ; fi ;
+\stoptyping
+
+Watch the colons after the if and else clause. They may not be omitted. The
+semi||colons on the other hand, are optional and depend on the context. You may
+say things like:
+
+\starttyping
+draw if n=10 : p ; else : q ; fi ;
+\stoptyping
+
+Here we can omit a few semi||colons:
+
+\starttyping
+draw if n=10 : p else : q fi withcolor red ;
+\stoptyping
+
+Adding semi||colons after \type {p} and \type {q} will definitely result in an
+error message, since the semi||colon ends the draw operation and \typ {withcolor
+red} becomes an isolated piece of nonsense.
+
+There is no case statement available, but for most purposes, the following
+extension is adequate:
+
+\starttyping
+draw p withcolor if n<10 : red elseif n=10 : green else : blue fi ;
+\stoptyping
+
+There is a wide repertoire of boolean tests available.
+
+\starttyping
+if picture p :
+if known n :
+if odd i :
+if cycle q :
+\stoptyping
+
+Of course, you can use \type {and}, \type {or}, \type {not}, and \type {( )} to
+construct very advanced boolean expressions. If you have a bit of programming
+experience, you will appreciate the extensive support of conditionals in
+\METAPOST.
+
+\stopsection
+
+\startsection[title={Loops}]
+
+\index{loops}
+
+Yet another programming concept present in \METAPOST\ is the loop statement, the
+familiar \quote {for loop} of all programming languages.
+
+\starttyping
+for i=0 step 2 until 20 :
+ draw (0,i) ;
+endfor ;
+\stoptyping
+
+As explained convincingly in Niklaus Wirth's book on algorithms and
+datastructures, the for loop is the natural companion to an array. Given an array
+of length $n$, you can construct a path out of the points that make up the array.
+
+\starttyping
+draw for i=0 step 1 until n-1 : p[i] .. endfor p[n] ;
+\stoptyping
+
+If the step increment is not explicitly stated, it has an assumed value of 1. We
+can shorten the previous loop construct as follows:
+
+\starttyping
+draw for i=0 upto n-1 : p[i] .. endfor p[n] ;
+\stoptyping
+
+After seeing \type {if} in action, the following \type {for} loop will be no
+surprise:
+
+\startbuffer
+draw origin for i=0 step 10 until 100 : ..{down}(i,0) endfor ;
+\stopbuffer
+
+\typebuffer
+
+This gives the zig||zag curve:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+You can use a loop to iterate over a list of objects. A simple 3||step iteration
+is:
+
+\starttyping
+for i=p,q,r :
+ fill i withcolor .8white ;
+ draw i withcolor red ;
+endfor ;
+\stoptyping
+Using \type {for} in this manner can sometimes save a bit of typing. The list can
+contain any expression, and may be of different types.
+
+In the previous example the \type {i} is an independent variable, local to the
+for loop. If you want to change the loop variable itself, you need to use \type
+{forsuffixes}. In the next loop the paths \type {p}, \type {q} and~\type {r} are
+all shifted.
+
+\starttyping
+forsuffixes i = p, q, r :
+ i := i shifted (3cm,2cm) ;
+endfor ;
+\stoptyping
+
+Sometimes you may want to loop forever until a specific condition occurs. For
+this, \METAPOST\ provides a special looping mechanism:
+
+\startbuffer[demo]
+numeric done[][], i, j, n ; n := 0 ;
+forever :
+ i := round(uniformdeviate(10)) ; j := round(uniformdeviate(2)) ;
+ if unknown done[i][j] :
+ drawdot (i*cm,j*cm) ; n := n + 1 ; done[i][j] := n ;
+ fi ;
+ exitif n = 10 ;
+endfor ;
+\stopbuffer
+
+\typebuffer[demo]
+
+Here we remain in the loop until we have 10 points placed. We use an array to
+keep track of placed points. The \METAPOST\ macro \type {uniformdeviate(n)}
+returns a random number between 0 and~n and the \type {round} command is used to
+move the result toward the nearest integer. The \type {unknown} primitive allows
+us to test if the array element already exists, otherwise we exit the
+conditional. This saves a bit of computational time as each point is drawn and
+indexed only once.
+
+\startbuffer[pen]
+pickup pencircle scaled 2mm ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[pen,demo]
+\stoplinecorrection
+
+The loop terminator \type {exitif} and its companion \type {exitunless} can be
+used in \type {for}, \type {forsuffixes} and \type {forever}.
+
+\stopsection
+
+\startsection[title={Macros}]
+
+\index{macros}
+\index{definitions}
+
+In the previous section we introduced \type {upto}. Actually this is not part of
+the built in syntax, but a sort of shortcut, defined by:
+
+\starttyping
+def upto = step 1 until enddef ;
+\stoptyping
+
+You just saw a macro definition where \type {upto} is the name of the macro. The
+counterpart of \type {upto} is \type {downto}. Whenever you use \type {upto}, it
+is replaced by \typ {step 1 until}. This replacement is called expansion.
+
+There are several types of macros. A primary macro is used to define your own
+operators. For example:
+
+\starttyping
+primarydef p doublescaled s =
+ p xscaled (s/2) yscaled (s*2)
+enddef ;
+\stoptyping
+
+Once defined, the \type {doublescaled} macro is implemented as in the following
+example:
+
+\starttyping
+draw somepath doublescaled 2cm withcolor red ;
+\stoptyping
+
+When this command is executed, the macro is expanded. Thus, the actual content of
+this command becomes:
+
+\starttyping
+draw somepath xscaled 1cm yscaled 4cm withcolor red ;
+\stoptyping
+
+If in the definition of \type {doublescaled} we had added a semi||colon after
+\type {(s*2)}, we could not have set the color, because the semicolon ends the
+statement. The \type {draw} expects a path, so the macro can best return one.
+
+A macro can take one or more arguments, as in:
+
+\starttyping
+def drawrandomscaledpath (expr p, s) =
+ draw p xscaled (s/2) yscaled (s*2) ;
+enddef ;
+\stoptyping
+
+When using this macro, it is expected that you will pass it two parameters, the
+first being a path, the second a numeric scale factor.
+
+\starttyping
+drawrandomscaledpath(fullsquare, 3cm) ;
+\stoptyping
+
+Sometimes we want to return a value from a macro. In that case we must make sure
+that any calculations don't interfere with the expectations. Consider:
+
+\starttyping
+vardef randomscaledpath(expr p, s) =
+ numeric r ; r := round(1 + uniformdeviate(4)) ;
+ p xscaled (s/r) yscaled (s*r)
+enddef ;
+\stoptyping
+
+Because we want to use the same value of \type {r} twice, we have to use an
+intermediate variable. By using a \type {vardef} we hide everything but the last
+statement. It is important to distinguish \type {def} macros from those defined
+with \type {vardef}. In the latter case, \type {vardef} macros are not a simple
+expansion and replacement. Rather, \type {vardef} macros return the value of
+their last statement. In the case of the \type {randomscaledpath} macro, a path
+is returned. This macro is used in the following manner:
+
+\starttyping
+path mypath ; mypath := randomscaledpath(unitsquare,4cm) ;
+\stoptyping
+
+Note that we send \type {randomscaledpath} a path (\type {unitsquare}) and a
+scaling factor (\type {4cm}). The macro returns a scaled path which is then
+stored in the path variable \type {mypath}.
+
+The following argument types are accepted:
+
+\starttabulate
+\HL
+\NC expr \NC something that can be assigned to a variable \NC \NR
+\NC text \NC arbitrary \METAPOST\ code ending with a \type {;} \NC \NR
+\NC suffix \NC a variable bound to another variable \NC \NR
+\HL
+\stoptabulate
+An expression is passed by value. This means that in the body of the macro, a
+copy is used and the original is left untouched. On the other hand, any change to
+a variable passed as suffix is also applied to the original.
+
+Local variables must be handled in a special manner, since they may conflict with
+variables used elsewhere. This is because all variables are global by default.
+The way out of this problem is using grouping in combination with saving
+variables. The use of grouping is not restricted to macros and may be used
+anywhere in your code. Variables saved and declared in a group are local to that
+group. Once the group is exited the variables cease to exist.
+
+\starttyping
+vardef randomscaledpath(expr p, s) =
+ begingroup ; save r ; numeric r ;
+ r := round(1 + uniformdeviate(4)) ;
+ p xscaled (s/r) yscaled (s*r)
+ endgroup
+enddef ;
+\stoptyping
+
+In this particular case, we could have omitted the grouping, since \type {vardef}
+macros are always grouped automatically. Therefore, we could have defined the
+macro as:
+
+\starttyping
+vardef randomscaledpath(expr p, s) =
+ save r ; numeric r ; r := round(1 + uniformdeviate(4)) ;
+ p xscaled (s/r) yscaled (s*r)
+enddef ;
+\stoptyping
+
+The command \type {save r} declares that the variable \type {r} is local to the
+macro. Thus, any changes to the (new) numeric variable \type {r} are local and
+will not interfere with a variable \type {r} defined outside the macro. This is
+important to understand, as variables outside the macro are global and accessible
+to the code within the body of the macro.
+
+Macro definitions may be nested, but since most \METAPOST\ code is relatively
+simple, it is seldom needed. Nesting is discouraged as it makes your code less
+readable.
+
+Besides \type {def} and \type {vardef}, \METAPOST\ also provides the classifiers
+\type {primarydef}, \type {secondarydef} and \type {tertiarydef}. You can use
+these classifiers to define macros like those provided by \METAPOST\ itself:
+
+\starttyping
+primarydef x mod y = ... enddef ;
+secondarydef p intersectionpoint q = ... enddef ;
+tertiarydef p softjoin q = ... enddef ;
+\stoptyping
+A primary macro acts like the binary operators \type {*} or \type {scaled} and
+\type {shifted}. Secondary macros are like \type {+}, \type {-} and logical \type
+{or}, and take less precedence. The tertiary operators like \type {<} or the path
+and string concatenation operator \type {&} have tertiary macros as companions.
+More details can be found in the \METAFONT\ book. When it comes to taking
+precedence, \METAPOST\ tries to be as natural as possible, in the sense that you
+need to provide as few \type {( )}'s as possible. When in doubt, or when
+surprised by unexpected results, use parentheses.
+
+\stopsection
+
+\startsection[title={Arguments}]
+
+\index{arguments}
+\index{macros+arguments}
+
+The \METAPOST\ macro language is rather flexible in how you feed arguments to
+macros. If you have only one argument, the following definitions and calls are
+valid.
+
+\starttyping
+def test expr a = enddef ; test (a) ; test a ;
+def test (expr a) = enddef ; test (a) ; test a ;
+\stoptyping
+
+A more complex definition is the following. As you can see, you can call the
+\type {test} macro in your favorite way.
+
+\starttyping
+def test (expr a,b) (expr c,d) = enddef ;
+
+test (a) (b) (c) (d) ;
+test (a,b) (c,d) ;
+test (a,b,c) (d) ;
+test (a,b,c,d) ;
+\stoptyping
+
+The type of the arguments is one of \type {expr}, \type {primary} or \type
+{suffix}. When fetching arguments, \METAPOST\ uses the type to determine how and
+what to grab. A fourth type is \type {text}. When no parenthesis are used, a
+\type {text} argument grabs everything upto the next semicolon.
+
+\starttyping
+def test (expr a) text b = enddef ;
+
+test (a) ; test (a) b ;
+\stoptyping
+
+You can use a \type {text} to grab arguments like \typ {withpen pencircle scaled
+10 withcolor red}. Because \type {text} is so hungry, you may occasionally need a
+two stage definition:
+
+\starttyping
+def test expr a = dotext(a) enddef ;
+def dotest (expr a) text b = ... enddef ;
+
+test a ; test a b ;
+\stoptyping
+
+This definition permits arguments without parenthesis, which is something you
+want with commands like \type {draw}.
+
+The \type {vardef} alternative behaves in a similar way. It always provides
+grouping. You need to generate a return value and as a result may not end with a
+semicolon.
+
+You may consider the whole \type {vardef} to be encapsulated into parenthesis and
+thereby to be a (self contained) variable. Adding additional parenthesis often
+does more harm than good:
+
+\starttyping
+vardef test (expr a) =
+ ( do tricky things with a ; manipulated_a )
+enddef ;
+\stoptyping
+
+Here the tricky things become part of the return value, which quite certainly is
+something that you don't want.
+
+The three operator look||alike macro definitions are less flexible and have the
+definition scheme:
+
+\starttyping
+primarydef x test y = enddef ;
+secondarydef x test y = enddef ;
+tertiarydef x test y = enddef ;
+\stoptyping
+
+When defining macros using this threesome you need to be aware of the associated
+priorities. When using these definitions, you also have to provide your own
+grouping.
+
+In the plain \METAPOST\ macro collection (\type {plain.mp}) you can find many
+examples of clever definitions. The following (simplified) version of \type {min}
+demonstrates how we use the argument handler to isolate the first argument from
+the provided list, simply by using two arguments.
+
+\starttyping
+vardef min (expr u) (text t) =
+ save min_u ; min_u := u ;
+ for uu = t : if uu<u : min_u := uu ; fi endfor
+ min_u
+enddef ;
+\stoptyping
+
+The special sequence \type {@#} is used to pick up a so called delimited argument:
+
+\starttyping
+vardef TryMe@#(expr x) =
+ % we can now use @#, which is just text
+enddef ;
+\stoptyping
+
+This feature is used in the definition of \type {z} as used in \type {z1} or
+\type {z234}:
+
+\starttyping
+vardef z@# = (x@#,y@#) enddef ;
+\stoptyping
+
+Other applications can be found in the label drawing macros where the anchor
+point is assigned to the obscure variable \type {@#}.
+
+\stopsection
+
+\startsection[title={Pens}]
+
+\index{pens}
+
+When drawing, three attributes can be applied to it: a dashpattern, a pen
+and|/|or a color. You may consider an arrowhead an attribute, but actually it is
+just an additional drawing, appended to the path.
+
+The (predefined) \type {pencircle} attribute looks like:
+
+\starttyping
+withpen pencircle
+\stoptyping
+
+where \type {pencircle} is a special kind of path, stored in a pen variable. Like
+any path, you can transform it. You can scale it equally in all directions:
+
+\starttyping
+withpen pencircle scaled 1mm
+\stoptyping
+
+You can also provide unequal scales, creating an elliptically shaped and rotated
+pen.
+
+\starttyping
+withpen pencircle xscaled 2mm yscaled 4mm rotated 30
+\stoptyping
+
+In the following graphic, the circle in the center is drawn without any option,
+which means that the default pen is used, being a pencircle with a radius of half
+a base point. The other three circles are drawn with different pen
+specifications.
+
+\startlinecorrection[blank]
+\startMPcode
+path p ; p := fullcircle scaled 1cm ;
+drawoptions (withcolor .625yellow) ;
+draw p ;
+drawoptions (withcolor .625red) ;
+draw p scaled 2 withpen pencircle ;
+drawoptions (withcolor .625yellow) ;
+draw p scaled 3 withpen pencircle scaled 1mm ;
+drawoptions (withcolor .625red) ;
+draw p scaled 4 withpen pencircle xscaled 2mm yscaled 4mm rotated 30 ;
+\stopMPcode
+\stoplinecorrection
+
+If you forget about the colors, the \METAPOST\ code to achieve this is as
+follows.
+
+\starttyping
+path p ; p := fullcircle scaled 1cm ;
+draw p ;
+draw p scaled 2 withpen pencircle ;
+draw p scaled 3 withpen pencircle scaled 1mm ;
+draw p scaled 4 withpen pencircle xscaled 2mm yscaled 4mm rotated 30 ;
+\stoptyping
+
+If this were the only way of specifying a pen, we would be faced with a
+considerable amount of typing, particularly in situations where we use pens
+similar to the fourth specification above. For that reason, \METAPOST\ supports
+the concept of a current pen. The best way to set this pen is to use the \type
+{pickup} macro.
+
+\starttyping
+pickup pencircle xscaled 2mm yscaled 4mm rotated 30 ;
+\stoptyping
+
+This macro also stores some characteristics of the pen in variables, so that they
+can be used in (the more complicated) calculations that are involved in
+situations like drawing font||like graphics.
+
+If we substitute \type {pencircle} by \type {pensquare}, we get a different kind
+of shapes. In the non rotated pens, the top, bottom, left and right parts of the
+curve are thinner.
+
+\startlinecorrection[blank]
+\startMPcode
+path p ; p := fullcircle scaled 1cm ;
+drawoptions (withcolor .625yellow) ;
+draw p ;
+drawoptions (withcolor .625red) ;
+draw p scaled 2 withpen pensquare ;
+drawoptions (withcolor .625yellow) ;
+draw p scaled 3 withpen pensquare scaled 1mm ;
+drawoptions (withcolor .625red) ;
+draw p scaled 4 withpen pensquare xscaled 2mm yscaled 4mm rotated 30 ;
+\stopMPcode
+\stoplinecorrection
+
+You should look at pens in the way an artist does. He follows a shape and in
+doing so he or she twists the pen (and thereby the nib) and puts more or less
+pressure on it.
+
+The chance that you have an appropriate pen laying at your desk is not so big,
+but you can simulate the following \METAPOST's pen by taking two pencils and
+holding them together in one hand. If you position them in a 45 degrees angle,
+and draw a circle, you will get something like:
+
+\startlinecorrection[blank]
+\startMPcode
+path p ; p := fullcircle xscaled 2cm yscaled 3cm ;
+drawoptions(withcolor .625red withpen pencircle scaled .5mm);
+draw p ; draw p shifted (.3cm,.3cm) ;
+\stopMPcode
+\stoplinecorrection
+
+If you take a calligraphic pen with a thin edge of .5cm, you will get:
+
+\startlinecorrection[blank]
+\startMPcode
+drawoptions(withcolor .625red);
+path p ; p := fullcircle xscaled 2cm yscaled 3cm ;
+draw p withpen makepen ((0,0)--(.3cm,.3cm)) withcolor .625white ;
+drawoptions(withcolor .625red withpen pencircle scaled .25mm);
+draw p ; draw p shifted (.3cm,.3cm) ;
+\stopMPcode
+\stoplinecorrection
+
+You can define such a pen yourself:
+
+\starttyping
+path p ; p := fullcircle xscaled 2cm yscaled 3cm ;
+pen doublepen ; doublepen := makepen ((0,0)--(.3cm,.3cm)) ;
+pickup doublepen ; draw p ;
+\stoptyping
+
+Here we define a new pen using the \type {pen} command. Then we define a path,
+and make a pen out of it using the \type {makepen} macro. The path should be a
+relatively simple one, otherwise \METAPOST\ will complain.
+
+You can use \type {makepen} with the previously introduced \type {withpen}:
+
+\starttyping
+draw p withpen makepen ((0,0)--(.3cm,.3cm)) ;
+\stoptyping
+
+and \type {pickup}:
+
+\starttyping
+pickup makepen ((0,0)--(.3cm,.3cm)) ; draw p ;
+\stoptyping
+
+You can use \type {makepen} and \type {makepath} to convert paths into pens and
+vice versa.
+
+Pens are very important when defining fonts, and \METAFONT\ is meant to be a font
+creation tool. Since \METAPOST\ has a slightly different audience, it lacks some
+features in this area, but offers a few others instead. Nevertheless, one can try
+to design a font using \METAPOST. Of course, pens are among the designers best
+kept secrets. But even then, not every~O is a nice looking one.
+
+\startlinecorrection[blank]
+\startMPcode
+path p ; p := fullcircle xscaled 2cm yscaled 3cm ;
+draw p withpen makepen (unitsquare scaled .4cm superellipsed .85)
+withcolor .625white ;
+\stopMPcode
+\stoplinecorrection
+
+\startbuffer[s00]
+ path p ; p := (-1,0) {down} .. {up} (1,0) ;
+ draw pensilled(p, pensquare scaled (1/3))
+ scaled 2cm ;
+ draw boundingbox image(draw p)
+ scaled 2cm ;
+\stopbuffer
+
+\startbuffer[s30]
+ path p ; p := (-1,0) {down} .. {up} (1,0) ;
+ draw pensilled(p, pensquare scaled (1/3) rotated 30)
+ scaled 2cm ;
+ draw boundingbox image(draw p)
+ scaled 2cm ;
+\stopbuffer
+
+\startbuffer[s45]
+ path p ; p := (-1,0) {down} .. {up} (1,0) ;
+ draw pensilled(p, pensquare scaled (1/3) rotated 45)
+ scaled 2cm ;
+ draw boundingbox image(draw p)
+ scaled 2cm ;
+\stopbuffer
+
+\startbuffer[c00]
+ path p ; p := (-1,0) {down} .. {up} (1,0) ;
+ draw pensilled(p, pencircle scaled (1/3))
+ scaled 2cm ;
+ draw boundingbox image(draw p)
+ scaled 2cm ;
+\stopbuffer
+
+\startbuffer[c30]
+ path p ; p := (-1,0) {down} .. {up} (1,0) ;
+ draw pensilled(p, pencircle scaled (1/3) rotated 30)
+ scaled 2cm ;
+ draw boundingbox image(draw p)
+ scaled 2cm ;
+\stopbuffer
+
+\startbuffer[c45]
+ path p ; p := (-1,0) {down} .. {up} (1,0) ;
+ draw pensilled(p, pencircle scaled (1/3) rotated 45)
+ scaled 2cm ;
+ draw boundingbox image(draw p)
+ scaled 2cm ;
+\stopbuffer
+
+\startbuffer[f30]
+ interim pensilstep := 1/6 ;
+ draw pensilled(fullcircle, pencircle xscaled (1/10) yscaled (2/10) rotated 30)
+ scaled 5cm ;
+ draw boundingbox fullcircle
+ scaled 5cm ;
+\stopbuffer
+
+The \type {pensilled} macro is a variant on a macro used for testing some border
+cases in the engine. It provides a nice way to see what actually happens when a
+pen is applied. \in {Figure} [fig:pensilled] demonstrates this macro. The first
+row shows a square pen:
+
+\typebuffer[s30]
+
+and the second row a circular pen:
+
+\typebuffer[c30]
+
+\startplacefigure[title={How pens are applied.},reference=fig:pensilled]
+ \startcombination[3*2]
+ {\processMPbuffer[s00]} {\tttf pensquare rotated 0}
+ {\processMPbuffer[s30]} {\tttf pensquare rotated 30}
+ {\processMPbuffer[s45]} {\tttf pensquare rotated 45}
+ {\processMPbuffer[c00]} {\tttf pencircle rotated 0}
+ {\processMPbuffer[c30]} {\tttf pencircle rotated 30}
+ {\processMPbuffer[c45]} {\tttf pencircle rotated 45}
+ \stopcombination
+\stopplacefigure
+
+The effects of rotation and non|-|proportional scaling are demonstrated
+in \in {figure} [fig:pensilled:fullcircle].
+
+\typebuffer[f30]
+
+\startplacefigure[title={A proportionally scaled and rotated pen.},reference=fig:pensilled:fullcircle]
+ \processMPbuffer[f30]
+\stopplacefigure
+
+\stopsection
+
+\startsection[title={Joining lines}]
+
+\index{joining}
+\index{paths+joining}
+
+The way lines are joined or end is closely related to the way \POSTSCRIPT\
+handles this. By setting the variables \type {linejoin} and \type {linecap}, you
+can influence the drawing process. \in {Figure} [fig:joints] demonstrates the
+alternatives. The gray curves are drawn with both variables set to \type
+{rounded}.
+
+\startnotmode[screen]
+
+\def\showMPline#1#2%
+ {\startMPcode
+ path p ; p := ((0,0)--(.5,1)--(1,0)) xscaled 3cm yscaled 1.5cm ;
+ pickup pencircle scaled 1cm ;
+ draw p withcolor .625white ;
+ interim linejoin := #1 ;
+ interim linecap := #2 ;
+ draw p withcolor transparent(1,.5,.625yellow) ;
+ \stopMPcode}
+
+\stopnotmode
+
+\startmode[screen]
+
+\def\showMPline#1#2%
+ {\startMPcode
+ path p ; p := ((0,0)--(.5,1)--(1,0)) xscaled 2.5cm yscaled 1.25cm ;
+ pickup pencircle scaled .75cm ;
+ draw p withcolor .625white ;
+ interim linejoin := #1 ;
+ interim linecap := #2 ;
+ draw p withcolor transparent(1,.5,.625yellow) ;
+ \stopMPcode}
+
+\stopmode
+
+\def\showMPtext#1#2%
+ {linejoin=#1\par linecap=#2}
+
+\startbuffer
+\startcombination[3*3]
+ {\showMPline{mitered}{butt}} {\showMPtext{mitered}{butt}}
+ {\showMPline{mitered}{rounded}} {\showMPtext{mitered}{rounded}}
+ {\showMPline{mitered}{squared}} {\showMPtext{mitered}{squared}}
+ {\showMPline{rounded}{butt}} {\showMPtext{rounded}{butt}}
+ {\showMPline{rounded}{rounded}} {\showMPtext{rounded}{rounded}}
+ {\showMPline{rounded}{squared}} {\showMPtext{rounded}{squared}}
+ {\showMPline{beveled}{butt}} {\showMPtext{beveled}{butt}}
+ {\showMPline{beveled}{rounded}} {\showMPtext{beveled}{rounded}}
+ {\showMPline{beveled}{squared}} {\showMPtext{beveled}{squared}}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here] [fig:joints]
+ {The nine ways to end and join lines.}
+ {\getbuffer}
+
+By setting the variable \type {miterlimit}, you can influence the mitering of
+joints. The next example demonstrates that the value of this variable acts as a
+trigger.
+
+\startbuffer
+interim linejoin := mitered ;
+for i :=1 step 1 until 5 :
+ interim miterlimit := i*pt ;
+ draw ((0,0)--(.5,1)--(1,0)) shifted (1.5i,0) scaled 50pt
+ withpen pencircle scaled 10pt withcolor .625red ;
+endfor ;
+\stopbuffer
+
+\typebuffer
+
+The variables \type {linejoin}, \type {linecap} and \type {miterlimit} are so
+called {\em internal} variables. When we prefix their assignments by \type
+{interim}, the setting will be local within groups, like \typ {beginfig ...
+endfig}.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Colors}]
+
+\index{attributes}
+\index{color}
+So far, we have seen some colors in graphics. It must be said that \METAPOST\
+color model is not that advanced, although playing with colors in the \METAPOST\
+way can be fun. In later chapters we will discuss some extensions that provide
+shading.
+
+Colors are defined as vectors with three components: a red, green and blue one.
+Like pens, colors have their \type {with}||command:
+
+\starttyping
+withcolor (.4,.5.,6)
+\stoptyping
+
+You can define color variables, like:
+
+\starttyping
+color darkred ; darkred := (.625,0.0) ;
+\stoptyping
+
+You can now use this color as:
+
+\starttyping
+withcolor darkred
+\stoptyping
+
+Given that \type {red} is already defined, we also could have said:
+
+\starttyping
+withcolor .625red
+\stoptyping
+
+Because for \METAPOST\ colors are just vectors, you can do things similar to
+points. A color halfway red and green is therefore accomplished with:
+
+\starttyping
+withcolor .5[red,green]
+\stoptyping
+
+Since only the \RGB\ color space is supported, this is about all we can tell
+about colors for this moment. Later we will discuss some nasty details.
+
+\stopsection
+
+\startsection[title={Dashes}]
+
+\index{dashes}
+
+A dash pattern is a simple picture that is build out of straight lines. Any
+slightly more complicated picture will be reduced to straight lines and a real
+complicated one is rejected, and in this respect \METAPOST\ considers a circle to
+be a complicated path.
+
+The next example demonstrates how to get a dashed line. First we built picture
+\type {p}, that we apply to a path. Here we use a straight path, but dashing can
+be applied to any path.
+
+\startbuffer
+picture p ; p := nullpicture ;
+addto p doublepath ((0,0)--(3mm,3mm)) shifted (6mm,6mm) ;
+draw (0,0)--(10cm,0) dashed p withpen pencircle scaled 1mm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+This way of defining a pattern is not that handy, especially if you start
+wondering why you need to supply a slanted path. Therefore, \METAPOST\ provides a
+more convenient mechanism to define a pattern.
+
+\startbuffer
+picture p ; p := dashpattern(on 3mm off 3mm) ;
+draw (0,0)--(10cm,0) dashed p withpen pencircle scaled 1mm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Most dashpatterns can be defined in terms of on and off. This simple on||off
+dashpattern is predefined as picture \type {evenly}. Because this is a picture,
+you can (and often need to) scale it.
+
+\startbuffer
+draw (0,0)--(10cm,0) dashed (evenly scaled 1mm)
+ withpen pencircle scaled 1mm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Opposite to a defaultpen, there is no default color and default dash pattern set.
+The macro \type {drawoptions} provides you a way to set the default attributes.
+
+\starttyping
+drawoptions(dashed evenly withcolor red) ;
+\stoptyping
+
+\stopsection
+
+\startsection[reference=sec:text,title={Text}]
+
+\index{text}
+
+Since \METAFONT\ is meant for designing fonts, the only means for including text
+are those that permit you to add labels to positions for the sole purpose of
+documentation.
+
+Because \METAPOST\ is derived from \METAFONT\ it provides labels too, but in
+order to let users add more sophisticated text, like a math formula, to a
+graphic, it also provides an interface to \TEX.
+
+Because we will spend a whole chapter on using text in \METAPOST\ we limit the
+discussion here to a few fundamentals.
+
+\startbuffer[font]
+defaultfont := "\truefontname{Mono}" ;
+defaultscale := .8 ;
+\stopbuffer
+
+\startbuffer[label]
+pair a ; a := (3cm,3cm) ;
+label.top("top",a) ; label.bot("bot",a) ;
+label.lft("lft",a) ; label.rt ("rt" ,a) ;
+\stopbuffer
+
+\typebuffer[label]
+
+These four labels show up at the position stored in the pair variable \type {a},
+anchored in the way specified after the period.
+
+\startlinecorrection[blank]
+\processMPbuffer[font,label]
+\stoplinecorrection
+
+The command \type {dotlabel} also typesets the point as a rather visible dot.
+
+\startbuffer[label]
+pair a ; a := (3cm,3cm) ;
+dotlabel.top("top",a) ; dotlabel.bot("bot",a) ;
+dotlabel.lft("lft",a) ; dotlabel.rt ("rt" ,a) ;
+\stopbuffer
+
+\typebuffer[label]
+
+\startlinecorrection[blank]
+\processMPbuffer[font,label]
+\stoplinecorrection
+
+The command \type {thelabel} returns the typeset label as picture that you can
+manipulate or draw afterwards.
+
+\startbuffer[label]
+pair a ; a := (3cm,3cm) ; pickup pencircle scaled 1mm ;
+drawdot a withcolor .625yellow ;
+draw thelabel.rt("the right way",a) withcolor .625red ;
+\stopbuffer
+
+\typebuffer[label]
+
+You can of course rotate, slant and manipulate such a label picture like any
+other picture.
+
+\startlinecorrection[blank]
+\processMPbuffer[font,label]
+\stoplinecorrection
+
+The font can be specified in the string \type {defaultfont} and the scale in
+\type {defaultscale}. Labels are defined using the low level operator \type
+{infont}. The next statement returns a picture:
+
+\startbuffer[mp]
+draw "this string will become a sequence of glyphs (MP)"
+ infont defaultfont scaled defaultscale ;
+\stopbuffer
+
+\typebuffer[mp]
+
+By default the \type {infont} operator is not that clever and does not apply
+kerning. Also, typesetting math or accented characters are not supported. The way
+out of this problem is using \typ {btex ... etex}.
+
+\startbuffer[tex]
+draw btex this string will become a sequence of glyphs (\TeX) etex ;
+\stopbuffer
+
+\typebuffer[tex]
+
+The difference between those two methods is shown below. The outcome of \type
+{infont} depends on the current setting of the variable \type {defaultfont}.
+
+\startlinecorrection[blank]
+\processMPbuffer[mp]
+\processMPbuffer[tex]
+\stoplinecorrection
+
+When you run inside \CONTEXT\ (as we do here) there is no difference between
+\type {infont} and the \TEX\ methods. This is because we overload the \type
+{infont} operator and also pass its content to \TEX. Both \type {infont} and
+\type {btex} use the macro \type {textext} which is intercepted and redirects the
+task to \TEX. This happens in the current run so there is no need to pass extra
+information about fonts.
+
+Instead of passing strings to \type {infont}, you can also pass characters, using
+\type {char}, for example \type {char(73)}. When you use \type {infont} you
+normally expect the font to be \ASCII\ conforming. If this is not the case, you
+must make sure that the encoding of the font that you use matches your
+expectations. However, as we overload this macro it does not really matter since
+the string is passed to \TEX\ anyway. For instance, \UTF\ encoded text should
+work fine as \CONTEXT\ itself understands this encoding.
+
+\stopsection
+
+\startsection[title={Linear equations}]
+
+\index{equations}
+\index{expressions}
+
+\startbuffer[a]
+\defineMPinstance
+ [solvers]
+ [format=metafun,
+ extensions=yes,
+ initializations=yes]
+\stopbuffer
+
+\startbuffer[b]
+\startMPdefinitions{solvers}
+def draw_problem (expr p, q, r, s, show_labels) =
+ begingroup ; save x, y, a, b, c, d, e, f, g, h ;
+
+ z11 = z42 = p ; z21 = z12 = q ; z31 = z22 = r ; z41 = z32 = s ;
+
+ a = x12 - x11 ; b = y12 - y11 ; c = x22 - x21 ; d = y22 - y21 ;
+ e = x32 - x31 ; f = y32 - y31 ; g = x42 - x41 ; h = y42 - y41 ;
+
+ z11 = (x11, y11) ; z12 = (x12, y12) ;
+ z13 = (x12-b, y12+a) ; z14 = (x11-b, y11+a) ;
+ z21 = (x21, y21) ; z22 = (x22, y22) ;
+ z23 = (x22-d, y22+c) ; z24 = (x21-d, y21+c) ;
+ z31 = (x31, y31) ; z32 = (x32, y32) ;
+ z33 = (x32-f, y32+e) ; z34 = (x31-f, y31+e) ;
+ z41 = (x41, y41) ; z42 = (x42, y42) ;
+ z43 = (x42-h, y42+g) ; z44 = (x41-h, y41+g) ;
+
+ pickup pencircle scaled .5pt ;
+
+ draw z11--z12--z13--z14--cycle ; draw z11--z13 ; draw z12--z14 ;
+ draw z21--z22--z23--z24--cycle ; draw z21--z23 ; draw z22--z24 ;
+ draw z31--z32--z33--z34--cycle ; draw z31--z33 ; draw z32--z34 ;
+ draw z41--z42--z43--z44--cycle ; draw z41--z43 ; draw z42--z44 ;
+
+ z1 = 0.5[z11,z13] ; z2 = 0.5[z21,z23] ;
+ z3 = 0.5[z31,z33] ; z4 = 0.5[z41,z43] ;
+
+ draw z1--z3 dashed evenly ; draw z2--z4 dashed evenly ;
+
+ z0 = whatever[z1,z3] = whatever[z2,z4] ;
+ mark_rt_angle (z1, z0, z2) ; % z2 is not used at all
+
+ if show_labels > 0 :
+ draw_problem_labels ;
+ fi ;
+
+ endgroup ;
+enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\startbuffer[c]
+\startMPdefinitions{solvers}
+angle_radius := 10pt ;
+
+def mark_rt_angle (expr a, b, c) =
+ draw ((1,0)--(1,1)--(0,1))
+ zscaled (angle_radius*unitvector(a-b))
+ shifted b
+enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\startbuffer[d]
+\startMPdefinitions{solvers}
+def draw_problem_labels =
+ pickup pencircle scaled 5pt ;
+
+ dotlabel.llft("$Z_{11}$", z11) ; dotlabel.ulft("$Z_{12}$", z12) ;
+ dotlabel.ulft("$Z_{13}$", z13) ; dotlabel.llft("$Z_{14}$", z14) ;
+
+ dotlabel.lrt ("$Z_{21}$", z21) ; dotlabel.llft("$Z_{22}$", z22) ;
+ dotlabel.urt ("$Z_{23}$", z23) ; dotlabel.ulft("$Z_{24}$", z24) ;
+
+ dotlabel.urt ("$Z_{31}$", z31) ; dotlabel.ulft("$Z_{32}$", z32) ;
+ dotlabel.urt ("$Z_{33}$", z33) ; dotlabel.urt ("$Z_{34}$", z34) ;
+
+ dotlabel.lrt ("$Z_{41}$", z41) ; dotlabel.urt ("$Z_{42}$", z42) ;
+ dotlabel.llft("$Z_{43}$", z43) ; dotlabel.lrt ("$Z_{44}$", z44) ;
+
+ dotlabel.urt ("$Z_{0}$", z0) ;
+ dotlabel.lft ("$Z_{1}$", z1) ; dotlabel.top ("$Z_{2}$", z2) ;
+ dotlabel.rt ("$Z_{3}$", z3) ; dotlabel.bot ("$Z_{4}$", z4) ;
+enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\startbuffer[e]
+\startuseMPgraphic{solvers::one}{i,j,s}
+ draw_problem (
+ (400pt,400pt), (300pt,600pt),
+ \MPvar{i}[(300pt,600pt), (550pt,800pt)],
+ \MPvar{j}[(400pt,400pt), (550pt,500pt)],
+ \MPvar{s}
+ ) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[f]
+\placefigure
+ [here][fig:problem]
+ {The problem.}
+ {\scale
+ [width=\textwidth]
+ {\useMPgraphic{solvers::one}{i=0.6,j=1.0,s=1}}}
+\stopbuffer
+
+In the previous sections, we used the assignment operator \type {:=} to assign a
+value to a variable. Although for most of the graphics that we will present in
+later chapters, an assignment is appropriate, specifying a graphic in terms of
+expressions is not only more flexible, but also more in the spirit of the
+designers of \METAFONT\ and \METAPOST.
+
+The \METAFONT\ book and \METAPOST\ manual provide lots of examples, some of which
+involve math that we don't consider to belong to everyones repertoire. But, even
+for non mathematicians using expressions can be a rewarding challenge.
+
+The next introduction to linear equations is based on my first experiences with
+\METAPOST\ and involves a mathematical challenge posed by a friend. I quickly
+ascertained that a graphical proof was far more easy than some proof with a lot
+of $\sin (this)$ and $\cos (that)$ and long forgotten formulas.
+
+I was expected to prove that the lines connecting the centers of four squares
+drawn upon the four sides of a quadrilateral were perpendicular (see \in {figure}
+[fig:problem]).
+
+\getbuffer[a,b,c,d,e]
+
+\getbuffer[f]
+
+This graphic was generated with the following command:
+
+\typebuffer[f]
+
+We will use this example to introduce a few new concepts, one being instances. In
+a large document there can be many \METAPOST\ graphics and they might fall in
+different categories. In this manual we have graphics that are generated as part
+of the style as wel as examples that show what \METAFUN\ can do. As definitions
+and variables in \METAPOST\ are global by default, there is a possibility that we
+end up with clashes. This can be avoided by grouping graphics in instances. Here
+we create an instance for the example that we're about to show.
+
+\typebuffer[a]
+
+We can now limit the scope of definitions to this specific instance. Let's start
+with the macro that takes care of drawing the solution to our problem. The macro
+accepts four pairs of coordinates that determine the central quadrilateral. All
+of them are expressions.
+
+\typebuffer[b]
+
+Because we want to call this macro more than once, we first have to save the
+locally used values. Instead of declaring local variables, one can hide their use
+from the outside world. In most cases variables behave globally. If we don't save
+them, subsequent calls will lead to errors due to conflicting equations. We can
+omit the grouping commands, because we wrap the graphic in a figure, and figures
+are grouped already.
+
+We will use the predefined \type {z} variable, or actually a macro that returns a
+variable. This variable has two components, an \type {x} and \type {y}
+coordinate. So, we don't save \type {z}, but the related variables \type {x} and
+\type {y}.
+
+Next we draw four squares and instead of hard coding their corner points, we use
+\METAPOST's equation solver. Watch the use of \type {=} which means that we just
+state dependencies. In languages like \PERL, the equal sign is used in
+assignments, but in \METAPOST\ it is used to express relations.
+
+In a first version, we will just name a lot of simple relations, as we can read
+them from a sketch drawn on paper. So, we end up with quite some \type {z}
+related expressions.
+
+For those interested in the mathematics behind this code, we add a short
+explanation. Absolutely key to the construction is the fact that you traverse the
+original quadrilateral in a clockwise orientation. What is really going on here
+is vector geometry. You calculate the vector from $z_{11}$ to $z_{12}$ (the first
+side of the original quadrilateral) with:
+
+\starttyping
+(a,b) = z12 - z11 ;
+\stoptyping
+
+This gives a vector that points from $z_{11}$ to $z_{12}$. Now, how about an
+image that shows that the vector $(-b,a)$ is a 90 degree rotation in the
+counterclockwise direction. Thus, the points $z_{13}$ and $z_{14}$ are easily
+calculated with vector addition.
+
+\starttyping
+z13 = z12 + (-b,a) ;
+z14 = z11 + (-b,a) ;
+\stoptyping
+
+This pattern continues as you move around the original quadrilateral in a
+clockwise manner. \footnote {Thanks to David Arnold for this bonus explanation.}
+
+The code that calculates the pairs \type {a} through \type {h}, can be written in
+a more compact way.
+
+\starttyping
+(a,b) = z12 - z11 ; (c,d) = z22 - z21 ;
+(e,f) = z32 - z31 ; (g,h) = z42 - z41 ;
+\stoptyping
+
+The centers of each square can also be calculated by \METAPOST. The next lines
+define that those points are positioned halfway the extremes.
+
+\starttyping
+z1 = 0.5[z11,z13] ; z2 = 0.5[z21,z23] ;
+z3 = 0.5[z31,z33] ; z4 = 0.5[z41,z43] ;
+\stoptyping
+
+Once we have defined the relations we can let \METAPOST\ solve the equations.
+This is triggered when a variable is needed, for instance when we draw the
+squares and their diagonals. We connect the centers of the squares using a dashed
+line style.
+
+Just to be complete, we add a symbol that marks the right angle. First we
+determine the common point of the two lines, that lays at {\em whatever} point
+\METAPOST\ finds suitable.
+
+The definition of \type {mark_rt_angle} is copied from the \METAPOST\ manual and
+shows how compact a definition can be (see \at {page} [zscaled] for an
+introduction to \type {zscaled}).
+
+\typebuffer[c]
+
+So far, most equations are rather simple, and in order to solve them, \METAPOST\
+did not have to work real hard. The only boundary condition is that in order to
+find a solution, \METAPOST\ must be able to solve all dependencies.
+
+The actual value of the \type {whatever} variable is that it saves us from
+introducing a slew of variables that will never be used again. We could write:
+
+\starttyping
+z0 = A[z1,z3] = B[z2,z4] ;
+\stoptyping
+
+and get the same result, but the \type {whatever} variable saves us the trouble
+of introducing intermediate variables for which we have no use once the
+calculation is finished.
+
+The macro \type{mark_rt_angle} draws the angle symbol and later we will see how
+it is defined. First we draw the labels. Unfortunately we cannot package \typ
+{btex ... etex} into a macro, because it is processed in a rather special way.
+Each \typ {btex ... etex} occurance is filtered from the source and converted
+into a snippet of \TEX\ code. When passed through \TEX, each snippet becomes a
+page, and an auxiliary program converts each page into a \METAPOST\ picture
+definition, which is loaded by \METAPOST. The limitation lays in the fact that
+the filtering is done independent from the \METAPOST\ run, which means that loops
+(and other code) are not seen at all. Later we will introduce the \METAFUN\ way
+around this.
+
+In order to get all the labels typeset, we have to put a lot of code here. The
+macro \type {dotlabel} draws a dot and places the typeset label.
+
+\typebuffer[d]
+
+Watch out: as we are in \CONTEXT, we can pass regular \TEX\ code to the label
+macro. In a standalone \METAPOST\ run you'd have to use the \type {btex} variant.
+
+We are going to draw a lot of pictures, so we define an extra macro. This time we
+hard||code some values. The fractions \type {i} and \type {j} are responsible for
+the visual iteration process, while \type {s} determines the labels. We pass
+these variables to the graphic using an extra argument. When you define the
+(useable) graphic you need to tell what variables it can expect.
+
+\typebuffer[e]
+
+Of course we could have used a loop construct here, but defining auxiliary macros
+probably takes more time than simply calling the drawing macro directly. The
+results are shown on a separate page (\in{figure}[fig:solution]).
+
+\startbuffer[x]
+\def\MyTest#1#2%
+ {\scale
+ [width=.25\textwidth]
+ {\useMPgraphic{solvers::one}{i=#1,j=#2,s=0}}}
+\stopbuffer
+
+\startbuffer[y]
+ \startcombination[3*4]
+ {\MyTest{1.0}{1.0}} {1.0 / 1.0} {\MyTest{0.8}{1.0}} {0.8 / 1.0}
+ {\MyTest{0.6}{1.0}} {0.6 / 1.0} {\MyTest{0.4}{1.0}} {0.4 / 1.0}
+ {\MyTest{0.2}{1.0}} {0.2 / 1.0} {\MyTest{0.0}{1.0}} {0.0 / 1.0}
+ {\MyTest{0.0}{1.0}} {0.0 / 1.0} {\MyTest{0.0}{0.8}} {0.0 / 0.8}
+ {\MyTest{0.0}{0.6}} {0.0 / 0.6} {\MyTest{0.0}{0.4}} {0.0 / 0.4}
+ {\MyTest{0.0}{0.2}} {0.0 / 0.2} {\MyTest{0.0}{0.0}} {0.0 / 0.0}
+ \stopcombination
+\stopbuffer
+
+We will use a helper macro (that saves us typing):
+
+\typebuffer[x]
+
+We now can say:
+
+\typebuffer[y]
+
+Watch how we pass the settings to the graphic definition using an extra argument.
+We force using the \type {solvers} instance by prefixing the name.
+
+\startpostponing
+
+ \startnotmode[screen]
+ \placefigure
+ [here][fig:solution]
+ {The solution.}
+ {\getbuffer[x,y]}
+ \stopnotmode
+
+ \startmode[screen]
+ \placefigure
+ [here][fig:solution]
+ {The solution.}
+ {\getbuffer[x,y]}
+ \stopmode
+
+ \page
+
+\stoppostponing
+
+It does not need that much imagination to see the four sided problem converge to
+a three sided one, which itself converges to a two sided one. In the two sided
+alternative it's not that hard to prove that the angle is indeed 90 degrees.
+
+As soon as you can see a clear pattern in some code, it's time to consider using
+loops. In the previous code, we used semi indexes, like \type {12} in \type
+{z12}. In this case \type{12} does reflect something related to square~1 and~2,
+but in reality the 12 is just twelve. This does not harm our expressions.
+
+A different approach is to use a two dimensional array. In doing so, we can
+access the variables more easily using loops. If we omit the labels, and angle
+macro, the previously defined macro can be reduced considerably.
+
+\starttyping
+def draw_problem (expr n, p, q, r, s) = % number and 4 positions
+ begingroup ; save x, y ;
+
+ z[1][1] = p ; z[2][1] = q ; z[3][1] = r ; z[4][1] = s ;
+
+ for i=1 upto 4 :
+ z[i][1] = (x[i][1],y[i][1]) = z[if i=1: 4 else: i-1 fi][2] ;
+ z[i][2] = (x[i][2],y[i][2]) ;
+ z[i][3] = (x[i][2]-y[i][2]+y[i][1], y[i][2]+x[i][2]-x[i][1]) ;
+ z[i][4] = (x[i][1]-y[i][2]+y[i][1], y[i][1]+x[i][2]-x[i][1]) ;
+ z[i] = 0.5[z[i][1],z[i][3]] ;
+ endfor ;
+
+ z[0] = whatever[z[1],z[3]] = whatever[z[2],z[4]] ;
+
+ pickup pencircle scaled .5pt ;
+
+ for i=1 upto 4 :
+ draw z[i][1]--z[i][2]--z[i][3]--z[i][4]--cycle ;
+ draw z[i][1]--z[i][3] ; draw z[i][2]--z[i][4] ;
+ if i<3 : draw z[i]--z[i+2] dashed evenly fi ;
+ endfor ;
+
+ draw ((1,0)--(1,1)--(0,1))
+ zscaled (unitvector(z[1]-z[0])*10pt)
+ shifted z[0] ;
+
+ endgroup ;
+enddef ;
+\stoptyping
+
+I think that we could argue quite some time about the readability of this code.
+If you start from a sketch, and the series of equations does a good job, there is
+hardly any need for such improvements to the code. On the other hand, there are
+situations where the simplified (reduced) case can be extended more easily, for
+instance to handle 10 points instead of~4. It all depends on how you want to
+spend your free hours.
+
+\stopsection
+
+\startsection[title={Clipping}]
+
+\index{clipping}
+
+For applications that do something with a drawing, for instance \TEX\ embedding a
+graphic in a text flow, it is important to know the dimensions of the graphic.
+The maximum dimensions of a graphic are specified by its bounding box.
+
+\startlinecorrection[blank]
+\startMPcode
+path p ; p := fullcircle scaled 3cm ;
+draw p withpen pencircle scaled 1mm withcolor .625red ;
+draw boundingbox p withpen pencircle scaled .1mm ;
+draw llcorner boundingbox p withpen pencircle scaled 2mm withcolor .625yellow ;
+draw urcorner boundingbox p withpen pencircle scaled 2mm withcolor .625yellow ;
+\stopMPcode
+\stoplinecorrection
+
+A bounding box is defined by its lower left and upper right corners. If you open
+the \POSTSCRIPT\ file produced by \METAPOST, you may find lines like:
+
+\starttyping
+%%BoundingBox: -46 -46 46 46
+\stoptyping
+
+or, when supported,
+
+\starttyping
+%%HiResBoundingBox: -45.35432 -45.35432 45.35432 45.35432
+\stoptyping
+
+The first two numbers define the lower left corner and the last two numbers the
+upper right corner. From these values, you can calculate the width and height of
+the graphic.
+
+A graphic may extend beyond its bounding box. It depends on the application that
+uses the graphic whether that part of the graphic is shown.
+
+In \METAPOST\ you can ask for all four points of the bounding box of a path or
+picture as well as the center.
+
+\starttabulate[|lT|l|]
+\HL
+\NC llcorner p \NC lower left corner \NC \NR
+\NC lrcorner p \NC lower right corner \NC \NR
+\NC urcorner p \NC upper right corner \NC \NR
+\NC ulcorner p \NC upper left corner \NC \NR
+\NC center p \NC the center point \NC \NR
+\HL
+\stoptabulate
+
+You can construct the bounding box of path~\type {p} out of the four points
+mentioned:
+
+\starttyping
+llcorner p -- lrcorner p -- urcorner p -- ulcorner p -- cycle
+\stoptyping
+
+You can set the bounding box of a picture, which can be handy if you want to
+build a picture in steps and show the intermediate results using the same
+dimensions as the final picture, or when you want to show only a small piece.
+
+\startbuffer
+fill fullcircle scaled 2cm withcolor .625yellow ;
+setbounds currentpicture to unitsquare scaled 1cm ;
+draw unitsquare scaled 1cm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+Here, we set the bounding box with the command \type {setbounds}, which takes a
+path.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The graphic extends beyond the bounding box, but the bounding box determines the
+placement and therefore the spacing around the graphic. We can get rid of the
+artwork outside the bounding box by clipping it.
+
+\startbuffer
+fill fullcircle scaled 2cm withcolor .625yellow ;
+clip currentpicture to unitsquare scaled 1cm ;
+\stopbuffer
+
+\typebuffer
+
+The resulting picture is just as large but shows less of the picture.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Some extensions}]
+
+We will now encounter a couple of transformations that can make your life easy
+when you use \METAPOST\ for making graphics like the ones demonstrated in this
+document. These transformations are not part of standard \METAPOST, but come with
+\METAFUN.
+
+A very handy extension is \type {enlarged}. Although you can feed it with any
+path, it will return a rectangle larger or smaller than the boundingbox of that
+path. You can specify a pair or a numeric.
+
+\startbuffer
+path p ; p := fullsquare scaled 2cm ;
+drawpath p ; drawpoints p ;
+p := (p shifted (3cm,0)) enlarged (.5cm,.25cm) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+There are a few more alternatives, like \type {bottomenlarged}, \type
+{rightenlarged}, \type {topenlarged} and \type {leftenlarged}.
+
+The \type {cornered} operator will replace sharp corners by rounded ones (we
+could not use \type {rounded} because this is already in use).
+
+\startbuffer
+path p ; p := ((1,0)--(2,0)--(2,2)--(1,2)--(0,1)--cycle)
+ xysized (4cm,2cm) ;
+drawpath p ; drawpoints p ;
+p := (p shifted (5cm,0)) cornered .5cm ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+The \type {smoothed} operation is a less subtle one, since it operates on the
+bounding box and thereby can result in a different shape.
+
+\startbuffer
+path p ; p := ((1,0)--(2,0)--(2,2)--cycle) xysized (4cm,2cm) ;
+drawpath p ; drawpoints p ;
+p := (p shifted (5cm,0)) smoothed .5cm ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+The next one, \type {simplified}, can be applied to paths that are constructed
+automatically. Instead of testing for duplicate points during construction, you
+can clean up the path afterwards.
+
+\startbuffer
+path p ; p :=
+ ((0,0)--(1,0)--(2,0)--(2,1)--(2,2)--(1,2)--(0,2)--(0,1)--cycle)
+ xysized (4cm,2cm) ;
+drawpath p ; drawpoints p ;
+p := simplified (p shifted (5cm,0)) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+A cousin of the previous operation is \type {unspiked}. This one removes ugly
+left|-|overs. It works well for the average case.
+
+\startbuffer
+path p ; p :=
+ ((0,0)--(2,0)--(3,1)--(2,0)--(2,2)--(1,2)--(1,3)--(1,2)--(0,1)--cycle)
+ xysized (4cm,2cm) ;
+drawpath p ; drawpoints p ;
+p := unspiked (p shifted (5cm,0)) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+There are a couple of operations that manipulate the path in more drastic ways.
+Take \type {randomized}.
+
+\startbuffer
+path p ; p := fullsquare scaled 2cm ;
+drawpath p ; drawpoints p ;
+p := (p shifted (5cm,0)) randomized .5cm ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+Or how about \type {squeezed}:
+
+\startbuffer
+path p ; p := fullsquare scaled 2cm randomized .5cm ;
+drawpath p ; drawpoints p ;
+p := (p shifted (5cm,0)) squeezed .5cm ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+A \type {punked} path is, like a punked font, a font with less smooth curves (in
+our case, only straight lines).
+
+\startbuffer
+path p ; p := fullcircle scaled 2cm randomized .5cm ;
+drawpath p ; drawpoints p ;
+p := punked (p shifted (5cm,0)) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+A \type {curved} path on the other hand has smooth connections. Where in many
+cases a punked path becomes smaller, a curved path will be larger.
+
+\startbuffer
+path p ; p := fullsquare scaled 2cm randomized .5cm ;
+drawpath p ; drawpoints p ;
+p := curved (p shifted (5cm,0)) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+Probably less usefull (although we use it in one of the \OPENTYPE\ visualizers)
+is \type {laddered}:
+
+\startbuffer
+path p ; p := fullcircle scaled 3cm ;
+drawpath p ; drawpoints p ;
+p := laddered (p shifted (5cm,0)) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+When writing \PPCHTEX\ (that can be used to draw chemical structure formulas) I
+needed a parallelizing macro, so here it is:
+
+\startbuffer
+path p ; p := fullcircle scaled 3cm ;
+drawpath p ; drawpoints p ;
+p := p paralleled 1cm ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+If you use a negative argument (like \type {-1cm}) the parallel line will be
+drawn at the other side.
+
+The \type {blownup} operation scales the path but keeps the center in the same
+place.
+
+\startbuffer
+path p ; p := fullsquare xyscaled (4cm,1cm) randomized .5cm ;
+drawpath p ; drawpoints p ;
+p := p blownup .5cm ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+The \type {shortened} operation also scales the path but only makes it longer or
+shorter. This macro only works on straight paths.
+
+\startbuffer
+path p ; p := (0,0) -- (2cm,3cm) ;
+drawpath p ; drawpoints p ;
+p := p shortened 1cm ;
+drawpath p ; drawpoints p ;
+p := p shortened -1cm ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+Here are a few more drawing helpers. Even if you don't need them you might at
+some point take a look at their definitions to see what happens there. First we
+give a square round corners with \type {roundedsquare}:
+
+\startbuffer
+path p ; p := roundedsquare(2cm,4cm,.25cm) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+Next we draw a square|-|like circle (or circle|-|like square) using \type
+{tensecircle}:
+
+\startbuffer
+path p ; p := tensecircle(2cm,4cm,.25cm) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+Often I make such helpers in the process of writing larger drawing systems. Take
+\type {crossed}:
+
+\startbuffer
+path p ; p := origin crossed 1cm ;
+drawpath p ; drawpoints p ;
+p := (origin crossed fullcircle scaled 2cm crossed .5cm) shifted (3cm,0) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+These examples demonstrate that a path is made up out of points (something that
+you probably already knew by now). The \METAPOST\ operator \type {of} can be used
+to \quote {access} a certain point at a curve.
+
+\startbuffer
+path p ; p := fullsquare xyscaled (3cm,2cm) randomized .5cm ;
+drawpath p ; drawpoints p ; drawpointlabels p ;
+draw point 2.25 of p withpen pencircle scaled 5mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+To this we add two more operators: \type {on} and \type {along}. With \type {on}
+you get the point at the supplied distance from point~0; with \type {along} you
+get the point at the fraction of the length of the path.
+
+\startbuffer
+path p, q, r ;
+p := fullsquare xyscaled (2cm,2cm) randomized .5cm ;
+q := p shifted (3cm,0) ; r := q shifted (3cm,0) ;
+drawpath p ; drawpoints p ; drawpointlabels p ;
+drawpath q ; drawpoints q ; drawpointlabels q ;
+drawpath r ; drawpoints r ; drawpointlabels r ;
+pickup pencircle scaled 5mm ;
+draw point 2.25 of p withcolor .625red ;
+draw point 2.50cm on q withcolor .625yellow ;
+draw point .45 along r withcolor .625white ;
+\stopbuffer
+
+\typebuffer
+
+Beware: the \type {length} of a path is the number of points minus one. The
+shapes below are constructed from 5~points and a length of~4. If you want the
+length as dimension, you should use \type {arclength}.
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+We will now play a bit with simple lines. With \type {cutends}, you can (indeed)
+cut off the ends of a curve. The specification is a dimension.
+
+\startbuffer
+path p ; p := (0cm,0cm) -- (4cm,1cm) ;
+path q ; q := (5cm,0cm){right} .. (9cm,1cm) ;
+drawpath p ; drawpoints p ; drawpath q ; drawpoints q ;
+p := p cutends .5cm ; q := q cutends .5cm ;
+drawpathoptions (withpen pencircle scaled 5pt withcolor .625yellow) ;
+drawpointoptions(withpen pencircle scaled 4pt withcolor .625red) ;
+drawpath p ; drawpoints p ; drawpath q ; drawpoints q ;
+resetdrawoptions ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+As with more operators, \type {cutends} accepts a numeric or a pair. Watch the
+subtle difference between the next and the previous use of \type {cutends}.
+
+\startbuffer
+path p ; p := (0cm,0) .. (4cm,0) .. (8cm,0) .. (4cm,0) .. cycle ;
+drawpath p ; drawpoints p ; p := p cutends (2cm,1cm) ;
+drawpathoptions (withpen pencircle scaled 5pt withcolor .625yellow) ;
+drawpointoptions(withpen pencircle scaled 4pt withcolor .625red) ;
+drawpath p ; drawpoints p ;
+resetdrawoptions ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+When \type {stretched} is applied to a path, it is scaled but the starting point
+(point~0) keeps its location. The specification is a scale.
+
+\startbuffer
+path p ; p := (0cm,0) .. (3cm,1cm) .. (4cm,0) .. (5cm,1cm) ;
+drawpath p ; drawpoints p ; p := p stretched 1.1 ;
+drawpathoptions (withpen pencircle scaled 2.5pt withcolor .625yellow) ;
+drawpointoptions(withpen pencircle scaled 4.0pt withcolor .625red) ;
+drawpath p ; drawpoints p ; resetdrawoptions ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+We can scale in two directions independently or even in one direction by
+providing a zero value. In the next example we apply the stretch two times.
+
+\startbuffer
+path p ; p := (0cm,0) .. (3cm,1cm) .. (4cm,0) .. (5cm,1cm) ;
+drawpath p ; drawpoints p ; p := p stretched (.75,1.25) ;
+drawpathoptions (withpen pencircle scaled 2.5pt withcolor .625yellow) ;
+drawpointoptions(withpen pencircle scaled 4.0pt withcolor .625red) ;
+drawpath p ; drawpoints p ; p := p stretched (0,1.5) ;
+drawpathoptions (withpen pencircle scaled 4.0pt withcolor .625red) ;
+drawpointoptions(withpen pencircle scaled 2.5pt withcolor .625yellow) ;
+drawpath p ; drawpoints p ; resetdrawoptions ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+We already met the \type {randomize} operator. This one is the chameleon under
+the operators.
+
+\startbuffer
+draw fullsquare xyscaled (4cm,2cm)
+ randomized .25cm
+ shifted origin randomized (1cm, 2cm)
+ withcolor red randomized (.625, .850)
+ withpen pencircle scaled (5pt randomized 1pt) ;
+\stopbuffer
+
+\typebuffer
+
+So, \type {randomized} can handle a numeric, pair, path and color, and its
+specification can be a numeric, pair or color, depending on what we're dealing
+with.
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+In the previous example we also see \type {xyscaled} in action. Opposite to \type
+{scaled}, \type {xscaled} and \type {yscaled}, this is not one of \METAPOST\
+build in features. The same is true for the \type {.sized} operators.
+
+\startbuffer[a]
+picture p ; p := image
+ ( draw fullsquare
+ xyscaled (300,800)
+ withpen pencircle scaled 50
+ withcolor .625 yellow ; ) ;
+draw p xysized (3cm,2cm) shifted (bbwidth(currentpicture)+.5cm,0) ;
+draw p xysized 2cm shifted (bbwidth(currentpicture)+.5cm,0) ;
+draw p xsized 1cm shifted (bbwidth(currentpicture)+.5cm,0) ;
+draw p ysized 2cm shifted (bbwidth(currentpicture)+.5cm,0) ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startlinecorrection[blank] \processMPbuffer[a] \stoplinecorrection
+
+Here, the \type {image} macro creates an (actually rather large) picture. The
+last four lines actually draw this picture, but at the given dimensions. Watch
+how the line width scales accordingly. If you don't want this, you can add the
+following line:
+
+\startbuffer[b]
+redraw currentpicture withpen pencircle scaled 2pt ;
+draw boundingbox currenpicture withpen pencircle scaled .5mm ;
+\stopbuffer
+
+\typebuffer[b]
+
+Watch how the boundingbox is not affected:
+
+\startlinecorrection[blank] \processMPbuffer[a,b] \stoplinecorrection
+
+In this example we also used \type {bbwidth} (which has a companion macro \type
+{bbheight}). You can apply this macro to a path or a picture.
+
+In fact you don't always need to follow this complex route if you want to simply
+redraw a path with another pen or color.
+
+\startbuffer
+draw fullcircle scaled 1cm
+ withcolor .625red withpen pencircle scaled 1mm ;
+draw currentpicture
+ withcolor .625yellow withpen pencircle scaled 3mm ;
+draw boundingbox currentpicture
+ withpen pencircle scaled .5mm ;
+\stopbuffer
+
+\typebuffer
+
+This is what you will get from this:
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+If you want to add a background color to a picture you can do that afterwards.
+This can be handy when you don't know in advance what size the picture will have.
+
+\startbuffer
+fill fullcircle scaled 1cm withcolor .625red ;
+addbackground withcolor .625 yellow ;
+\stopbuffer
+
+\typebuffer
+
+The background is just a filled rectangle that gets the same size as the current
+picture, that is put on top of it.
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+\stopsection
+
+\startsection[title={Cutting and pasting}]
+
+\index{paths+cutting}
+\index{cutting}
+
+When enhancing or building a graphic, often parts of already constructed paths
+are needed. The \type {subpath}, \type {cutbefore} and \type {cutafter} operators
+can be used to split paths in smaller pieces. In order to do so, we must know
+where we are on the path that is involved. For this we use points on the path.
+Unfortunately we can only use these points when we know where they are located.
+In this section we will combine some techniques discussed in previous sections.
+We will define a few macros, manipulate some paths and draw curves and points.
+
+\startbuffer
+path p ; p := fullcircle yscaled 3cm xscaled .9TextWidth ;
+drawpath p ; drawpoints p withcolor .625red ; drawpointlabels p ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+This circle is drawn by scaling the predefined path \type {fullcircle}. This path
+is constructed using 8~points. As you can see, these points are not distributed
+equally along the path. In the following graphic, the second and third point of
+the curve are colored red, and point 2.5 is colored yellow. Point~0 is marked in
+black. This point is positioned halfway between point~2 and~3.
+
+\startbuffer
+path p ; p := fullcircle scaled 3cm xscaled 2 ;
+pickup pencircle scaled 5mm ; autoarrows := true ;
+drawarrow p withcolor .625white ;
+draw point 0.0 of p ;
+draw point 2.0 of p withcolor .625red ;
+draw point 2.5 of p withcolor .625yellow ;
+draw point 3.0 of p withcolor .625red ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+It is clear that, unless you know exactly how the path is constructed, other
+methods should be available. A specific point on a path is accessed by \typ
+{point ... of}, but the next example demonstrates two more alternatives.
+
+\startbuffer
+path p ; p := fullcircle scaled 3cm xscaled 2 ;
+pickup pencircle scaled 5mm ;
+draw p withcolor .625white ;
+draw point 3 of p withcolor .625red ;
+draw point .6 along p withcolor .625yellow ;
+draw point 3cm on p ;
+\stopbuffer
+
+\typebuffer
+
+So, in addition to \type {on} to specify a point by number (in \METAPOST\
+terminology called time), we have \type {along} to specify a point as fraction of
+the path, and \type {on} to specify the position in a dimension.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The \type {on} and \type {along} operators are macros and can be defined as:
+
+\starttyping
+primarydef len on pat =
+ (arctime len of pat) of pat
+enddef ;
+
+primarydef pct along pat =
+ (arctime (pct * (arclength pat)) of pat) of pat
+enddef ;
+\stoptyping
+
+These macros introduce two new primitives, \type {arctime} and \type {arclength}.
+While \type {arctime} returns a number denoting the time of the point on the
+path, \type {arclength} returns a dimension.
+
+\quotation {When mathematicians draw parametric curves, they frequently need to
+indicate the direction of motion. I often have need of a little macro that will
+put an arrow of requested length, anchored at a point on the curve, and bending
+with the curve in the direction of motion.}
+
+When David Arnold asked me how this could be achieved, the fact that a length was
+requested meant that the solution should be sought in using the primitives and
+macros we introduced a few paragraphs before. Say that we want to call for such
+an arrow as follows.
+
+\startbuffer[a]
+path p ; p := fullcircle scaled 3cm ;
+pair q ; q := point .4 along p ;
+pickup pencircle scaled 2mm ;
+draw p withcolor .625white ;
+drawarrow somearrow(p,q,2cm) withcolor .625red ;
+draw q withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer[a]
+
+Because we want to follow the path, we need to construct the arrow from this
+path. Therefore, we first reduce the path by cutting off the part before the
+given point. Next we cut off the end of the resulting path so that we keep a
+slice that has the length that was asked for. Since we can only cut at points, we
+determine this point using the \type {arctime} primitive.
+
+\startbuffer[b]
+vardef somearrow (expr pat, loc, len) =
+ save p ; path p ; p := pat cutbefore loc ;
+ (p cutafter point (arctime len of p) of p)
+enddef ;
+\stopbuffer
+
+\typebuffer[b]
+
+By using a \type {vardef} we hide the intermediate assignments. Such \type
+{vardef} is automatically surrounded by \type {begingroup} and \type {endgroup},
+so the \type {save} is local to this macro. When processed, this code produces
+the following graphic:
+
+\startbuffer[c]
+autoarrows := true ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[c,b,a]
+\stoplinecorrection
+
+This graphic shows that we need a bit more control over the exact position of the
+arrow. It would be nice if we could start the arrow at the point, or end there,
+or center the arrow around the point. Therefore, the real implementation is a bit
+more advanced.
+
+\startbuffer
+vardef pointarrow (expr pat, loc, len, off) =
+ save l, r, s, t ; path l, r ; numeric s ; pair t ;
+ t := if pair loc : loc else : point loc along pat fi ;
+ s := len/2 - off ; if s<=0 : s := 0 elseif s>len : s := len fi ;
+ r := pat cutbefore t ;
+ r := (r cutafter point (arctime s of r) of r) ;
+ s := len/2 + off ; if s<=0 : s := 0 elseif s>len : s := len fi ;
+ l := reverse (pat cutafter t) ;
+ l := (reverse (l cutafter point (arctime s of l) of l)) ;
+ (l..r)
+enddef ;
+\stopbuffer
+
+\typebuffer
+
+This code fragment also demonstrates how we can treat the \type {loc} argument as
+pair (coordinates) or fraction of the path. We calculate the piece of path before
+and after the given point separately and paste them afterwards as \type {(l..r)}.
+By adding braces we can manipulate the path in expressions without the danger of
+handling \type {r} alone.
+
+We can now implement left, center and right arrows by providing this macro the
+right parameters. The offset (the fourth parameter), is responsible for a
+backward displacement. This may seem strange, but negative values would be even
+more confusing.
+
+\startbuffer
+def rightarrow (expr p,t,l) = pointarrow(p,t,l,-l) enddef ;
+def leftarrow (expr p,t,l) = pointarrow(p,t,l,+l) enddef ;
+def centerarrow(expr p,t,l) = pointarrow(p,t,l, 0) enddef ;
+\stopbuffer
+
+\typebuffer
+
+We can now apply this macro as follows:
+
+\startbuffer[a]
+path p ; p := fullcircle scaled 3cm ;
+pickup pencircle scaled 2mm ;
+draw p withcolor .625white ;
+drawarrow leftarrow (p, .4 ,2cm) withcolor .625red ;
+drawarrow centerarrow(p,point 5 of p,2cm) withcolor .625yellow ;
+draw point .4 along p withcolor .625yellow ;
+draw point 5 of p withcolor .625red ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+Watch how we can pass a point (\typ {point 5 of p}) as well as a fraction (\type
+{.4}). The following graphic demonstrates a few more alternatives.
+
+\startbuffer[a]
+pickup pencircle scaled 2mm; autoarrows := true ;
+
+path p ; p := fullcircle yscaled 3cm xscaled .9TextWidth ;
+
+draw p withcolor .5white;
+
+for i=1, 2, 3 :
+ drawdot point i of p withpen pencircle scaled 5mm withcolor .625white ;
+endfor ;
+for i=.60, .75, .90 :
+ drawdot point i along p withpen pencircle scaled 5mm withcolor .625white ;
+endfor ;
+\stopbuffer
+
+\startbuffer[b]
+drawarrow leftarrow (p,point 1 of p,2cm) withcolor red ;
+drawarrow centerarrow (p,point 2 of p,2cm) withcolor blue ;
+drawarrow rightarrow (p,point 3 of p,2cm) withcolor green ;
+drawarrow pointarrow (p,.60,4cm,+.5cm) withcolor yellow ;
+drawarrow pointarrow (p,.75,3cm,-.5cm) withcolor cyan ;
+drawarrow centerarrow (p,.90,3cm) withcolor magenta ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+The arrows are drawn using the previously defined macros. Watch the positive and
+negative offsets in call to \type {pointarrow}.
+
+\typebuffer[b]
+
+\stopsection
+
+\startsection[title={Current picture}]
+
+\index {pictures}
+
+When you draw paths, texts and|/|or pictures they are added to the so called
+current picture. You can manipulate this current picture as is demonstrated in
+this manual. Let's show a few current picture related tricks.
+
+\startbuffer
+ draw fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer \startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+We can manipulate the picture as a whole:
+
+\startbuffer
+ draw fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625red ;
+ currentpicture := currentpicture slanted .5 ;
+\stopbuffer
+
+\typebuffer \startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+Sometimes it's handy to temporarily set aside the current picture.
+
+\startbuffer
+ draw fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625red ;
+ currentpicture := currentpicture slanted .5 ;
+ pushcurrentpicture ;
+ draw fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625yellow ;
+ currentpicture := currentpicture slanted -.5 ;
+ popcurrentpicture ;
+\stopbuffer
+
+\typebuffer \startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+These are \METAFUN\ commands but \METAPOST\ itself comes with a variant, \type
+{image}, and you explicitly have to draw this picture (or otherwise add it to the
+currentpicture).
+
+\startbuffer
+ draw fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625red ;
+ currentpicture := currentpicture slanted .5 ;
+ draw image (
+ draw fullcircle scaled 1cm
+ withpen pencircle scaled 1mm withcolor .625yellow ;
+ currentpicture := currentpicture slanted -.5 ;
+ ) ;
+\stopbuffer
+
+\typebuffer \startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+Each graphic starts fresh with an empty current picture. In \METAFUN\ we make
+sure that we also reset some otherwise global variables, like color, pen and some
+line properties.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun.tex b/doc/context/sources/general/manuals/metafun/metafun.tex
new file mode 100644
index 000000000..dc90bb611
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun.tex
@@ -0,0 +1,108 @@
+% language=uk macros=mkvi
+
+% author : Hans Hagen
+% copyright : PRAGMA ADE & ConTeXt Development Team
+% license : Creative Commons Attribution ShareAlike 4.0 International
+% reference : pragma-ade.nl | contextgarden.net | texlive (related) distributions
+% origin : the ConTeXt distribution
+%
+% comment : Because this manual is distributed with TeX distributions it comes with a rather
+% liberal license. We try to adapt these documents to upgrades in the (sub)systems
+% that they describe. Using parts of the content otherwise can therefore conflict
+% with existing functionality and we cannot be held responsible for that. Many of
+% the manuals contain characteristic graphics and personal notes or examples that
+% make no sense when used out-of-context.
+%
+% comment : Some chapters might have been published in TugBoat, the NTG Maps, the ConTeXt
+% Group journal or otherwise. Thanks to the editors for corrections. Also thanks
+% to users for testing, feedback and corrections.
+%
+% comment : This manual was originally written for MkII and as a consequence many examples
+% are coded in a bit different way than we would nowadays do in MkIV. But, as we
+% try to be downward compatible, it doesn't hurt.
+%
+% comment : I also use this manual for benchmarking ConTeXt MkIV. On my current machine (a
+% 2013 dell i7 laptop) one run takes some 18.1 seconds for LuaTeX and around 14.2
+% seconds for LuajitTeX which is quite okay given the amount of graphics (428
+% pages).
+%
+% comment : This is one of the manuals that can be ordered at http://www.h2o-books.com and
+% it's actually meant to be read on paper.
+
+\enabledirectives[hyphenator.optimize]
+\enabledirectives[hyphenator.flatten]
+% \setuphyphenation[method=traditional]
+
+% \enabletrackers[*defin*]
+
+% \enablemode[screen]
+\enablemode[print]
+% \enablemode[book]
+
+% \usemodule[luacalls]
+
+% todo: check startintro .. stopintro each chapter
+
+% \showframe
+
+\startproduct metafun
+
+\environment metafun-environment
+
+\startnotmode[screen]
+ \component metafun-titlepage-paper
+ \component metafun-colofon-paper
+\stopnotmode
+
+\startmode[screen]
+ \environment metafun-environment-screen
+ \component metafun-titlepage-screen
+\stopmode
+
+\startfrontmatter
+ \component metafun-introduction
+ \component metafun-contents
+ \component metafun-conventions
+\stopfrontmatter
+
+\startbodymatter
+ \component metafun-welcome
+ \component metafun-basics
+ \component metafun-embedding
+ \component metafun-layout
+ \component metafun-positioning
+ \component metafun-backgrounds
+ \component metafun-gadgets
+ \component metafun-effects
+ \component metafun-functions
+ \component metafun-text
+ \component metafun-debugging
+ \component metafun-styles
+ \component metafun-examples
+ \component metafun-macros
+ \component metafun-lua
+ %component metafun-graphics
+ \component metafun-sneaky
+\stopbodymatter
+
+\startappendices
+ % \component metafun-programs
+ \component metafun-syntax
+ \component metafun-document
+ \component metafun-reference
+ % \component metafun-literature
+\stopappendices
+
+\startbackmatter
+ \component metafun-index
+\stopbackmatter
+
+\startmode[screen]
+ \component metafun-colofon-screen
+\stopmode
+
+\startnotmode[screen]
+ \component metafun-backpage
+\stopnotmode
+
+\stopproduct
diff --git a/doc/context/sources/general/manuals/metafun/mfun-700.tex b/doc/context/sources/general/manuals/metafun/mfun-700.tex
new file mode 100644
index 000000000..e393a34f3
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-700.tex
@@ -0,0 +1,17 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\starttext
+
+\TitlePage
+ {A Few Nice Quotes\\
+ A Simple Style Demo\\
+ Hans Hagen, August 2000}
+
+\Topic {Douglas R. Hofstadter} \input douglas \page
+\Topic {Donald E. Knuth} \input knuth \page
+\Topic {Edward R. Tufte} \input tufte \page
+\Topic {Hermann Zapf} \input zapf \page
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/metafun/mfun-771.tex b/doc/context/sources/general/manuals/metafun/mfun-771.tex
new file mode 100644
index 000000000..460c16f2a
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-771.tex
@@ -0,0 +1,9 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\usemodule[present-organic]
+
+\setupMPvariables[page][alternative=1]
+
+\input mfun-700
diff --git a/doc/context/sources/general/manuals/metafun/mfun-772.tex b/doc/context/sources/general/manuals/metafun/mfun-772.tex
new file mode 100644
index 000000000..99dec1551
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-772.tex
@@ -0,0 +1,9 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\usemodule[present-organic]
+
+\setupMPvariables[page][alternative=2]
+
+\input mfun-700
diff --git a/doc/context/sources/general/manuals/metafun/mfun-773.tex b/doc/context/sources/general/manuals/metafun/mfun-773.tex
new file mode 100644
index 000000000..daefcfe66
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-773.tex
@@ -0,0 +1,9 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\usemodule[present-organic]
+
+\setupMPvariables[page][alternative=3]
+
+\input mfun-700
diff --git a/doc/context/sources/general/manuals/metafun/mfun-774.tex b/doc/context/sources/general/manuals/metafun/mfun-774.tex
new file mode 100644
index 000000000..725d1199b
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-774.tex
@@ -0,0 +1,103 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\usemodule[present-organic]
+
+\setupMPvariables[page][alternative=1]
+
+\startuseMPgraphic{page}
+
+ \includeMPgraphic{rightsuperbutton}
+
+ StartPage ;
+
+ path p, q ;
+
+ p := Field[Text][Text] enlarged 36pt superellipsed .90 ;
+
+ fill Page
+ withcolor \MPcolor{yellow} ;
+ fill p
+ withcolor \MPcolor{white} ;
+ draw p
+ dashed dashpattern (on 9pt off 9pt)
+ withpen pencircle scaled 3pt
+ withcolor \MPcolor{red} ;
+
+ p := Field[Text][Text] enlarged 48pt superellipsed .90 ;
+
+ draw p
+ dashed dashpattern (on 9pt off 9pt)
+ withpen pencircle scaled 1.5pt ;
+
+ def right_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) =
+ if (pp>0) and (rr>0) :
+ q := rightsuperbutton(p,xx,yy,RightEdgeWidth,hh) ;
+ fill q
+ withcolor \MPcolor{white} ;
+ draw ptop
+ withpen pencircle scaled 1.5pt ;
+ draw pbot
+ withpen pencircle scaled 1.5pt ;
+ draw q
+ dashed dashpattern (on 9pt off 9pt)
+ withpen pencircle scaled 3pt
+ withcolor if rr=2 : \MPcolor{gray} else : \MPcolor{red} fi ;
+ fi ;
+ enddef ;
+
+ \MPmenubuttons{right}
+
+ StopPage ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{rightsuperbutton}
+
+vardef rightsuperbutton (expr pat, xpos, ypos, wid, hei) =
+
+ save p, t, b, edge, shift, width, height ;
+ path p, ptop, pbot ; pair t, b ; numeric edge, shift, width, height ;
+
+ edge := xpos + wid ; shift := ypos + hei ;
+
+ p := rightpath pat ;
+
+draw p withpen pencircle scaled 1.5pt ;
+
+ ptop := ((-infinity,shift)--(edge,shift)) ;
+ pbot := ((-infinity,shift-hei)--(edge,shift-hei)) ;
+
+ t := p intersectionpoint ptop ;
+ b := p intersectionpoint pbot ;
+
+ label.llft("t",t) ;
+ label.ulft("b",b) ;
+
+ p := subpath(0,xpart (p intersectiontimes ptop)) of p ;
+ p := subpath(xpart (p intersectiontimes pbot),length(p)) of p ;
+
+ (p -- t -- point 1 of ptop &
+ point 1 of ptop -- point 1 of pbot &
+ point 1 of pbot -- b
+ -- cycle)
+
+enddef ;
+
+\stopuseMPgraphic
+
+
+
+\starttext
+
+\TitlePage
+ {A Few Nice Quotes\\
+ A Simple Style Demo\\
+ Hans Hagen, August 2000}
+
+\Topic {Douglas R. Hofstadter} \input douglas \page
+\Topic {Donald E. Knuth} \input knuth \page
+\Topic {Edward R. Tufte} \input tufte \page
+\Topic {Hermann Zapf} \input zapf \page
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/metafun/mfun-775.tex b/doc/context/sources/general/manuals/metafun/mfun-775.tex
new file mode 100644
index 000000000..e9d2b85a7
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-775.tex
@@ -0,0 +1,9 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\usemodule[present-organic]
+
+\setupMPvariables[page][alternative=11]
+
+\input mfun-700
diff --git a/doc/context/sources/general/manuals/metafun/mfun-776.tex b/doc/context/sources/general/manuals/metafun/mfun-776.tex
new file mode 100644
index 000000000..82b5c18dd
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-776.tex
@@ -0,0 +1,9 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\usemodule[present-organic]
+
+\setupMPvariables[page][alternative=12]
+
+\input mfun-700
diff --git a/doc/context/sources/general/manuals/metafun/mfun-800.tex b/doc/context/sources/general/manuals/metafun/mfun-800.tex
new file mode 100644
index 000000000..aa0c1260f
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-800.tex
@@ -0,0 +1,27 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\setupMPpage
+ [offset=1pt,
+ background=color,
+ backgroundcolor=gray]
+
+\definecolor [gray] [s=.625]
+\definecolor [red] [r=.625]
+\definecolor [yellow] [r=.625,g=.625]
+
+\startuseMPgraphic{test}
+ fill fullsquare rotated 45 scaled 4cm
+ withcolor \MPcolor{yellow} ;
+\stopuseMPgraphic
+
+\starttext
+
+\startMPpage
+ \includeMPgraphic{test}
+ fill fullcircle scaled 3cm
+ withcolor \MPcolor{red} ;
+\stopMPpage
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/metafun/mfun-900.tex b/doc/context/sources/general/manuals/metafun/mfun-900.tex
new file mode 100644
index 000000000..c295ec908
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-900.tex
@@ -0,0 +1,48 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent mfun-900
+
+\environment metafun-environment
+
+% Page 1
+
+\getbuffer[pagetext]
+
+% Page 2/3
+
+\getbuffer[back-0,back-1,pagetext]
+\getbuffer[back-0,back-1,pagetext]
+
+\setupbackgrounds[page][background=]
+
+% Page 4/5
+
+\getbuffer[back-0,back-2,pagetext]
+\getbuffer[back-0,back-2,pagetext]
+
+\setupbackgrounds[page][background=]
+
+% Page 6/7
+
+\getbuffer[back-0,back-3,pagetext]
+\getbuffer[back-0,back-3,pagetext]
+
+\setupbackgrounds[page][background=]
+
+% Page 8/9
+
+\getbuffer[back-0,back-4,pagetext]
+\getbuffer[back-0,back-4,pagetext]
+
+\setupbackgrounds[page][background=]
+
+% Page 10/11
+
+\getbuffer[back-0,back-5,pagetext]
+\getbuffer[back-0,back-5,pagetext]
+
+\setupbackgrounds[page][background=]
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/mfun-901.tex b/doc/context/sources/general/manuals/metafun/mfun-901.tex
new file mode 100644
index 000000000..23adf77b4
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-901.tex
@@ -0,0 +1,11 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent mfun-901
+
+\environment metafun-environment
+
+\getbuffer[gridpage]
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/mfun-902.tex b/doc/context/sources/general/manuals/metafun/mfun-902.tex
new file mode 100644
index 000000000..7c4fed73e
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-902.tex
@@ -0,0 +1,11 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent mfun-902
+
+\environment metafun-environment
+
+\getbuffer[handwrit]
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/mfun-mrun-demo.mp b/doc/context/sources/general/manuals/metafun/mfun-mrun-demo.mp
new file mode 100644
index 000000000..c6589beb5
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-mrun-demo.mp
@@ -0,0 +1,212 @@
+%D Downloading
+
+beginfig (1) ;
+
+ path p, q ;
+
+ p := (0,110)..(50,110) shifted (0,-15)..(100,110)--
+ (50,50) shifted (10,0) ..(50,50) shifted (0,2.5)..
+ (50,50) shifted(-10,0)--cycle ;
+ q := (5,0)--(95,0)--(95,30)..(50,0) shifted (0,10)..(5,30)--cycle ;
+
+ pickup pencircle scaled 15 ;
+ drawdot (80,100) withcolor .6red ;
+ drawdot (65,95) withcolor .6red ;
+ drawdot (50,95) withcolor .6red ;
+ drawdot (35,95) withcolor .6red ;
+
+ drawdot (50,60) withcolor .6red ;
+ drawdot (50,35) withcolor .6red ;
+ drawdot (50,10) withcolor .6red ;
+ drawdot (70,10) withcolor .6red ;
+ drawdot (32.5,10) withcolor .6red ;
+
+ pickup pencircle scaled 5 ;
+ fill p withcolor .6green ; draw p withcolor .4green ;
+ fill q withcolor .6green ; draw q withcolor .4green ;
+
+ bboxmargin := 2.5 ; p := bbox currentpicture ;
+ picture s ; s := currentpicture ; currentpicture := nullpicture ;
+
+ pickup pencircle scaled 2.5 ;
+ fill p withcolor .4blue ;
+ addto currentpicture also s ;
+
+endfig ;
+
+%D WWW Links
+
+beginfig (2) ;
+
+ boolean angles [], lengths[], colors [][][] ;
+ numeric a, l, r, g, b, n ;
+ path p ;
+ color c ;
+
+ draw fullsquare scaled 150 withpen pencircle scaled 1 withcolor .5white ;
+
+ n := 0 ;
+ forever :
+ a := 6 * round(uniformdeviate 60) ;
+ l := 40 + round(uniformdeviate 60) ;
+ r := 2 + round(uniformdeviate 6) ;
+ g := 2 + round(uniformdeviate 6) ;
+ b := 2 + round(uniformdeviate 6) ;
+ if (a>0) and not known angles [a] and not known lengths[l] and not known colors [r][g][b] :
+ n := n + 1 ;
+ angles [a] := true ;
+ lengths[l] := true ;
+ colors [r][g][b] := true ;
+ p := (origin--origin shifted (0,.5l)) rotatedaround(origin,a) ;
+ draw p withpen pencircle scaled 2 withcolor (r/10,g/10,b/10) ;
+ drawdot point 1 of p withpen pencircle scaled 4 withcolor (r/10,g/10,b/10) ;
+ p := (origin shifted (0,.5l+8)--origin shifted(0,100)) rotatedaround(origin,a) ;
+ draw p withpen pencircle scaled 2 withcolor (r/10,g/10,b/10) ;
+ drawdot point 0 of p withpen pencircle scaled 4 withcolor (r/10,g/10,b/10) ;
+ fi ;
+ exitif n >= 60 ;
+ endfor ;
+
+ drawdot
+ origin
+ withpen pencircle scaled 10
+ withcolor white ;
+
+ fill
+ ((fullcircle scaled 130) peepholed (fullsquare scaled 150))
+ withcolor (1,1,1)-(1,.62,.06);
+
+ clip currentpicture to fullsquare scaled 130 ;
+
+endfig ;
+
+%D Mirrors
+
+beginfig(3)
+
+ path a, b, p, q ;
+ pair s, t, u, v ;
+ color c ;
+ numeric h, w, r ;
+
+ pickup pencircle scaled 10 ;
+
+ h := 120 ;
+ w := 80 ;
+ r := 30 ;
+
+ a := (0,0)..(0,.5h) shifted (-r,0)..(0,h) ;
+ b := (w,0)..(w,.5h) shifted ( r,0)..(w,h) ;
+
+ draw a withcolor .4white;
+ draw b withcolor .4white;
+
+ def moved (expr i) =
+ ((i) - 10 + uniformdeviate 20)
+ enddef ;
+
+ for i=5 step 10 until h-5 :
+ s := (point (length(a)*(i/h)) of a) ;
+ t := (point (length(b)*(1-i/h)) of b) ;
+ u := (s--t) intersectionpoint ((.25w,0)--(.25w,h)) ;
+ v := (s--t) intersectionpoint ((.75w,0)--(.75w,h)) ;
+ p := s..(xpart u,moved(ypart u))..(xpart v,moved(ypart v))..t ;
+ c := (0,.4+uniformdeviate.55,0) ;
+ l := length(p) ;
+ l := .25l+uniformdeviate.5l ;
+ q := p cutafter point l of p ;
+ pickup pencircle scaled 2.5 ;
+ draw p withcolor c ;
+ pickup pencircle scaled 5 ;
+ drawdot point 0 of p withcolor c ;
+ drawdot point infinity of p withcolor c ;
+ endfor ;
+
+ picture s ; s := currentpicture ; currentpicture := nullpicture ;
+
+ bboxmargin := 2.5 ; fill bbox s withcolor .85white ;
+
+ addto currentpicture also s ;
+
+endfig;
+
+%D Team
+
+def dpuppet (expr v, w) =
+ v - .5w + uniformdeviate w
+enddef ;
+
+def somepuppet (expr s, r) =
+ picture p ; p := currentpicture ; currentpicture := nullpicture ;
+ draw ((-10,0)--(10,0)) ;
+ for i:=-10 step 5 until 10 :
+ draw ((i,0)--(dpuppet(i,2),-10)) ;
+ endfor ;
+ currentpicture := currentpicture rotated r shifted s ;
+ addto currentpicture also p ;
+enddef ;
+
+def puppet (expr loc, sca, col) =
+ picture s ; s := currentpicture ; currentpicture := nullpicture ;
+
+ pair a ; a := (dpuppet( 20,5),dpuppet( 0, 5)) ;
+ pair b ; b := (dpuppet(-20,5),dpuppet( 0, 5)) ;
+ pair c ; c := (dpuppet( 30,5),dpuppet(60,10)) ;
+ pair d ; d := (dpuppet(-30,5),dpuppet(60,10)) ;
+ pair e ; e := (dpuppet( 0,5),dpuppet(30,10)) ;
+ pair f ; f := (dpuppet( 0,5),dpuppet(50,10)) ;
+ pair g ; g := (dpuppet( 0,5),dpuppet(65,10)) ;
+
+ pair f ; f := (.6+uniformdeviate.1)[e,g] ;
+
+ drawoptions (withcolor col) ;
+
+ somepuppet(a,dpuppet( 20,5)) ;
+ somepuppet(b,dpuppet( -20,5)) ;
+ somepuppet(c,dpuppet( 120,5)) ;
+ somepuppet(d,dpuppet(-120,5)) ;
+
+ draw a -- e ;
+ draw b -- e ;
+ draw c -- f ;
+ draw d -- f ;
+ draw e -- g ;
+ draw fullcircle scaled 25 shifted (g shifted (0,12.5));
+
+ drawoptions () ;
+
+ currentpicture := currentpicture scaled sca shifted loc ;
+ addto currentpicture also s ;
+enddef ;
+
+beginfig (4) ;
+
+ pickup pencircle scaled 0 ;
+
+ color col ; col := (.4,.8,.6) ;
+
+ puppet((-20, 0) ,.20, 0.700col) ;
+ puppet(( 10,10) ,.30, 0.750col) ;
+ puppet(( 30,20) ,.40, 0.800col) ;
+ puppet((-20,30) ,.35, 0.850col) ;
+ puppet(( 20,60) ,.20, 0.900col) ;
+ puppet(( -5,65) ,.25, 0.950col) ;
+
+ picture s ; s := currentpicture ; currentpicture := nullpicture ;
+
+ bboxmargin := 15 ; fill bbox s withcolor .8(1,1,0) ;
+
+ addto currentpicture also s withpen pencircle scaled .8 ;
+
+ path b ; bboxmargin := -10 ; b := bbox currentpicture ;
+ numeric len ; len := length(b) ;
+ numeric stp ; stp := 20 ;
+ drawoptions(withpen pencircle scaled .8 withcolor .7red) ;
+ for i=len/8stp step len/4stp until len+len/8stp :
+ pair ii ; ii := point (dpuppet(i,len/20stp)) of b ;
+ pair dd ; dd := (direction i of b) rotated (dpuppet(-90,10)) ;
+ draw ii shifted -.1dd withpen pencircle scaled 1.2 ;
+ draw ii--(ii shifted .25dd) ;
+ endfor ;
+
+endfig ;
diff --git a/doc/context/sources/general/manuals/metafun/mycow.mp b/doc/context/sources/general/manuals/metafun/mycow.mp
new file mode 100644
index 000000000..24c3e0f7d
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mycow.mp
@@ -0,0 +1,299 @@
+% Converted from PostScript(TM) to MetaPost by pstoedit
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+% MetaPost backend contributed by Scott Pakin <pakin@uiuc.edu>
+% pstoedit is Copyright (C) 1993 - 1999 Wolfgang Glunz <wglunz@geocities.com>
+
+% Generate structured PostScript
+prologues := 1;
+
+% Display a given string with its *baseline* at a given location
+% and with a given rotation angle
+vardef showtext(expr origin)(expr angle)(expr string) =
+ draw string infont defaultfont scaled defaultscale
+ rotated angle shifted origin;
+enddef;
+
+beginfig(1);
+drawoptions (withcolor (1,1,1));
+fill (84.3799,618.55)..controls (88.3398,624.38) and (92.5898,622.94)..(96.3398,615.67)
+ ..controls (101.23,615.6) and (102.46,612.43)..(104.98,610.78)
+ ..controls (122.62,598.39) and (147.46,607.18)..(167.9,601.92)
+ ..controls (180.94,598.54) and (190.87,599.76)..(200.09,602.06)
+ ..controls (220.32,607.25) and (246.1,596.16)..(263.74,603.86)
+ ..controls (274.75,608.62) and (284.76,605.66)..(292.97,600.91)
+ ..controls (297.58,597.96) and (299.59,596.09)..(300.96,591.26)
+ ..controls (306.29,572.54) and (306.29,551.02)..(309.53,530.57)
+ ..controls (309.53,528.84) and (312.19,526.1)..(312.48,522.07)
+ ..controls (315.79,511.34) and (316.08,510.12)..(317.16,502.2)
+ ..controls (317.16,501.34) and (326.52,488.45)..(325.01,479.02)
+ ..controls (323.93,481.25) and (323.86,482.83)..(321.62,481.68)
+ ..controls (320.33,479.3) and (320.9,473.9)..(322.56,471.74)
+ ..controls (320.83,470.81) and (318.46,473.47)..(317.52,475.2)
+ ..controls (318.17,473.04) and (317.81,470.81)..(316.73,469.3)
+ ..controls (315.86,472.25) and (316.58,473.18)..(315.36,473.9)
+ ..controls (313.99,472.9) and (314.21,469.3)..(314.28,466.2)
+ ..controls (313.49,468.07) and (311.47,472.46)..(312.55,476.42)
+ ..controls (312.48,484.2) and (308.81,489.1)..(310.32,499.1)
+ ..controls (310.1,504.43) and (307.3,521.06)..(304.56,524.3)
+ ..controls (303.12,526.25) and (306.36,510.77)..(306.36,506.16)
+ ..controls (306.65,500.9) and (307.08,468.72)..(306.43,463.1)
+ ..controls (306.43,459.22) and (306.22,453.96)..(307.08,452.16)
+ ..controls (308.74,450.79) and (309.38,450.5)..(309.6,447.98)
+ ..controls (309.24,446.62) and (308.74,446.04)..(307.73,445.54)
+ ..controls (306.07,444.6) and (307.37,441.79)..(306.07,439.85)
+ ..controls (304.49,438.77) and (304.13,441.86)..(303.34,441.86)
+ ..controls (302.69,441) and (303.05,437.98)..(302.47,436.18)
+ ..controls (299.66,433.8) and (292.18,432.5)..(289.15,434.66)
+ ..controls (289.73,440.64) and (291.74,441.58)..(295.63,446.62)
+ ..controls (298.66,452.59) and (297,460.94)..(296.93,468.14)
+ ..controls (295.49,480.38) and (289.22,487.3)..(289.44,496.44)
+ ..controls (287.86,495.72) and (286.42,494.57)..(284.26,494.86)
+ ..controls (283.39,489.46) and (286.42,484.56)..(284.83,480.82)
+ ..controls (281.95,471.96) and (277.06,446.62)..(279,437.76)
+ ..controls (280.01,434.74) and (278.21,433.15)..(277.06,433.94)
+ ..controls (276.77,433.94) and (276.55,433.94)..(276.41,433.94)
+ ..controls (276.41,433.94) and (276.55,431.42)..(275.69,430.92)
+ ..controls (274.1,430.34) and (273.67,431.71)..(272.66,432.14)
+ ..controls (271.22,430.85) and (272.52,429.48)..(271.15,428.04)
+ ..controls (267.19,428.04) and (261.36,425.38)..(257.98,428.26)
+ ..controls (257.33,434.16) and (263.3,436.68)..(266.47,440.71)
+ ..controls (268.63,446.62) and (271.08,462.89)..(267.77,474.62)
+ ..controls (267.77,475.56) and (264.38,485.28)..(261.43,488.66)
+ ..controls (258.7,487.66) and (257.33,485.5)..(253.22,486.29)
+ ..controls (252.58,484.34) and (253.3,482.33)..(252.22,480.1)
+ ..controls (251.86,479.52) and (249.34,478.58)..(249.19,481.39)
+ ..controls (248.98,483.05) and (248.9,486.36)..(248.26,486.72)
+ ..controls (243.65,486.72) and (233.71,487.08)..(231.77,493.92)
+ ..controls (219.89,492.34) and (215.93,491.26)..(206.57,493.42)
+ ..controls (196.63,489.67) and (183.24,506.16)..(174.53,502.2)
+ ..controls (172.51,496.15) and (173.09,485.64)..(171.65,481.39)
+ ..controls (169.34,474.77) and (171.14,467.14)..(171.14,456.41)
+ ..controls (170.57,455.4) and (169.85,454.46)..(168.48,454.46)
+ ..controls (168.48,453.1) and (169.34,450.86)..(168.62,449.42)
+ ..controls (167.18,447.62) and (165.89,451.8)..(165.02,444.6)
+ ..controls (163.15,443.74) and (157.75,442.22)..(155.59,445.18)
+ ..controls (155.88,448.99) and (158.33,451.3)..(160.13,453.38)
+ ..controls (161.42,456.91) and (160.99,458.28)..(160.7,461.81)
+ ..controls (160.99,464.98) and (161.71,468.58)..(161.86,470.09)
+ ..controls (161.86,473.04) and (162.5,479.3)..(161.14,481.18)
+ --(159.41,482.69)..controls (157.18,487.22) and (158.33,494.64)..(157.61,500.26)
+ ..controls (155.81,500.69) and (155.81,500.98)..(154.01,498.31)
+ ..controls (154.01,494.42) and (153.5,486.36)..(152.35,483.84)
+ ..controls (149.69,479.81) and (150.84,459.65)..(151.42,448.56)
+ ..controls (151.78,446.47) and (149.69,447.7)..(149.76,444.74)
+ ..controls (150.05,442.8) and (147.89,443.59)..(146.09,444.6)
+ ..controls (145.15,445.18) and (146.59,439.78)..(145.37,439.56)
+ ..controls (142.34,438.84) and (136.87,438.19)..(135.22,440.71)
+ ..controls (134.57,444.6) and (137.88,448.06)..(140.62,451.01)
+ ..controls (143.14,455.83) and (140.9,465.7)..(140.47,476.28)
+ --(138.89,478.22)..controls (134.86,483.19) and (139.61,496.94)..(136.51,506.23)
+ ..controls (120.02,514.87) and (122.11,519.19)..(118.73,537.62)
+ ..controls (115.13,557.64) and (93.3799,567.65)..(79.0598,567.65)
+ ..controls (73.4399,563.04) and (66.24,563.62)..(58.5398,567.65)
+ ..controls (55.6599,569.23) and (54.4299,573.19)..(54.5,576.5)
+ ..controls (52.6299,580.75) and (55.22,582.19)..(59.6199,583.49)
+ ..controls (62.71,587.81) and (68.6199,594.65)..(69.1899,597.74)
+ ..controls (70.3398,601.92) and (75.5298,608.11)..(77.7598,609.77)
+ ..controls (75.8198,613.01) and (74.8098,615.17)..(77.1099,618.55)
+ ..controls (79.5598,620.14) and (81.7898,616.61)..(84.3799,618.55)
+ --cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.636492bp;
+draw (84.3799,618.55)..controls (88.3398,624.38) and (92.5898,622.94)..(96.3398,615.67)
+ ..controls (101.23,615.6) and (102.46,612.43)..(104.98,610.78)
+ ..controls (122.62,598.39) and (147.46,607.18)..(167.9,601.92)
+ ..controls (180.94,598.54) and (190.87,599.76)..(200.09,602.06)
+ ..controls (220.32,607.25) and (246.1,596.16)..(263.74,603.86)
+ ..controls (274.75,608.62) and (284.76,605.66)..(292.97,600.91)
+ ..controls (297.58,597.96) and (299.59,596.09)..(300.96,591.26)
+ ..controls (306.29,572.54) and (306.29,551.02)..(309.53,530.57)
+ ..controls (309.53,528.84) and (312.19,526.1)..(312.48,522.07)
+ ..controls (315.79,511.34) and (316.08,510.12)..(317.16,502.2)
+ ..controls (317.16,501.34) and (326.52,488.45)..(325.01,479.02)
+ ..controls (323.93,481.25) and (323.86,482.83)..(321.62,481.68)
+ ..controls (320.33,479.3) and (320.9,473.9)..(322.56,471.74)
+ ..controls (320.83,470.81) and (318.46,473.47)..(317.52,475.2)
+ ..controls (318.17,473.04) and (317.81,470.81)..(316.73,469.3)
+ ..controls (315.86,472.25) and (316.58,473.18)..(315.36,473.9)
+ ..controls (313.99,472.9) and (314.21,469.3)..(314.28,466.2)
+ ..controls (313.49,468.07) and (311.47,472.46)..(312.55,476.42)
+ ..controls (312.48,484.2) and (308.81,489.1)..(310.32,499.1)
+ ..controls (310.1,504.43) and (307.3,521.06)..(304.56,524.3)
+ ..controls (303.12,526.25) and (306.36,510.77)..(306.36,506.16)
+ ..controls (306.65,500.9) and (307.08,468.72)..(306.43,463.1)
+ ..controls (306.43,459.22) and (306.22,453.96)..(307.08,452.16)
+ ..controls (308.74,450.79) and (309.38,450.5)..(309.6,447.98)
+ ..controls (309.24,446.62) and (308.74,446.04)..(307.73,445.54)
+ ..controls (306.07,444.6) and (307.37,441.79)..(306.07,439.85)
+ ..controls (304.49,438.77) and (304.13,441.86)..(303.34,441.86)
+ ..controls (302.69,441) and (303.05,437.98)..(302.47,436.18)
+ ..controls (299.66,433.8) and (292.18,432.5)..(289.15,434.66)
+ ..controls (289.73,440.64) and (291.74,441.58)..(295.63,446.62)
+ ..controls (298.66,452.59) and (297,460.94)..(296.93,468.14)
+ ..controls (295.49,480.38) and (289.22,487.3)..(289.44,496.44)
+ ..controls (287.86,495.72) and (286.42,494.57)..(284.26,494.86)
+ ..controls (283.39,489.46) and (286.42,484.56)..(284.83,480.82)
+ ..controls (281.95,471.96) and (277.06,446.62)..(279,437.76)
+ ..controls (280.01,434.74) and (278.21,433.15)..(277.06,433.94)
+ ..controls (276.77,433.94) and (276.55,433.94)..(276.41,433.94)
+ ..controls (276.41,433.94) and (276.55,431.42)..(275.69,430.92)
+ ..controls (274.1,430.34) and (273.67,431.71)..(272.66,432.14)
+ ..controls (271.22,430.85) and (272.52,429.48)..(271.15,428.04)
+ ..controls (267.19,428.04) and (261.36,425.38)..(257.98,428.26)
+ ..controls (257.33,434.16) and (263.3,436.68)..(266.47,440.71)
+ ..controls (268.63,446.62) and (271.08,462.89)..(267.77,474.62)
+ ..controls (267.77,475.56) and (264.38,485.28)..(261.43,488.66)
+ ..controls (258.7,487.66) and (257.33,485.5)..(253.22,486.29)
+ ..controls (252.58,484.34) and (253.3,482.33)..(252.22,480.1)
+ ..controls (251.86,479.52) and (249.34,478.58)..(249.19,481.39)
+ ..controls (248.98,483.05) and (248.9,486.36)..(248.26,486.72)
+ ..controls (243.65,486.72) and (233.71,487.08)..(231.77,493.92)
+ ..controls (219.89,492.34) and (215.93,491.26)..(206.57,493.42)
+ ..controls (196.63,489.67) and (183.24,506.16)..(174.53,502.2)
+ ..controls (172.51,496.15) and (173.09,485.64)..(171.65,481.39)
+ ..controls (169.34,474.77) and (171.14,467.14)..(171.14,456.41)
+ ..controls (170.57,455.4) and (169.85,454.46)..(168.48,454.46)
+ ..controls (168.48,453.1) and (169.34,450.86)..(168.62,449.42)
+ ..controls (167.18,447.62) and (165.89,451.8)..(165.02,444.6)
+ ..controls (163.15,443.74) and (157.75,442.22)..(155.59,445.18)
+ ..controls (155.88,448.99) and (158.33,451.3)..(160.13,453.38)
+ ..controls (161.42,456.91) and (160.99,458.28)..(160.7,461.81)
+ ..controls (160.99,464.98) and (161.71,468.58)..(161.86,470.09)
+ ..controls (161.86,473.04) and (162.5,479.3)..(161.14,481.18)
+ --(159.41,482.69)..controls (157.18,487.22) and (158.33,494.64)..(157.61,500.26)
+ ..controls (155.81,500.69) and (155.81,500.98)..(154.01,498.31)
+ ..controls (154.01,494.42) and (153.5,486.36)..(152.35,483.84)
+ ..controls (149.69,479.81) and (150.84,459.65)..(151.42,448.56)
+ ..controls (151.78,446.47) and (149.69,447.7)..(149.76,444.74)
+ ..controls (150.05,442.8) and (147.89,443.59)..(146.09,444.6)
+ ..controls (145.15,445.18) and (146.59,439.78)..(145.37,439.56)
+ ..controls (142.34,438.84) and (136.87,438.19)..(135.22,440.71)
+ ..controls (134.57,444.6) and (137.88,448.06)..(140.62,451.01)
+ ..controls (143.14,455.83) and (140.9,465.7)..(140.47,476.28)
+ --(138.89,478.22)..controls (134.86,483.19) and (139.61,496.94)..(136.51,506.23)
+ ..controls (120.02,514.87) and (122.11,519.19)..(118.73,537.62)
+ ..controls (115.13,557.64) and (93.3799,567.65)..(79.0598,567.65)
+ ..controls (73.4399,563.04) and (66.24,563.62)..(58.5398,567.65)
+ ..controls (55.6599,569.23) and (54.4299,573.19)..(54.5,576.5)
+ ..controls (52.6299,580.75) and (55.22,582.19)..(59.6199,583.49)
+ ..controls (62.71,587.81) and (68.6199,594.65)..(69.1899,597.74)
+ ..controls (70.3398,601.92) and (75.5298,608.11)..(77.7598,609.77)
+ ..controls (75.8198,613.01) and (74.8098,615.17)..(77.1099,618.55)
+ ..controls (79.5598,620.14) and (81.7898,616.61)..(84.3799,618.55)
+ --cycle;
+pickup pencircle scaled 0bp;
+fill (305.28,560.95)..controls (304.63,560.95) and (299.95,561.24)..(299.38,561.24)
+ ..controls (302.4,550.44) and (303.98,536.47)..(304.2,525.31)
+ ..controls (303.7,521.35) and (299.81,517.46)..(299.38,525.67)
+ ..controls (295.85,530.86) and (296.42,540.07)..(293.4,540.29)
+ ..controls (287.35,539.64) and (285.34,513.22)..(280.01,509.33)
+ ..controls (276.26,512.28) and (280.73,524.02)..(275.54,524.74)
+ ..controls (270.5,524.02) and (264.31,526.68)..(266.69,534.46)
+ ..controls (270.29,543.02) and (268.34,554.76)..(266.54,561.6)
+ ..controls (262.37,578.59) and (264.02,587.09)..(271.58,596.09)
+ --(267.48,604.51)..controls (275.4,608.26) and (285.62,604.58)..(290.02,602.21)
+ ..controls (294.62,600.26) and (300.24,595.94)..(301.1,587.38)
+ ..controls (303.34,578.88) and (304.42,569.74)..(305.28,560.95)
+ --cycle;
+fill (245.45,600.34)..controls (242.78,599.4) and (239.62,596.02)..(237.67,594.07)
+ ..controls (236.74,584.42) and (244.58,583.63)..(250.2,577.44)
+ ..controls (258.77,573.7) and (251.21,567.72)..(256.18,557.42)
+ ..controls (257.04,550.94) and (257.9,543.89)..(255.31,539.78)
+ ..controls (249.48,538.92) and (247.97,540.22)..(246.89,531.43)
+ ..controls (246.31,526.97) and (231.77,529.06)..(229.03,538.27)
+ ..controls (227.09,544.97) and (221.33,546.7)..(217.8,543.17)
+ ..controls (213.77,538.06) and (215.78,531.22)..(217.8,527.47)
+ ..controls (224.93,517.32) and (212.04,511.42)..(205.13,516.74)
+ ..controls (199.73,508.68) and (211.39,500.04)..(207.43,494.5)
+ ..controls (205.78,493.99) and (204.77,489.17)..(185.47,500.54)
+ ..controls (180.36,504.14) and (167.83,500.76)..(168.77,520.63)
+ ..controls (168.77,525.82) and (165.6,543.53)..(162.14,555.91)
+ ..controls (159.41,561.24) and (156.74,559.08)..(156.89,553.9)
+ ..controls (157.18,547.85) and (162.94,531.22)..(155.52,540.22)
+ ..controls (153.58,539.21) and (156.89,523.58)..(156.89,521.64)
+ ..controls (162,517.03) and (157.39,513.58)..(154.73,512.28)
+ ..controls (151.27,518.33) and (149.62,518.04)..(147.17,514.44)
+ ..controls (141.7,514.08) and (144.58,528.19)..(140.26,528.62)
+ ..controls (137.02,527.76) and (139.18,520.06)..(138.24,518.76)
+ ..controls (132.98,524.74) and (130.9,529.27)..(127.01,521.64)
+ ..controls (126.14,521.64) and (122.11,519.19)..(120.96,526.54)
+ ..controls (117.65,552.74) and (107.06,558.36)..(93.8198,565.13)
+ ..controls (92.0198,565.63) and (84.24,566.71)..(79.3398,568.15)
+ ..controls (73.5098,560.88) and (58.3198,565.63)..(56.23,570.31)
+ ..controls (54.7898,572.69) and (54.6499,575.21)..(54.7898,576.5)
+ ..controls (52.3398,580.1) and (55.8699,582.7)..(59.6199,583.06)
+ ..controls (62.8599,587.16) and (68.5398,594.94)..(71.2798,601.56)
+ ..controls (72.2898,603.07) and (74.95,609.34)..(78.1899,609.55)
+ ..controls (74.95,612.94) and (74.2998,622.51)..(82.6599,617.33)
+ ..controls (87.1199,624.02) and (92.0898,624.31)..(95.7598,615.82)
+ ..controls (102.89,615.38) and (102.31,608.69)..(115.78,605.52)
+ ..controls (122.76,602.86) and (132.77,604.58)..(140.26,603.72)
+ ..controls (136.22,596.88) and (127.44,566.86)..(132.98,559.8)
+ ..controls (140.76,564.7) and (141.84,605.38)..(157.03,595.66)
+ ..controls (160.56,593.93) and (159.91,590.04)..(164.09,590.18)
+ ..controls (170.42,587.45) and (169.13,600.77)..(172.51,600.77)
+ ..controls (176.47,599.76) and (183.02,599.04)..(186.98,599.54)
+ ..controls (197.71,600.77) and (206.93,604.08)..(223.92,602.5)
+ ..controls (231.12,601.78) and (238.25,601.06)..(245.45,600.34)
+ --cycle;
+pickup pencircle scaled 0.636492bp;
+draw (305.28,560.95)..controls (304.63,560.95) and (299.95,561.24)..(299.38,561.24)
+ ..controls (302.4,550.44) and (303.98,536.47)..(304.2,525.31)
+ ..controls (303.7,521.35) and (299.81,517.46)..(299.38,525.67)
+ ..controls (295.85,530.86) and (296.42,540.07)..(293.4,540.29)
+ ..controls (287.35,539.64) and (285.34,513.22)..(280.01,509.33)
+ ..controls (276.26,512.28) and (280.73,524.02)..(275.54,524.74)
+ ..controls (270.5,524.02) and (264.31,526.68)..(266.69,534.46)
+ ..controls (270.29,543.02) and (268.34,554.76)..(266.54,561.6)
+ ..controls (262.37,578.59) and (264.02,587.09)..(271.58,596.09)
+ --(267.48,604.51)..controls (275.4,608.26) and (285.62,604.58)..(290.02,602.21)
+ ..controls (294.62,600.26) and (300.24,595.94)..(301.1,587.38)
+ ..controls (303.34,578.88) and (304.42,569.74)..(305.28,560.95)
+ --cycle;
+draw (245.45,600.34)..controls (242.78,599.4) and (239.62,596.02)..(237.67,594.07)
+ ..controls (236.74,584.42) and (244.58,583.63)..(250.2,577.44)
+ ..controls (258.77,573.7) and (251.21,567.72)..(256.18,557.42)
+ ..controls (257.04,550.94) and (257.9,543.89)..(255.31,539.78)
+ ..controls (249.48,538.92) and (247.97,540.22)..(246.89,531.43)
+ ..controls (246.31,526.97) and (231.77,529.06)..(229.03,538.27)
+ ..controls (227.09,544.97) and (221.33,546.7)..(217.8,543.17)
+ ..controls (213.77,538.06) and (215.78,531.22)..(217.8,527.47)
+ ..controls (224.93,517.32) and (212.04,511.42)..(205.13,516.74)
+ ..controls (199.73,508.68) and (211.39,500.04)..(207.43,494.5)
+ ..controls (205.78,493.99) and (204.77,489.17)..(185.47,500.54)
+ ..controls (180.36,504.14) and (167.83,500.76)..(168.77,520.63)
+ ..controls (168.77,525.82) and (165.6,543.53)..(162.14,555.91)
+ ..controls (159.41,561.24) and (156.74,559.08)..(156.89,553.9)
+ ..controls (157.18,547.85) and (162.94,531.22)..(155.52,540.22)
+ ..controls (153.58,539.21) and (156.89,523.58)..(156.89,521.64)
+ ..controls (162,517.03) and (157.39,513.58)..(154.73,512.28)
+ ..controls (151.27,518.33) and (149.62,518.04)..(147.17,514.44)
+ ..controls (141.7,514.08) and (144.58,528.19)..(140.26,528.62)
+ ..controls (137.02,527.76) and (139.18,520.06)..(138.24,518.76)
+ ..controls (132.98,524.74) and (130.9,529.27)..(127.01,521.64)
+ ..controls (126.14,521.64) and (122.11,519.19)..(120.96,526.54)
+ ..controls (117.65,552.74) and (107.06,558.36)..(93.8198,565.13)
+ ..controls (92.0198,565.63) and (84.24,566.71)..(79.3398,568.15)
+ ..controls (73.5098,560.88) and (58.3198,565.63)..(56.23,570.31)
+ ..controls (54.7898,572.69) and (54.6499,575.21)..(54.7898,576.5)
+ ..controls (52.3398,580.1) and (55.8699,582.7)..(59.6199,583.06)
+ ..controls (62.8599,587.16) and (68.5398,594.94)..(71.2798,601.56)
+ ..controls (72.2898,603.07) and (74.95,609.34)..(78.1899,609.55)
+ ..controls (74.95,612.94) and (74.2998,622.51)..(82.6599,617.33)
+ ..controls (87.1199,624.02) and (92.0898,624.31)..(95.7598,615.82)
+ ..controls (102.89,615.38) and (102.31,608.69)..(115.78,605.52)
+ ..controls (122.76,602.86) and (132.77,604.58)..(140.26,603.72)
+ ..controls (136.22,596.88) and (127.44,566.86)..(132.98,559.8)
+ ..controls (140.76,564.7) and (141.84,605.38)..(157.03,595.66)
+ ..controls (160.56,593.93) and (159.91,590.04)..(164.09,590.18)
+ ..controls (170.42,587.45) and (169.13,600.77)..(172.51,600.77)
+ ..controls (176.47,599.76) and (183.02,599.04)..(186.98,599.54)
+ ..controls (197.71,600.77) and (206.93,604.08)..(223.92,602.5)
+ ..controls (231.12,601.78) and (238.25,601.06)..(245.45,600.34)
+ --cycle;
+endfig;
+end
+pstoedit: version 3.18 / DLL interface 106 (build May 1 2000) : Copyright (C) 1993 - 2000 Wolfgang Glunz
+Interpreter finished. Return status 0
diff --git a/doc/context/sources/general/manuals/metafun/mycow.pdf b/doc/context/sources/general/manuals/metafun/mycow.pdf
new file mode 100644
index 000000000..9cc8fb0b4
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mycow.pdf
Binary files differ
diff --git a/doc/context/sources/general/manuals/metafun/somecow.pdf b/doc/context/sources/general/manuals/metafun/somecow.pdf
new file mode 100644
index 000000000..1a43087fd
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/somecow.pdf
Binary files differ