summaryrefslogtreecommitdiff
path: root/doc/context
diff options
context:
space:
mode:
Diffstat (limited to 'doc/context')
-rw-r--r--doc/context/documents/general/magazines/mag-1104-mkiv.pdfbin781988 -> 751131 bytes
-rw-r--r--doc/context/documents/general/manuals/lowlevel-boxes.pdfbin0 -> 75834 bytes
-rw-r--r--doc/context/documents/general/manuals/lowlevel-conditionals.pdfbin0 -> 95412 bytes
-rw-r--r--doc/context/documents/general/manuals/lowlevel-expansion.pdfbin0 -> 48778 bytes
-rw-r--r--doc/context/documents/general/manuals/lowlevel-registers.pdfbin0 -> 43435 bytes
-rw-r--r--doc/context/documents/general/manuals/luametafun.pdfbin0 -> 1514692 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-cs.pdfbin887551 -> 887655 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-de.pdfbin889628 -> 889580 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-en.pdfbin893466 -> 893435 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-fr.pdfbin885546 -> 885603 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-it.pdfbin891211 -> 891252 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-cs.pdfbin383751 -> 383751 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-de.pdfbin471626 -> 471430 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-en.pdfbin380397 -> 380397 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-fr.pdfbin384093 -> 384093 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-it.pdfbin383246 -> 383246 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-nl.pdfbin382226 -> 382225 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-ro.pdfbin620292 -> 620289 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-nl.pdfbin881171 -> 881208 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-ro.pdfbin885510 -> 885570 bytes
-rw-r--r--doc/context/presentations/context/2017/context-2017-css-selectors.pdfbin0 -> 130327 bytes
-rw-r--r--doc/context/presentations/context/2017/context-2017-css-selectors.tex238
-rw-r--r--doc/context/presentations/context/2017/context-2017-features-chaintest.pdfbin0 -> 15666 bytes
-rw-r--r--doc/context/presentations/context/2017/context-2017-features-chaintest.tex49
-rw-r--r--doc/context/presentations/context/2017/context-2017-features-kerntest.pdfbin0 -> 15259 bytes
-rw-r--r--doc/context/presentations/context/2017/context-2017-features-kerntest.tex25
-rw-r--r--doc/context/presentations/context/2017/context-2017-features-pairtest.pdfbin0 -> 15703 bytes
-rw-r--r--doc/context/presentations/context/2017/context-2017-features-pairtest.tex26
-rw-r--r--doc/context/presentations/context/2017/context-2017-features-singletest.pdfbin0 -> 15672 bytes
-rw-r--r--doc/context/presentations/context/2017/context-2017-features-singletest.tex25
-rw-r--r--doc/context/presentations/context/2017/context-2017-features-spacetest.pdfbin0 -> 15716 bytes
-rw-r--r--doc/context/presentations/context/2017/context-2017-features-spacetest.tex43
-rw-r--r--doc/context/presentations/context/2017/context-2017-features-substitutiontest.pdfbin0 -> 17567 bytes
-rw-r--r--doc/context/presentations/context/2017/context-2017-features-substitutiontest.tex141
-rw-r--r--doc/context/presentations/context/2017/context-2017-features.pdfbin0 -> 58197 bytes
-rw-r--r--doc/context/presentations/context/2017/context-2017-features.tex153
-rw-r--r--doc/context/presentations/context/2017/context-2017-performance.pdfbin0 -> 51156 bytes
-rw-r--r--doc/context/presentations/context/2017/context-2017-performance.tex65
-rw-r--r--doc/context/presentations/context/2017/context-2017-synctex.pdfbin0 -> 58760 bytes
-rw-r--r--doc/context/presentations/context/2017/context-2017-synctex.tex102
-rw-r--r--doc/context/presentations/context/2017/context-2017-tables.pdfbin0 -> 46060 bytes
-rw-r--r--doc/context/presentations/context/2017/context-2017-tables.tex175
-rw-r--r--doc/context/presentations/context/2019/context-2019-lmtx.pdfbin0 -> 41345 bytes
-rw-r--r--doc/context/presentations/context/2019/context-2019-lmtx.tex201
-rw-r--r--doc/context/sources/general/magazines/mag-1104-mkiv.tex28
-rw-r--r--doc/context/sources/general/manuals/lowlevel/lowlevel-boxes.tex698
-rw-r--r--doc/context/sources/general/manuals/lowlevel/lowlevel-conditionals.tex1409
-rw-r--r--doc/context/sources/general/manuals/lowlevel/lowlevel-expansion.tex442
-rw-r--r--doc/context/sources/general/manuals/lowlevel/lowlevel-registers.tex251
-rw-r--r--doc/context/sources/general/manuals/lowlevel/lowlevel-style.tex104
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-arrow.tex166
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-axis.tex83
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-chart.tex441
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-contents.tex11
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-contour.tex771
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-followtext.tex124
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-function.tex296
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-grid.tex11
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-interface.tex155
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-introduction.tex88
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-mesh-examples.tex161
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-mesh.tex78
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-outline.tex188
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-placeholder.tex163
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-shade.tex230
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-style.tex55
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-svg.tex75
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-text.tex137
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun-titlepage.tex41
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun.tex31
-rw-r--r--doc/context/sources/general/manuals/luametafun/mozilla-svg-001.svg1
-rw-r--r--doc/context/sources/general/manuals/luametafun/mozilla-svg-002.svg10
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-basics.tex2
73 files changed, 7478 insertions, 15 deletions
diff --git a/doc/context/documents/general/magazines/mag-1104-mkiv.pdf b/doc/context/documents/general/magazines/mag-1104-mkiv.pdf
index ee73daea5..523ba75b2 100644
--- a/doc/context/documents/general/magazines/mag-1104-mkiv.pdf
+++ b/doc/context/documents/general/magazines/mag-1104-mkiv.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/lowlevel-boxes.pdf b/doc/context/documents/general/manuals/lowlevel-boxes.pdf
new file mode 100644
index 000000000..305e6beba
--- /dev/null
+++ b/doc/context/documents/general/manuals/lowlevel-boxes.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/lowlevel-conditionals.pdf b/doc/context/documents/general/manuals/lowlevel-conditionals.pdf
new file mode 100644
index 000000000..5e3d82cee
--- /dev/null
+++ b/doc/context/documents/general/manuals/lowlevel-conditionals.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/lowlevel-expansion.pdf b/doc/context/documents/general/manuals/lowlevel-expansion.pdf
new file mode 100644
index 000000000..8628f4896
--- /dev/null
+++ b/doc/context/documents/general/manuals/lowlevel-expansion.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/lowlevel-registers.pdf b/doc/context/documents/general/manuals/lowlevel-registers.pdf
new file mode 100644
index 000000000..d00daa0cc
--- /dev/null
+++ b/doc/context/documents/general/manuals/lowlevel-registers.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/luametafun.pdf b/doc/context/documents/general/manuals/luametafun.pdf
new file mode 100644
index 000000000..e2b99ab2f
--- /dev/null
+++ b/doc/context/documents/general/manuals/luametafun.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-cs.pdf b/doc/context/documents/general/qrcs/setup-cs.pdf
index c42a21d13..d2f987d97 100644
--- a/doc/context/documents/general/qrcs/setup-cs.pdf
+++ b/doc/context/documents/general/qrcs/setup-cs.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-de.pdf b/doc/context/documents/general/qrcs/setup-de.pdf
index 5e7b80ac8..320d8ca11 100644
--- a/doc/context/documents/general/qrcs/setup-de.pdf
+++ b/doc/context/documents/general/qrcs/setup-de.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-en.pdf b/doc/context/documents/general/qrcs/setup-en.pdf
index a6e83085f..5c0fba19a 100644
--- a/doc/context/documents/general/qrcs/setup-en.pdf
+++ b/doc/context/documents/general/qrcs/setup-en.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-fr.pdf b/doc/context/documents/general/qrcs/setup-fr.pdf
index 71cb7eaa8..30c60469e 100644
--- a/doc/context/documents/general/qrcs/setup-fr.pdf
+++ b/doc/context/documents/general/qrcs/setup-fr.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-it.pdf b/doc/context/documents/general/qrcs/setup-it.pdf
index f8df2036f..f02842253 100644
--- a/doc/context/documents/general/qrcs/setup-it.pdf
+++ b/doc/context/documents/general/qrcs/setup-it.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-cs.pdf b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
index 6ee9c83d2..fb720a611 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-de.pdf b/doc/context/documents/general/qrcs/setup-mapping-de.pdf
index bf1adfd0d..225593507 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-de.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-de.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-en.pdf b/doc/context/documents/general/qrcs/setup-mapping-en.pdf
index 130408cf9..ad12ac66c 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-en.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-en.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
index 7087bb0e2..07e1a5f7c 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-it.pdf b/doc/context/documents/general/qrcs/setup-mapping-it.pdf
index 5f803464f..97b9586f7 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-it.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-it.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
index f8f5cfa5b..3a7de7431 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
index 07dbe708d..9f837fa1b 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-nl.pdf b/doc/context/documents/general/qrcs/setup-nl.pdf
index 075e71cd9..1718a6b3d 100644
--- a/doc/context/documents/general/qrcs/setup-nl.pdf
+++ b/doc/context/documents/general/qrcs/setup-nl.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-ro.pdf b/doc/context/documents/general/qrcs/setup-ro.pdf
index 79a6d0a9f..6682a9bcb 100644
--- a/doc/context/documents/general/qrcs/setup-ro.pdf
+++ b/doc/context/documents/general/qrcs/setup-ro.pdf
Binary files differ
diff --git a/doc/context/presentations/context/2017/context-2017-css-selectors.pdf b/doc/context/presentations/context/2017/context-2017-css-selectors.pdf
new file mode 100644
index 000000000..d4575f0e7
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-css-selectors.pdf
Binary files differ
diff --git a/doc/context/presentations/context/2017/context-2017-css-selectors.tex b/doc/context/presentations/context/2017/context-2017-css-selectors.tex
new file mode 100644
index 000000000..845206655
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-css-selectors.tex
@@ -0,0 +1,238 @@
+\usemodule[present-lines]
+
+\definecolor[maincolor][b=.4]
+
+\setuppapersize[A4][A4]
+
+\startdocument[title=CSS selectors,subtitle={\CONTEXT\ 2017 Maibach}]
+
+\startbuffer[selector-001]
+<?xml version="1.0" ?>
+
+<a>
+ <b class="one">b.one</b>
+ <b class="two">b.two</b>
+ <b class="one two">b.one.two</b>
+ <b class="three">b.three</b>
+ <b id="first">b#first</b>
+ <c>c</c>
+ <d>d e</d>
+ <e>d e</e>
+ <e>d e e</e>
+ <d>d f</d>
+ <f foo="bar">@foo = bar</f>
+ <f bar="foo">@bar = foo</f>
+ <f bar="foo1">@bar = foo1</f>
+ <f bar="foo2">@bar = foo2</f>
+ <f bar="foo3">@bar = foo3</f>
+ <f bar="foo+4">@bar = foo+4</f>
+ <g>g</g>
+ <g><gg><d>g gg d</d></gg></g>
+ <g><gg><f>g gg f</f></gg></g>
+ <g><gg><f class="one">g gg f.one</f></gg></g>
+ <g>g</g>
+ <g><gg><f class="two">g gg f.two</f></gg></g>
+ <g><gg><f class="three">g gg f.three</f></gg></g>
+ <g><f class="one">g f.one</f></g>
+ <g><f class="three">g f.three</f></g>
+ <h whatever="four five six">@whatever = four five six</h>
+</a>
+\stopbuffer
+
+\startbuffer[selector-002]
+<?xml version="1.0" ?>
+
+<document>
+ <title class="one" >title 1</title>
+ <title class="two" >title 2</title>
+ <title class="one" >title 3</title>
+ <title class="three">title 4</title>
+</document>
+\stopbuffer
+
+\startbuffer[selector-003]
+<?xml version="1.0" ?>
+
+<document>
+ <title class="one">title 1</title>
+ <subtitle class="sub">title 1.1</subtitle>
+ <title class="two">title 2</title>
+ <subtitle class="sub">title 2.1</subtitle>
+ <title class="one">title 3</title>
+ <subtitle class="sub">title 3.1</subtitle>
+ <title class="two">title 4</title>
+ <subtitle class="sub">title 4.1</subtitle>
+</document>
+\stopbuffer
+
+\xmlloadbuffer{selector-001}{selector-001}
+\xmlloadbuffer{selector-002}{selector-002}
+\xmlloadbuffer{selector-003}{selector-003}
+
+\startxmlsetups xml:selector:demo
+ \ignorespaces\xmlverbatim{#1}\par
+\stopxmlsetups
+
+\unexpanded\def\showCSSdemo#1#2%
+ {\blank
+ \textrule{\tttf#2}
+ \startlines
+ \dontcomplain
+ \tttf \obeyspaces
+ \xmlcommand{#1}{#2}{xml:selector:demo}
+ \stoplines
+ \blank}
+
+\startchapter[title=Needed or not?]
+
+\startitemize
+\startitem
+ used in \HTML\ styling
+\stopitem
+\startitem
+ a bit different from the path based method
+\stopitem
+\startitem
+ shortcuts for filtering by attribute
+\stopitem
+\startitem
+ class filtering is special because it checks for list
+\stopitem
+\startitem
+ one can select more at the same time
+\stopitem
+\startitem
+ performance is okay compared to path lookup
+\stopitem
+\startitem
+ selectors go between curly braces:
+ \starttyping
+ \xmlall {#1} {{foo bar .whatever, bar foo .whatever}}
+ \stoptyping
+\stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=Supported methods]
+
+The following methods are supported:
+
+\starttabulate[|T||]
+\NC \type {element} \NC all tags element \NC \NR
+\NC \type {element-1 > element-2} \NC all tags element-2 with parent tag element-1 \NC \NR
+\NC \type {element-1 + element-2} \NC all tags element-2 preceded by tag element-1 \NC \NR
+\NC \type {element-1 ~ element-2} \NC all tags element-2 preceded by tag element-1 \NC \NR
+\NC \type {element-1 element-2} \NC all tags element-2 inside tag element-1 \NC \NR
+\NC \type {[attribute]} \NC has attribute \NC \NR
+\NC \type {[attribute=value]} \NC attribute equals value\NC \NR
+\NC \type {[attribute~=value]} \NC attribute contains value (space is separator) \NC \NR
+\NC \type {[attribute^="value"]} \NC attribute starts with value \NC \NR
+\NC \type {[attribute$="value"]} \NC attribute ends with value \NC \NR
+\NC \type {[attribute*="value"]} \NC attribute contains value \NC \NR
+\NC \type {.class} \NC has class \NC \NR
+\NC \expanded{\type {\letterhash id}} \NC has id \NC \NR
+\NC \type {:nth-child(n)} \NC the child at index n \NC \NR
+\NC \type {:nth-last-child(n)} \NC the child at index n from the end \NC \NR
+\NC \type {:first-child} \NC the first child \NC \NR
+\NC \type {:last-child} \NC the last child \NC \NR
+\NC \type {:nth-of-type(n)} \NC the match at index n \NC \NR
+\NC \type {:nth-last-of-type(n)} \NC the match at index n from the end \NC \NR
+\NC \type {:first-of-type} \NC the first match \NC \NR
+\NC \type {:last-of-type} \NC the last match \NC \NR
+\NC \type {:only-of-type} \NC the only match or nothing \NC \NR
+\NC \type {:only-child} \NC the only child or nothing \NC \NR
+\NC \type {:empty} \NC only when empty \NC \NR
+\NC \type {:root} \NC the whole tree \NC \NR
+\stoptabulate
+
+\stopchapter
+
+\startchapter[title=Filtering classes]
+
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{.one}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{.one, .two}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{.one, .two, \letterhash first}} \page
+
+\stopchapter
+
+\startchapter[title=Filtering attributes]
+
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{[foo], [bar=foo]}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{[bar\lettertilde=foo]}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{[bar\letterhat="foo"]}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{[whatever\lettertilde="five"]}} \page
+
+\stopchapter
+
+\startchapter[title=Combining methods]
+
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{g f .one, g f .three}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{g > f .one, g > f .three}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{d + e}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{d ~ e}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{d ~ e, g f .one, g f .three}} \page
+
+\stopchapter
+
+% \startchapter[title=Negation]
+
+% \typebuffer[selector-001] \showCSSdemo{selector-001}{{:not([whatever\lettertilde="five"])}} \page
+% \typebuffer[selector-001] \showCSSdemo{selector-001}{{:not(d)}} \page
+
+\stopchapter
+
+\startchapter[title=Child selectors]
+
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{a:nth-child(3)}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{a:nth-last-child(3)}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{g:nth-of-type(3)}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{g:nth-last-of-type(3)}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{a:first-child}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{a:last-child}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{e:first-of-type}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{gg d:only-of-type}} \page
+
+\stopchapter
+
+\startchapter[title=Simple formulas]
+
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{a:nth-child(even)}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{a:nth-child(odd)}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{a:nth-child(3n+1)}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{a:nth-child(2n+3)}} \page
+
+\stopchapter
+
+\startchapter[title=Special cases]
+
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{g:empty}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{g:root}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{*}} \page
+
+\stopchapter
+
+\startchapter[title=Combinations]
+
+\typebuffer[selector-001] \showCSSdemo{selector-001}{{g gg f .one}} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{g/gg/f[@class='one']} \page
+\typebuffer[selector-001] \showCSSdemo{selector-001}{g/{gg f .one}} \page
+
+\stopchapter
+
+\startchapter[title=Comparison (1)]
+
+\typebuffer[selector-002] \showCSSdemo{selector-002}{{document title .one, document title .three}} \page
+\typebuffer[selector-002] \showCSSdemo{selector-002}{/document/title[(@class='one') or (@class='three')]} \page
+
+\stopchapter
+
+\startchapter[title=Comparison (2)]
+
+\typebuffer[selector-003] \showCSSdemo{selector-003}{{document title .one + subtitle, document title .two + subtitle}}
+
+{\em A combined filter triggers a sorting pass!}
+
+\stopchapter
+
+\stopdocument
diff --git a/doc/context/presentations/context/2017/context-2017-features-chaintest.pdf b/doc/context/presentations/context/2017/context-2017-features-chaintest.pdf
new file mode 100644
index 000000000..1da70b355
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-features-chaintest.pdf
Binary files differ
diff --git a/doc/context/presentations/context/2017/context-2017-features-chaintest.tex b/doc/context/presentations/context/2017/context-2017-features-chaintest.tex
new file mode 100644
index 000000000..58d1040f2
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-features-chaintest.tex
@@ -0,0 +1,49 @@
+\setupbodyfont[dejavu]
+
+\startluacode
+ fonts.handlers.otf.addfeature {
+ name = "chaintest",
+ type = "chainposition",
+ lookups = {
+ {
+ type = "pair",
+ data = {
+ A = { B = { { -30, 0, -50, 0 } } },
+ B = { C = { { -30, 0, -50, 0 } } },
+ },
+ },
+ {
+ type = "pair",
+ data = {
+ D = { E = { { -30, 0, -50, 0 } } },
+ },
+ },
+ },
+ data = {
+ rules = {
+ {
+ current = { { "A"}, { "B"}, { "C" }, { "D" }, { "E" }, { "F" } },
+ lookups = { false, false, false, 2 },
+ },
+ {
+ current = { { "A" }, { "B" }, { "C" } },
+ lookups = { 1, 1 },
+ },
+ },
+ }
+ }
+\stopluacode
+
+\starttext
+
+\definecolor[tgray][s=.5,t=.5,a=1] \showfontkerns \showglyphs
+
+\definefontfeature[chaintest] [mode=node,chaintest=yes]
+
+\definedfont[file:dejavu-serif.ttf*chaintest @ 48pt]
+
+\startTEXpage[offset=10pt,foregroundcolor=tgray]
+ ABCDEF
+\stopTEXpage
+
+\stoptext
diff --git a/doc/context/presentations/context/2017/context-2017-features-kerntest.pdf b/doc/context/presentations/context/2017/context-2017-features-kerntest.pdf
new file mode 100644
index 000000000..5a8d0d38d
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-features-kerntest.pdf
Binary files differ
diff --git a/doc/context/presentations/context/2017/context-2017-features-kerntest.tex b/doc/context/presentations/context/2017/context-2017-features-kerntest.tex
new file mode 100644
index 000000000..795af8b5f
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-features-kerntest.tex
@@ -0,0 +1,25 @@
+\setupbodyfont[dejavu]
+
+\startluacode
+ fonts.handlers.otf.addfeature {
+ name = "kerntest",
+ type = "kern",
+ data = {
+ A = { B = -500 },
+ }
+ }
+\stopluacode
+
+\starttext
+
+\definecolor[tgray][s=.5,t=.5,a=1] \showfontkerns \showglyphs
+
+\definefontfeature[kerntest] [mode=node,kerntest=yes]
+
+\definedfont[file:dejavu-serif.ttf*kerntest @ 48pt]
+
+\startTEXpage[offset=10pt,foregroundcolor=tgray]
+ ABCDEF
+\stopTEXpage
+
+\stoptext
diff --git a/doc/context/presentations/context/2017/context-2017-features-pairtest.pdf b/doc/context/presentations/context/2017/context-2017-features-pairtest.pdf
new file mode 100644
index 000000000..ba959e4f7
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-features-pairtest.pdf
Binary files differ
diff --git a/doc/context/presentations/context/2017/context-2017-features-pairtest.tex b/doc/context/presentations/context/2017/context-2017-features-pairtest.tex
new file mode 100644
index 000000000..e84851e7d
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-features-pairtest.tex
@@ -0,0 +1,26 @@
+\setupbodyfont[dejavu]
+
+\startluacode
+ fonts.handlers.otf.addfeature {
+ name = "pairtest",
+ type = "pair",
+ data = {
+ A = { B = { { -30, 50, -50, 0 } } },
+ B = { C = { { -30, 0, -50, 0 } } },
+ }
+ }
+\stopluacode
+
+\starttext
+
+\definecolor[tgray][s=.5,t=.5,a=1] \showfontkerns \showglyphs
+
+\definefontfeature[pairtest] [mode=node,pairtest=yes]
+
+\definedfont[file:dejavu-serif.ttf*pairtest @ 48pt]
+
+\startTEXpage[offset=10pt,foregroundcolor=tgray]
+ ABCDEF
+\stopTEXpage
+
+\stoptext
diff --git a/doc/context/presentations/context/2017/context-2017-features-singletest.pdf b/doc/context/presentations/context/2017/context-2017-features-singletest.pdf
new file mode 100644
index 000000000..624ee547f
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-features-singletest.pdf
Binary files differ
diff --git a/doc/context/presentations/context/2017/context-2017-features-singletest.tex b/doc/context/presentations/context/2017/context-2017-features-singletest.tex
new file mode 100644
index 000000000..fb0326fa3
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-features-singletest.tex
@@ -0,0 +1,25 @@
+\setupbodyfont[dejavu]
+
+\startluacode
+ fonts.handlers.otf.addfeature {
+ name = "singletest",
+ type = "single",
+ data = {
+ B = { -30, 0, -50, 0 },
+ }
+ }
+\stopluacode
+
+\starttext
+
+\definecolor[tgray][s=.5,t=.5,a=1] \showfontkerns \showglyphs
+
+\definefontfeature[singletest] [mode=node,singletest=yes]
+
+\definedfont[file:dejavu-serif.ttf*singletest @ 48pt]
+
+\startTEXpage[offset=10pt,foregroundcolor=tgray]
+ ABCDEF
+\stopTEXpage
+
+\stoptext
diff --git a/doc/context/presentations/context/2017/context-2017-features-spacetest.pdf b/doc/context/presentations/context/2017/context-2017-features-spacetest.pdf
new file mode 100644
index 000000000..9a2c7b012
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-features-spacetest.pdf
Binary files differ
diff --git a/doc/context/presentations/context/2017/context-2017-features-spacetest.tex b/doc/context/presentations/context/2017/context-2017-features-spacetest.tex
new file mode 100644
index 000000000..48ad4e32f
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-features-spacetest.tex
@@ -0,0 +1,43 @@
+\setupbodyfont[dejavu]
+
+\startluacode
+
+ -- we could populate this one mostly automatic if needed
+ -- but also expect a font to have such kerns
+
+ local kern = -50
+ local pair = { [32] = kern }
+
+ fonts.handlers.otf.addfeature {
+ name = "kern", -- spacekerns assume kern (for now)
+ type = "kern",
+ data = {
+ D = pair,
+ E = pair,
+ F = pair,
+ [32] = {
+ D = kern,
+ E = kern,
+ F = kern,
+ },
+ }
+ }
+
+\stopluacode
+
+\starttext
+
+\enabledirectives[fonts.injections.useitalics] % use italic kerns for tracing
+
+\definecolor[tgray][s=.5,t=.5,a=1] \showfontkerns \showfontitalics \showglyphs
+
+\definefontfeature[kern] [mode=node,kern=yes,spacekerns=yes]
+
+\definedfont[file:dejavu-serif.ttf*kern @ 48pt]
+\definedfont[file:dejavu-serif.ttf*default @ 48pt]
+
+\startTEXpage[offset=10pt,foregroundcolor=tgray]
+ A B C D E F G H
+\stopTEXpage
+
+\stoptext
diff --git a/doc/context/presentations/context/2017/context-2017-features-substitutiontest.pdf b/doc/context/presentations/context/2017/context-2017-features-substitutiontest.pdf
new file mode 100644
index 000000000..b95e531ec
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-features-substitutiontest.pdf
Binary files differ
diff --git a/doc/context/presentations/context/2017/context-2017-features-substitutiontest.tex b/doc/context/presentations/context/2017/context-2017-features-substitutiontest.tex
new file mode 100644
index 000000000..9e2657a6e
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-features-substitutiontest.tex
@@ -0,0 +1,141 @@
+\startluacode
+ fonts.handlers.otf.addfeature {
+ name = "singlesubstitution",
+ type = "substitution",
+ data = {
+ a = "X",
+ b = "P",
+ }
+ }
+\stopluacode
+
+\startluacode
+ fonts.handlers.otf.addfeature {
+ name = "alternatesubstitution",
+ type = "alternate",
+ data = {
+ a = { "X", "Y" },
+ b = { "P", "Q" },
+ }
+ }
+\stopluacode
+
+\startluacode
+ fonts.handlers.otf.addfeature {
+ name = "multiplesubstitution",
+ type = "multiple",
+ data = {
+ a = { "X", "Y" },
+ b = { "P", "Q" },
+ }
+ }
+\stopluacode
+
+\startluacode
+ fonts.handlers.otf.addfeature {
+ name = "ligaturesubstitution",
+ type = "ligature",
+ data = {
+ ['1'] = { "a", "b" },
+ ['2'] = { "d", "a" },
+ }
+ }
+\stopluacode
+
+\startluacode
+ fonts.handlers.otf.addfeature {
+ name = "chainsubstitution-1",
+ type = "chainsubstitution",
+ -- flags = { false, false, false, false },
+ lookups = {
+ {
+ type = "substitution",
+ data = {
+ ["b"] = "B",
+ ["c"] = "C",
+ },
+ },
+ },
+ -- steps = {
+ -- {
+ -- rules = {
+ -- {
+ -- before = { { "a" } },
+ -- current = { { "b", "c" } },
+ -- lookups = { 1 },
+ -- },
+ -- },
+ -- },
+ -- },
+ data = {
+ rules = {
+ {
+ before = { { "a" } },
+ current = { { "b", "c" } },
+ lookups = { 1 },
+ },
+ },
+ },
+ }
+\stopluacode
+
+\startluacode
+ fonts.handlers.otf.addfeature {
+ name = "chainsubstitution-2",
+ type = "chainsubstitution",
+ prepend = 1,
+ lookups = {
+ {
+ type = "multiple",
+ data = {
+ ["f"] = { "f", 0x200C },
+ },
+ },
+ {
+ type = "substitution",
+ data = {
+ ["a"] = "1",
+ ["b"] = "2",
+ ["c"] = "3",
+ },
+ },
+ },
+ data = {
+ rules = {
+ {
+ current = { { "f" }, { "f" } },
+ lookups = { 1 },
+ },
+ {
+ current = { { "a" }, { "b" }, { "c" } },
+ lookups = { 2, false, 2 },
+ },
+ },
+ }
+ }
+\stopluacode
+
+\definefontfeature[singlesubstitution] [singlesubstitution=yes]
+\definefontfeature[alternatesubstitution][alternatesubstitution=2]
+\definefontfeature[multiplesubstitution] [multiplesubstitution=yes]
+\definefontfeature[ligaturesubstitution] [ligaturesubstitution=yes]
+\definefontfeature[chainsubstitution-1] [chainsubstitution-1=yes]
+\definefontfeature[chainsubstitution-2] [chainsubstitution-2=yes]
+
+\setupbodyfont[dejavu]
+
+\starttext
+
+\definedfont[Serif*default] \showfontkerns \showfontitalics \showglyphs
+
+\startTEXpage
+ abracadabra\par
+ {\addff {singlesubstitution}abracadabra\par}
+ {\addff{alternatesubstitution}abracadabra\par}
+ {\addff {multiplesubstitution}abracadabra\par}
+ {\addff {ligaturesubstitution}abracadabra\par}
+ {\addff {chainsubstitution-1}abracadabra\par}
+ {\addff {chainsubstitution-2}effe abcdef !f\par}
+\stopTEXpage
+
+\stoptext
diff --git a/doc/context/presentations/context/2017/context-2017-features.pdf b/doc/context/presentations/context/2017/context-2017-features.pdf
new file mode 100644
index 000000000..e70afbed7
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-features.pdf
Binary files differ
diff --git a/doc/context/presentations/context/2017/context-2017-features.tex b/doc/context/presentations/context/2017/context-2017-features.tex
new file mode 100644
index 000000000..772de4ff6
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-features.tex
@@ -0,0 +1,153 @@
+\usemodule[present-lines]
+
+\definecolor[maincolor][r=.4,g=.4]
+
+\startdocument[title=Font features,subtitle={\CONTEXT\ 2017 Maibach}]
+
+\startchapter[title=What are they]
+
+\startitemize
+ \startitem
+ built in substitution that is often optional like ligatures but for some
+ languages mandate
+ \stopitem
+ \startitem
+ built in positioning that is assumed to be applied like kerning, mark
+ anchoring cursive
+ \stopitem
+ \startitem
+ external properties like coloring, spacing, fallback combinations
+ \stopitem
+ \startitem
+ engine related tricks like expansion and protrusion
+ \stopitem
+ \startitem
+ tracing options
+ \stopitem
+ \startitem
+ whatever you like \unknown\ so let me know
+ \stopitem
+ \blank[2*big]
+ \startitem
+ so in \CONTEXT\ we have font features (driven by font) and pseudo
+ features (driven by additional needs)
+ \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=Substitution]
+
+\startitemize
+ \startitem
+ single: replace one by another
+ \stopitem
+ \startitem
+ alternate: replace one by one of a set
+ \stopitem
+ \startitem
+ multiple: replace one by multiple others
+ \stopitem
+ \startitem
+ ligature: replace multiple by one shape
+ \stopitem
+ \blank[2*big]
+ \startitem
+ contextual lookups and replacements with look back and look ahead
+ \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=Positioning]
+
+\startitemize
+ \startitem
+ single: repositioning a glyph (with optional marks), this includes
+ traditional kerning
+ \stopitem
+ \startitem
+ pairwise: repositioning two adjacent glyphs (with optional marks)
+ \stopitem
+ \startitem
+ anchoring: often used for marks to base glyphs, ligatures and other marks
+ \stopitem
+ \startitem
+ attachment: often used for cursive scripts, pasting glyphs in a word together
+ \stopitem
+ \blank[2*big]
+ \startitem
+ contextual lookups and positioning with look back and look ahead
+ \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=Related]
+
+\startitemize
+ \startitem
+ analyze: needed for dealing with features that need information about
+ initial, medial, final and isolated properties
+ \stopitem
+ \startitem
+ reordering: needed for script like devanagari
+ \stopitem
+ \startitem
+ spacing: deals with for positioning glyphs and spaces
+ \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=Pitfalls]
+
+\startitemize
+ \startitem
+ solutions for similar tasks can be quite different which makes tracing
+ or checking sometimes hard (many ways to make ligatures)
+ \stopitem
+ \startitem
+ order matters and demands careful font design but it is hard to predict
+ all cases
+ \stopitem
+ \startitem
+ a sloppy font design can result in a performance hit or huge fonts
+ \stopitem
+ \startitem
+ features can be bugged and fonts vendors seldom have an update policy
+ \stopitem
+ \startitem
+ shapers can differ due to assumptions, heuristics, interpreting
+ specifications, bugs, \unknown
+ \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=Examples]
+ \startitem
+ all kind of substitutions: \type {2017-features-substitutiontest.tex}
+ \stopitem
+ \startitem
+ simple inter character kerns: \type {2017-features-kerntest.tex}
+ \stopitem
+ \startitem
+ single character positioning: \type {2017-features-singletest.tex}
+ \stopitem
+ \startitem
+ pairwise character positioning: \type {2017-features-pairtest.tex}
+ \stopitem
+ \startitem
+ contextual positioning: \type {2017-features-contexttest.tex}
+ \stopitem
+ \startitem
+ kerning with space (glue): \type {2017-features-spacetest.tex}
+ \stopitem
+\startitemize
+
+\stopitemize
+
+\stopchapter
+
+\stopdocument
diff --git a/doc/context/presentations/context/2017/context-2017-performance.pdf b/doc/context/presentations/context/2017/context-2017-performance.pdf
new file mode 100644
index 000000000..9656e2f0e
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-performance.pdf
Binary files differ
diff --git a/doc/context/presentations/context/2017/context-2017-performance.tex b/doc/context/presentations/context/2017/context-2017-performance.tex
new file mode 100644
index 000000000..458a051a5
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-performance.tex
@@ -0,0 +1,65 @@
+\usemodule[present-lines]
+
+\definecolor[maincolor][g=.4,b=.4]
+
+\startdocument[title=Performance,subtitle={\CONTEXT\ 2017 Maibach}]
+
+\startchapter[title=Why bother]
+
+\startitemize
+ \startitem because we don't want to waste time waiting \stopitem
+ \startitem because I get tired of ignorance related complaints \stopitem
+ \startitem because it (sometimes) can be a nice puzzle to improve performance \stopitem
+ \startitem because it occasionally reviewing makes code better \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=Possible bottlenecks]
+
+\startitemize
+ \startitem starting up \stopitem
+ \startitem loading fonts \stopitem
+ \startitem processing features \stopitem
+ \startitem applying trickery \stopitem
+ \startitem enabling tracing \stopitem
+ \blank[2*big]
+ \startitem fonts \stopitem
+ \startitem \LUA \stopitem
+ \startitem images \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=Measurements]
+
+\startitemize
+ \startitem how long does a run take \stopitem
+ \startitem how does the number of pages matter \stopitem
+ \startitem how many runs are needed \stopitem
+ \blank[2*big]
+ \startitem start-up time \stopitem
+ \startitem processing pages \stopitem
+ \startitem finishing the document \stopitem
+ \startitem the console used \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=Examples]
+
+\startitemize
+\startitem
+ see \goto{onandon-performance.pdf}[file(onandon-performance.pdf)] for timings
+\stopitem
+\startitem
+ you can try \type {--timing} to see where \LUA\ spends it time
+\stopitem
+\startitem
+ analyzing with \type {--profile} can give some indication (but is slow)
+\stopitem
+\stopitemize
+
+\stopchapter
+
+\stopdocument
diff --git a/doc/context/presentations/context/2017/context-2017-synctex.pdf b/doc/context/presentations/context/2017/context-2017-synctex.pdf
new file mode 100644
index 000000000..d5b39f095
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-synctex.pdf
Binary files differ
diff --git a/doc/context/presentations/context/2017/context-2017-synctex.tex b/doc/context/presentations/context/2017/context-2017-synctex.tex
new file mode 100644
index 000000000..0ca6dfd0e
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-synctex.tex
@@ -0,0 +1,102 @@
+% \setupsynctex
+% [state=start]
+
+% \enabletrackers
+% [system.synctex.visualize]
+
+\usemodule[present-lines]
+
+\definecolor[maincolor][r=.6]
+
+\startdocument[title=\SYNCTEX,subtitle={\CONTEXT\ 2017 Maibach}]
+
+\startchapter[title=What is \SYNCTEX]
+
+\startitemize
+ \startitem it is a mechanism for going back from viewer to editor \stopitem
+ \startitem it uses an extra (zipped) output file \stopitem
+ \startitem it adds an overhead of 5 to 15 percent runtime \stopitem
+ \startitem it is designed with a specific macro package in mind \stopitem
+ \startitem the rather generic approach works okay for simple document layouts \stopitem
+ \startitem but it often fails for projects that use multiple files\stopitem
+ \startitem and that moves information around like \XML\ encoded files \stopitem
+\stopitemize
+
+\startchapter[title=Disclaimer]
+
+\startitemize
+ \startitem till recently it was supported in \CONTEXT\ as-it-was \stopitem
+ \startitem there were no compliants, so it must have worked ok for most users \stopitem
+ \startitem we never used it ourselves because of mentioned reasons \stopitem
+ \startitem we only wanted to support it when it works ok in projects \stopitem
+ \startitem (think of thousands of \XML\ with deeply nested inclusions in one document) \stopitem
+ \startitem but what we support now is purely based on personal experiences \stopitem
+ \startitem we don't use it ourselves so feedback is welcome \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=What we do]
+
+\startitemize
+ \startitem the normal \SYNCTEX\ mechanism is disabled \stopitem
+ \startitem when told so, \CONTEXT\ will kick in its own code \stopitem
+ \startitem this is done by using \LUA\ code to set the right information \stopitem
+ \startitem only source files that make sense are dealt with \stopitem
+ \startitem this protects the styles from unwanted changes \stopitem
+ \startitem within reasonable bounds \XML\ is supported \stopitem
+ \startitem this also includes nested documents \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=How it works]
+
+\startitemize
+ \startitem we only mark text and don't bother about the rest \stopitem
+ \startitem we collapse information about whole stretches \stopitem
+ \startitem the extra file is therefore not that large \stopitem
+ \startitem so we can do without compression \stopitem
+ \startitem some care is needed to avoid interference with the editors parser \stopitem
+ \startitem (read: we need to get rid of the rather complex and heuristics) \stopitem
+ \startitem (read: it would be nice to have a simple robust parser option) \stopitem
+ \startitem there are flaws but I will look into them when motivated \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=What the user gets]
+
+\startitemize
+ \startitem a way to turn it on:
+ \starttyping
+ \setupsynctex[state=start]
+ \stoptyping
+ \stopitem
+ \startitem control over methods:
+ \starttyping
+ \setupsynctex[method=max]
+ \stoptyping
+ \stopitem
+ \startitem visual tracing:
+ \starttyping
+ \enabletrackers[system.synctex.visualize]
+ \stoptyping
+ \stopitem
+ \startitem some low level commands:
+ \starttyping
+ \synctexblockfilename{filename}
+ \synctexsetfilename {filename}
+ \synctexresetfilename
+ \synctexpause
+ \synctexresume
+ \stoptyping
+ \stopitem
+\stopitemize
+
+% \enabletrackers[system.synctex.xml]
+% \enabledirectives[system.synctex.details]
+
+\stopchapter
+
+\stopdocument
diff --git a/doc/context/presentations/context/2017/context-2017-tables.pdf b/doc/context/presentations/context/2017/context-2017-tables.pdf
new file mode 100644
index 000000000..299c21f39
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-tables.pdf
Binary files differ
diff --git a/doc/context/presentations/context/2017/context-2017-tables.tex b/doc/context/presentations/context/2017/context-2017-tables.tex
new file mode 100644
index 000000000..6f2822668
--- /dev/null
+++ b/doc/context/presentations/context/2017/context-2017-tables.tex
@@ -0,0 +1,175 @@
+\usemodule[present-lines]
+
+\definecolor[maincolor][r=.4,b=.4]
+
+\startdocument[title=Tables,subtitle={\CONTEXT\ 2017 Maibach}]
+
+\startchapter[title=Variants]
+
+\startitemize
+ \startitem
+ Good old \TABLE, a wrapper about \TEX's alignment.
+ \stopitem
+ \startitem
+ Running text, break across pages tabulates.
+ \stopitem
+ \startitem
+ Tables that behave like \HTML\ tables therefore called
+ natural tables.
+ \stopitem
+ \startitem
+ A variant on this that is more easy to extend, tagged
+ extreme tables.
+ \stopitem
+ \startitem
+ A low profile linetable mechanism that can span pages
+ and breaks well.
+ \stopitem
+ \startitem
+ A way to make huge tables without overflowing \TEX\ too
+ soon.
+ \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=\TABLE]
+
+\startitemize
+ \startitem
+ Based on the \TABLE\ macro package.
+ \stopitem
+ \startitem
+ Detailed control over spacing.
+ \stopitem
+ \startitem
+ Somewhat inconsistent spacing out of the box.
+ \stopitem
+ \startitem
+ Extended with extra features.
+ \stopitem
+ \startitem
+ Mostly rewritten but within the original concept.
+ \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=Tabulate]
+
+\startitemize
+ \startitem
+ Mostly meant for tables that are part of the text flow.
+ \stopitem
+ \startitem
+ Breaks paragraphs across pages.
+ \stopitem
+ \startitem
+ Sort of compatible in control with \TABLE.
+ \stopitem
+ \startitem
+ The system that I used most often.
+ \stopitem
+ \startitem
+ It uses multiple passes if needed.
+ \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=Natural tables]
+
+\startitemize
+ \startitem
+ Modelled after \HTML\ tables.
+ \stopitem
+ \startitem
+ Often used in \XML\ workflows, possibly as cals tables.
+ \stopitem
+ \startitem
+ To some extend automatic spans horizontally and vertically.
+ \stopitem
+ \startitem
+ There are a couple of (undocumented and obscure) flags that can control
+ behaviour.
+ \stopitem
+ \startitem
+ They can break cross pages if needed.
+ \stopitem
+ \startitem
+ Tables, rows and cells have framed like properties.
+ \stopitem
+ \startitem
+ Not the fastest mechanism as it used several passes (for which it
+ stores all cells).
+ \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=Extreme tables]
+
+\startitemize
+ \startitem
+ Again modelled after \HTML\ tables.
+ \stopitem
+ \startitem
+ A few less options but also some more than natural tables.
+ \stopitem
+ \startitem
+ Most work is delegated to \LUA.
+ \stopitem
+ \startitem
+ Uses buffers and therefore nesting is (as with natural tables)
+ possible but with care.
+ \stopitem
+\stopitemize
+
+\stopchapter
+
+\startchapter[title=Line tables]
+
+\startitemize
+ \startitem
+ Written for and used in a project long ago.
+ \stopitem
+ \startitem
+ Meant for huge tables that span multiple pages horizontally
+ and vertically.
+ \stopitem
+ \startitem
+ It only can have simple colored backgrounds.
+ \stopitem
+ \startitem
+ Hardly used.
+ \stopitem
+ \startitem
+ I need to redo (or check) the implementation some day.
+ \stopitem
+\stopitemize
+
+\startchapter[title=Frame tables]
+
+\startitemize
+ \startitem
+ Written for and used for Thomas who needs real huge tables
+ generated from \XML.
+ \stopitem
+ \startitem
+ It's a single pass mechanism.
+ \stopitem
+ \startitem
+ Each cell is a framed.
+ \stopitem
+ \startitem
+ Dimensions need to be adapted when you want predictable output.
+ \stopitem
+ \startitem
+ I might extend it but within reasonable bounds.
+ \stopitem
+\stopitemize
+
+\stopchapter
+
+
+\stopdocument
diff --git a/doc/context/presentations/context/2019/context-2019-lmtx.pdf b/doc/context/presentations/context/2019/context-2019-lmtx.pdf
new file mode 100644
index 000000000..7cf257347
--- /dev/null
+++ b/doc/context/presentations/context/2019/context-2019-lmtx.pdf
Binary files differ
diff --git a/doc/context/presentations/context/2019/context-2019-lmtx.tex b/doc/context/presentations/context/2019/context-2019-lmtx.tex
new file mode 100644
index 000000000..62dd915ad
--- /dev/null
+++ b/doc/context/presentations/context/2019/context-2019-lmtx.tex
@@ -0,0 +1,201 @@
+% macros=mkvi
+
+\usemodule[abbreviations-smallcaps]
+\usemodule[present-luatex]
+
+\logo [LUAMETATEX] {LuaMeta\TeX}
+
+\setupbodyfont[12pt]
+
+\setupalign[verytolerant]
+
+\setupdocument
+ [title={Lean and mean},
+ subtitle={\LUAMETATEX},
+ location={\ConTeXt\ meeting, September 2019},
+ author={Hans & Alan},
+ mp:title={\LUAMETATEX}]
+
+\startdocument
+
+\setupitemize[headintext]
+\setupitemize[headstyle=bold]
+
+\page \setupdocument[mp:subtitle={How it became}]
+
+\startitemize
+ \starthead {interferences:}
+ \CONTEXT, plain \TEX\ and \LATEX\ all have different demands (we want to
+ experiment and move on and users pick up fast)
+ \stophead
+ \starthead {complexity:}
+ the source tree is way too complex as is the build (we only need \LUATEX)
+ \stophead
+ \starthead {distributions:}
+ no one can guarantee stability for \CONTEXT\ (being a minor player but
+ often a bit ahead)
+ \stophead
+ \starthead {annoyances:}
+ experimental codes leads to usage outside \CONTEXT\ and that triggers
+ complaints
+ \stophead
+ \starthead {motivation:}
+ running into folks who love to stress \quotation {huge bugs} and
+ \quotation {much instability} wastes energy
+ \stophead
+ \starthead {arguments:}
+ I got tired of \quotation {you need to support this because \unknown}
+ blabla
+ \stophead
+ \starthead {nagging:}
+ like \quotation {the manual \unknown} is becoming too tiresome, so best
+ keep experiments within the \CONTEXT\ bubble
+ \stophead
+\stopitemize
+
+\page \setupdocument[mp:subtitle={What it is}]
+
+\startitemize
+ \starthead {simplification:}
+ we don't need all what is currently in the \LUATEX\ engine as we don't
+ use it
+ \stophead
+ \starthead {source:}
+ there is much less of it and we can get rid of \WEB\ artifacts
+ \stophead
+ \starthead {compilation:}
+ there was much more going on than was needed and only a few knew those
+ details
+ \stophead
+ \starthead {consistency:}
+ to guarantee consistency with \CONTEXT\ the source code will be part of
+ the source distribution (once I'm satisfied)
+ \stophead
+ \starthead {marketing:}
+ this way the relation with \CONTEXT\ and its user base is more clear
+ \stophead
+ \starthead {playground:}
+ we can move forward and experiment without the danger of running into
+ problems with non \CONTEXT\ users: \quotation {use it at your own risk}
+ \stophead
+ \starthead {possibilities:}
+ playing a bit more with the bits and pieces that are reponsible for most
+ (interfering) issues, like the the (asynchronous) page builder
+ \stophead
+\stopitemize
+
+\page \setupdocument[mp:subtitle={Implications}]
+
+\startitemize
+ \starthead {binary:}
+ there is only one relatively small binary needed (that does all things
+ needed)
+ \stophead
+ \starthead {code base:}
+ there comes an extra source tree, but it's small (compresses to around 2
+ MB)
+ \stophead
+ \starthead {user control:}
+ if needed users can compile the program so we're self contained
+ \stophead
+ \starthead {future safe:}
+ we can move forward and improve
+ \stophead
+ \starthead {modern:}
+ a code base with the latest \LUATEX, \MPLIB\ and \LUA
+ \stopitem
+ \starthead {side effect:}
+ we drop \LUAJIT\ as it doesn't keep up (and benefits are too small)
+ \stophead
+ \starthead {design:}
+ we have a better separation between the Knuthian front- and output format
+ driven backend
+ \stophead
+ \starthead {independent:}
+ there is no dependency on external libraries, we keep all we need in the
+ code base (we only use a few small third party libraries)
+ \stophead
+\stopitemize
+
+\page \setupdocument[mp:subtitle={A few notes}]
+
+\startitemize
+ \starthead {hobyism}
+ we don't need to carry the burden of everything (unless paid for it's
+ only fun and users that drives development)
+ \stophead
+ \starthead {convenience:}
+ the faster compilation makes reworking and experimenting reasonable
+ \stophead
+ \starthead {stepwise:}
+ I take my time an do string stepswise because things should not break
+ without fast recovery
+ \stophead
+ \starthead {feelgood:}
+ this all fits well into the good old \TEX\ extension model
+ \stophead
+ \starthead {eventually:}
+ when proven useful we can always push code upstream into \LUATEX
+ \stophead
+\stopitemize
+
+\page \setupdocument[mp:subtitle={Bits and pieces}]
+
+\startitemize
+ \starthead {original:}
+ the starting point is \LUATEX, original \WEB\ code, already \CWEB\ code
+ \stophead
+ \starthead {stability:}
+ after a initial stage \LUATEX\ was stepwise extended till version one
+ a few years ago
+ \stophead
+ \starthead {frozen:}
+ there were only a few changes after that but no real conceptual ones
+ \stophead
+ \starthead {engine:}
+ what is now called \LUAMETATEX\ is a reworked code base
+ \stophead
+ \starthead {graphics:}
+ also \MPLIB\ has been reworked a bit and some extensions were added
+ \stophead
+ \starthead {libraries:}
+ there are a few extra (small) helper libs, but all in the source tree
+ \stophead
+ \starthead {pplib:}
+ we already use the next version of pplib
+ \stophead
+ \starthead {pruning:}
+ and best of all, quite some not used code could go
+ \stophead
+\stopitemize
+
+\page \setupdocument[mp:subtitle={Some details}]
+
+\startitemize
+ \starthead {source tree:}
+ the code base has been regrouped, globals became more local (work in
+ progress), header files were added
+ \stophead
+ \starthead {source files:}
+ there is hardly any font related code, languages were kept, and the
+ backend code is dropped: show files
+ \stophead
+ \starthead {libraries:}
+ a few libs were added and dropped: show some
+ \stophead
+ \starthead {cmake:}
+ compilation is different: work in progress
+ \stophead
+ \starthead {mkxl:}
+ there are new files in \CONTEXT: \type {driv}, \type {lpdf}, \type {.mkxl}
+ and expect more
+ \stophead
+ \starthead {binary:}
+ there is only one stub for all
+ \stophead
+\stopitemize
+
+{\infofont during presentation: show the source tree as well as the binary directory}
+
+\stopdocument
+
diff --git a/doc/context/sources/general/magazines/mag-1104-mkiv.tex b/doc/context/sources/general/magazines/mag-1104-mkiv.tex
index 4cbc3d921..ef46b6fe1 100644
--- a/doc/context/sources/general/magazines/mag-1104-mkiv.tex
+++ b/doc/context/sources/general/magazines/mag-1104-mkiv.tex
@@ -497,25 +497,25 @@ Let's look at outlines.
save h ; h = 12mm ;
draw lmt_outline [
- content = "hello"
+ text = "hello"
kind = "draw",
drawcolor = "darkblue",
] ysized h ;
draw lmt_outline [
- content = "hello",
+ text = "hello",
kind = "fill",
fillcolor = "darkred",
] ysized h shifted (3.75h,0) ;
draw lmt_outline [
- content = "hello",
+ test = "hello",
kind = "both",
fillcolor = "darkred",
] ysized h shifted (7.5h,0mm) ;
draw lmt_outline [
- content = "hello",
+ text = "hello",
kind = "both",
fillcolor = "darkred",
drawcolor = "darkblue",
@@ -523,7 +523,7 @@ Let's look at outlines.
] ysized h shifted (0,-1.25h) ;
draw lmt_outline [
- content = "hello",
+ text = "hello",
kind = "reverse",
fillcolor = "darkred",
drawcolor = "darkblue",
@@ -531,8 +531,8 @@ Let's look at outlines.
] ysized h shifted (3.75h,-1.25h) ;
draw lmt_outline [
- content = "hello",
- kind = "u",
+ text = "hello",
+ kind = "fillup",
fillcolor = "darkgreen",
rulethickness = 0,
] ysized h shifted (7.5h,-1.25h) ;
@@ -552,7 +552,7 @@ outline and fill. Let's show some more:
\startbuffer
\startMPcode{doublefun}
draw lmt_outline [
- content = "\obeydiscretionaries\samplefile{tufte}",
+ text = "\obeydiscretionaries\samplefile{tufte}",
align = "normal",
kind = "draw",
drawcolor = "darkblue",
@@ -569,7 +569,7 @@ outline and fill. Let's show some more:
\startbuffer
\startMPcode{doublefun}
draw lmt_outline [
- content = "\obeydiscretionaries\samplefile{ward}",
+ text = "\obeydiscretionaries\samplefile{ward}",
align = "normal,tolerant",
width = 10cm,
kind = "draw",
@@ -587,7 +587,7 @@ outline and fill. Let's show some more:
\startbuffer
\startMPcode{doublefun}
draw lmt_outline [
- content = "\obeydiscretionaries\samplefile{sapolsky}",
+ text = "\obeydiscretionaries\samplefile{sapolsky}",
align = "normal,tolerant",
style = "bold",
width = 10cm,
@@ -611,14 +611,14 @@ That interface has evolved over time, also due to more advanced possibilities in
\startbuffer
\startMPcode{doublefun}
draw lmt_followtext [
- content = "How well does it work {\bf 1}! ",
+ text = "How well does it work {\bf 1}! ",
path = (fullcircle scaled 4cm),
trace = true,
spread = true,
] ysized 5cm ;
draw lmt_followtext [
- content = "How well does it work {\bf 2}! ",
+ text = "How well does it work {\bf 2}! ",
path = fullcircle scaled 4cm,
trace = true,
spread = false,
@@ -626,13 +626,13 @@ That interface has evolved over time, also due to more advanced possibilities in
] ysized 5cm shifted (0,-6cm) ;
draw lmt_followtext [
- content = "How well does it work {\bf 3}! ",
+ text = "How well does it work {\bf 3}! ",
trace = true,
autoscaleup = "yes"
] ysized 5cm shifted (6cm,0) ;
draw lmt_followtext [
- content = "How well does it work {\bf 4}! ",
+ text = "How well does it work {\bf 4}! ",
path = fullcircle scaled 2cm,
trace = true,
autoscaleup = "max"
diff --git a/doc/context/sources/general/manuals/lowlevel/lowlevel-boxes.tex b/doc/context/sources/general/manuals/lowlevel/lowlevel-boxes.tex
new file mode 100644
index 000000000..986d07b1b
--- /dev/null
+++ b/doc/context/sources/general/manuals/lowlevel/lowlevel-boxes.tex
@@ -0,0 +1,698 @@
+% language=us
+
+% \hfil \hss
+% spread
+
+\environment lowlevel-style
+
+\startdocument
+ [title=boxes,
+ color=middlered]
+
+\startsection[title=Preamble]
+
+\startsubsection[title=Introduction]
+
+An average \CONTEXT\ user will not use the low level box primitives but a basic
+understanding of how \TEX\ works doesn't hurt. In fact, occasionally using a box
+command might bring a solution not easily achieved otherwise, simply because a
+more high level interface can also be in the way.
+
+The best reference is of course The \TeX book so if you're really interested in
+the details you should get a copy of that book. Below I will not go into details
+about all kind of glues, kerns and penalties, just boxes it is.
+
+This explanation will be extended when I feel the need (or users have questions
+that can be answered here).
+
+\stopsubsection
+
+\startsubsection[title=Boxes]
+
+This paragraph of text is made from lines that contain words that themselves
+contain symbolic representations of characters. Each line is wrapped in a so
+called horizontal box and eventually those lines themselves get wrapped in what
+we call a vertical box.
+
+\startbuffer
+\vbox \bgroup
+ \hsize 5cm
+ \raggedright
+ This is a rather narrow paragraph blown up a bit. Here we use a flush left,
+ aka ragged right, approach.
+\egroup
+\stopbuffer
+
+When we expose some details of a paragraph it looks like this:
+
+\startlinecorrection
+\startcombination[2*1]
+ {\scale[width=8cm]{\showmakeup[boxes]\getbuffer}} {}
+ {\scale[width=8cm]{\showmakeup\getbuffer}} {}
+\stopcombination
+\stoplinecorrection
+
+The left only shows the boxes, the variant at the right shows (font) kerns and
+glue too. Because we flush left, there is rather strong right skip glue at the
+right boundary of the box. If font kerns show up depends on the font, not all
+fonts have them (or have only a few). The glyphs themselves are also kind of
+boxed, as their dimensions determine the area that they occupy:
+
+\startlinecorrection
+ \scale[width=\textwidth]{\showglyphs\hbox{This is a rather ...}}
+\stoplinecorrection
+
+But, internally they are not really boxed, as they already are a single quantity.
+The same is true for rules: they are just blobs with dimensions. A box on the
+other hand wraps a linked list of so called nodes: glyphs, kerns, glue,
+penalties, rules, boxes, etc. It is a container with properties like width,
+height, depth and shift.
+
+\stopsubsection
+
+\stopsection
+
+\startsection[title={\TEX\ primitives}]
+
+The box model is reflected in \TEX's user interface but not by that many
+commands, most noticeably \type {\hbox}, \type {\vbox} and \type {\vtop}. Here is
+an example of the first one:
+
+\starttyping[option=TEX]
+\hbox width 10cm{text}
+\hbox width 10cm height 1cm depth 5mm{text}
+text \raise5mm\hbox{text} text
+\stoptyping
+
+The \type {\raise} and \type {\lower} commands behave the same but in opposite
+directions. One could as well have been defined in terms of the other.
+
+\startbuffer
+text \raise 5mm \hbox to 2cm {text}
+text \lower -5mm \hbox to 2cm {text}
+text \raise -5mm \hbox to 2cm {text}
+text \lower 5mm \hbox to 2cm {text}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+{\dontcomplain\showboxes\getbuffer}
+\stoplinecorrection
+
+A box can be moved to the left or right but, believe it or not, in \CONTEXT\ we
+never use that feature, probably because the consequences for the width are such
+that we can as well use kerns. Here are some examples:
+
+\startbuffer
+text \vbox{\moveleft 5mm \hbox {left}}text !
+text \vbox{\moveright 5mm \hbox{right}}text !
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+{\dontcomplain\getbuffer}
+\stoplinecorrection
+
+\startbuffer
+text \vbox{\moveleft 25mm \hbox {left}}text !
+text \vbox{\moveright 25mm \hbox{right}}text !
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+{\dontcomplain\getbuffer}
+\stoplinecorrection
+
+Code like this will produce a complaint about an underfull box but we can easily
+get around that:
+
+\startbuffer
+text \raise 5mm \hbox to 2cm {\hss text}
+text \lower -5mm \hbox to 2cm {text\hss}
+text \raise -5mm \hbox to 2cm {\hss text}
+text \lower 5mm \hbox to 2cm {text\hss}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The \type {\hss} primitive injects a glue that when needed will fill up the
+available space. So, here we force the text to the right or left.
+
+\startlinecorrection
+{\dontcomplain\showboxes\getbuffer}
+\stoplinecorrection
+
+We have three kind of boxes: \type {\hbox}, \type {\vbox} and \type {\vtop}:
+
+\startbuffer
+\hbox{\strut height and depth\strut}
+\vbox{\hsize 4cm \strut height and depth\par and width\strut}
+\vtop{\hsize 4cm \strut height and depth\par and width\strut}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+A \type {\vbox} aligns at the bottom and a \type {\vtop} at the top. I have added
+some so called struts to enforce a consistent height and depth. A strut is an
+invisible quantity (consider it a black box) that enforces consistent line
+dimensions: height and depth.
+
+
+\startlinecorrection
+{\dontcomplain\hbox{\showstruts\showboxes\getbuffer}}
+\stoplinecorrection
+
+You can store a box in a register but you need to be careful not to use a
+predefined one. If you need a lot of boxes you can reserve some for your own:
+
+\starttyping
+\newbox\MySpecialBox
+\stoptyping
+
+but normally you can do with one of the scratch registers, like 0, 2, 4, 6 or 8,
+for local boxes, and 1, 3, 5, 7 and 9 for global ones. Registers are used like:
+
+\starttyping
+ \setbox0\hbox{here}
+\global\setbox1\hbox{there}
+\stoptyping
+
+In \CONTEXT\ you can also use
+
+\starttyping
+\setbox\scratchbox \hbox{here}
+\setbox\scratchboxone\hbox{here}
+\setbox\scratchboxtwo\hbox{here}
+\stoptyping
+
+and some more. In fact, there are quite some predefined scratch registers (boxes,
+dimensions, counters, etc). Feel free to investigate further.
+
+When a box is stored, you can consult its dimensions with \type {\wd}, \type
+{\ht} and \type {\dp}. You can of course store them for later use.
+
+\starttyping
+\scratchwidth \wd\scratchbox
+\scratchheight\ht\scratchbox
+\scratchdepth \dp\scratchbox
+\scratchtotal \dimexpr\ht\scratchbox+\dp\scratchbox\relax
+\scratchtotal \htdp\scratchbox
+\stoptyping
+
+The last line is \CONTEXT\ specific. You can also set the dimensions
+
+\starttyping
+\wd\scratchbox 10cm
+\ht\scratchbox 10mm
+\dp\scratchbox 5mm
+\stoptyping
+
+So you can cheat! A box is placed with \type {\copy}, which keeps the original
+intact or \type {\box} which just inserts the box and then wipes the register. In
+practice you seldom need a copy, which is more expensive in runtime anyway. Here
+we use copy because it serves the examples.
+
+\starttyping
+\copy\scratchbox
+\box \scratchbox
+\stoptyping
+
+\stopsection
+
+\startsection[title={\ETEX\ primitives}]
+
+The \ETEX\ extensions don't add something relevant for boxes, apart from that you
+can use the expressions mechanism to mess around with their dimensions. There is
+a mechanism for typesetting r2l within a paragraph but that has limited
+capabilities and doesn't change much as it's mostly a way to trick the backend
+into outputting a stretch of text in the other direction. This feature is not
+available in \LUATEX\ because it has an alternative direction mechanism.
+
+\stopsection
+
+\startsection[title={\LUATEX\ primitives}]
+
+The concept of boxes is the same in \LUATEX\ as in its predecessors but there are
+some aspects to keep in mind. When a box is typeset this happens in \LUATEX:
+
+\startitemize[n]
+ \startitem
+ A list of nodes is constructed. In \LUATEX\ this is a double linked
+ list (so that it can easily be manipulated in \LUA) but \TEX\ itself
+ only uses the forward links.
+ \stopitem
+ \startitem
+ That list is hyphenated, that is: so called discretionary nodes are
+ injected. This depends on the language properties of the glyph
+ (character) nodes.
+ \stopitem
+ \startitem
+ Then ligatures are constructed, if the font has such combinations. When
+ this built|-|in mechanism is used, in \CONTEXT\ we speak of base mode.
+ \stopitem
+ \startitem
+ After that inter|-|character kerns are applied, if the font provides
+ them. Again this is a base mode action.
+ \stopitem
+ \startitem
+ Finally the box gets packaged:
+ \startitemize
+ \startitem
+ In the case of a horizontal box, the list is packaged in a
+ hlist node, basically one liner, and its dimensions are calculated
+ and set.
+ \stopitem
+ \startitem
+ In the case of a vertical box, the paragraph is broken into one
+ or more lines, without hyphenation, with optimal hyphenation or
+ in the worst case with so called emergency stretch applied, and
+ the result becomes a vlist node with its dimensions set.
+ \stopitem
+ \stopitemize
+ \stopitem
+\stopitemize
+
+In traditional \TEX\ the first four steps are interwoven but in \LUATEX\ we need
+them split because the step~5 can be overloaded by a callback. In that case steps
+3 and 4 (and maybe 2) are probably also overloaded, especially when you bring
+handling of fonts under \LUA\ control.
+
+New in \LUATEX\ are three packers: \type {\hpack}, \type {\vpack} and \type
+{\tpack}, which are companions to \type {\hbox}, \type {\vbox} and \type {\vtop}
+but without the callbacks applied. Using them is a bit tricky as you never know
+if a callback should be applied, which, because users can often add their own
+\LUA\ code, is not something predictable.
+
+Another box related extension is direction. There are four possible directions
+but because in \LUAMETATEX\ there are only two. Because this model has been upgraded,
+it will be discusses in the next section. A \CONTEXT\ user is supposed to use the
+official \CONTEXT\ interfaces in order to be downward compatible.
+
+\stopsection
+
+\startsection[title={\LUAMETATEX\ primitives}]
+
+There are two possible directions: left to right (the default) and right to left
+for Hebrew and Arabic. Here is an example that shows how it'd done with low level
+directives:
+
+\startbuffer
+\hbox direction 0 {from left to right}
+\hbox direction 1 {from right to left}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+A low level direction switch is done with:
+
+\startbuffer
+\hbox direction 0
+ {from left to right \textdirection 1 from right to left}
+\hbox direction 1
+ {from right to left \textdirection 1 from left to right}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+but actually this is kind of {\em not done} in \CONTEXT, because there you are
+supposed to use the proper direction switches:
+
+\startbuffer
+\naturalhbox {from left to right}
+\reversehbox {from right to left}
+\naturalhbox {from left to right \righttoleft from right to left}
+\reversehbox {from right to left \lefttoright from left to right}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+Often more is needed to properly support right to left typesetting so using the
+\CONTEXT\ commands is more robust.
+
+In \LUAMETATEX\ the box model has been extended a bit, this as a consequence of
+dropping the vertical directional typesetting, which never worked well. In
+previous sections we discussed the properties width, height and depth and the
+shift resulting from a \type {\raise}, \type {\lower}, \type {\moveleft} and
+\type {\moveright}. Actually, the shift is also used in for instance positioning
+math elements.
+
+The way shifting influences dimensions can be somewhat puzzling. Internally, when
+\TEX\ packages content in a box there are two cases:
+
+\startitemize
+ \startitem
+ When a horizontal box is made, and \typ {height - shift} is larger than the
+ maximum height so far, that delta is taken. When \typ {depth + shift} is
+ larger than the current depth, then that depth is adapted. So, a shift up
+ influences the height and a shift down influences the depth.
+ \stopitem
+ \startitem
+ In the case of vertical packaging, when \typ {width + shift} is larger
+ than the maximum box (line) width so far, that maximum gets bumped. So, a
+ shift to the right can contribute, but a shift to the left cannot result
+ in a negative width. This is also why vertical typesetting, where height
+ and depth are swapped with width, goes wrong: we somehow need to map two
+ properties onto one and conceptually \TEX\ is really set up for
+ horizontal typesetting. (And it's why I decided to just remove it from the
+ engine.)
+ \stopitem
+\stopitemize
+
+This is one of these cases where \TEX\ behaves as expected but it also means that
+there is some limitation to what can be manipulated. Setting the shift using one
+of the four commands has a direct consequence when a box gets packaged which
+happens immediately because the box is an argument to the foursome.
+
+There is in traditional \TEX, probably for good reason, no way to set the shift
+of a box, if only because the effect would normally be none. But in \LUATEX\ we
+can cheat, and therefore, for educational purposed \CONTEXT\ has implements
+some cheats.
+
+We use this sample box:
+
+\startbuffer[demo]
+\setbox\scratchbox\hbox\bgroup
+ \middlegray\vrule width 20mm depth -.5mm height 10mm
+ \hskip-20mm
+ \darkgray \vrule width 20mm height -.5mm depth 5mm
+\egroup
+\stopbuffer
+
+\typebuffer[demo][option=TEX]
+
+When we mess with the shift using the \CONTEXT\ \type {\shiftbox} helper, we see
+no immediate effect. We only get the shift applied when we use another helper,
+\type {\hpackbox}.
+
+\startbuffer
+\hbox\bgroup
+ \showstruts \strut
+ \quad \copy\scratchbox
+ \quad \shiftbox\scratchbox -20mm \copy\scratchbox
+ \quad \hpackbox\scratchbox \box \scratchbox
+ \quad \strut
+\egroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer[demo]\getbuffer
+\stoplinecorrection
+
+When instead we use \type {\vpackbox} we get a different result. This time we
+move left.
+
+\startbuffer
+\hbox\bgroup
+ \showstruts \strut
+ \quad \copy\scratchbox
+ \quad \shiftbox\scratchbox -10mm \copy\scratchbox
+ \quad \vpackbox\scratchbox \copy\scratchbox
+ \quad \strut
+\egroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer[demo]\getbuffer
+\stoplinecorrection
+
+The shift is set via \LUA\ and the repackaging is also done in \LUA, using the
+low level \type {hpack} and \type {vpack} helpers and these just happen to look
+at the shift when doing their job. At the \TEX\ end this never happens.
+
+This long exploration of shifting serves a purpose: it demonstrates that there is
+not that much direct control over boxes apart from their three dimensions.
+However this was never a real problem as one can just wrap a box in another one
+and use kerns to move the embedded box around. But nevertheless I decided to see
+if the engine can be a bit more helpful, if only because all that extra wrapping
+gives some overhead and complications when we want to manipulate boxes. And of
+course it is also a nice playground.
+
+We start with changing the direction. Changing this property doesn't require
+repackaging because directions are not really dealt with in the frontend. When
+a box is converted to (for instance \PDF) the reversion happens.
+
+\startbuffer
+\setbox\scratchbox\hbox{whatever}
+\the\boxdirection\scratchbox: \copy\scratchbox \crlf
+\boxdirection\scratchbox 1
+\the\boxdirection\scratchbox: \copy\scratchbox
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+Another property that can be queried and set is an attribute. In order to get
+a private attribute we define one.
+
+\startbuffer
+\newattribute\MyAt
+\setbox\scratchbox\hbox attr \MyAt 123 {whatever}
+[\the\boxattr\scratchbox\MyAt]
+\boxattr\scratchbox\MyAt 456
+[\the\boxattr\scratchbox\MyAt]
+[\ifnum\boxattr\scratchbox\MyAt>400 okay\fi]
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+The sum of the height and depth is available too. Because for practical reasons
+setting that property is also needed then, the choice was made to distribute the
+value equally over height and depth.
+
+\startbuffer
+\setbox\scratchbox\hbox {height and depth}
+[\the\ht\scratchbox]
+[\the\dp\scratchbox]
+[\the\boxtotal\scratchbox]
+\boxtotal\scratchbox=20pt
+[\the\ht\scratchbox]
+[\the\dp\scratchbox]
+[\the\boxtotal\scratchbox]
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+We've now arrived to a set of properties that relate to each other. They are
+a bit complex and given the number of possibilities one might need to revert
+to some trial and error: orientations and offsets. As with the dimensions,
+directions and attributes, they are passed as box specification. We start
+with the orientation.
+
+\startbuffer
+\hbox \bgroup \showboxes
+ \hbox orientation 0 {right}
+ \quad \hbox orientation 1 {up}
+ \quad \hbox orientation 2 {left}
+ \quad \hbox orientation 3 {down}
+\egroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+When the orientation is set, you can also set an offset. Where shifting around a box
+can have consequences for the dimensions, an offset is virtual. It gets effective
+in the backend, when the contents is converted to some output format.
+
+\startbuffer
+\hbox \bgroup \showboxes
+ \hbox orientation 0 yoffset 10pt {right}
+ \quad \hbox orientation 1 xoffset 10pt {up}
+ \quad \hbox orientation 2 yoffset -10pt {left}
+ \quad \hbox orientation 3 xoffset -10pt {down}
+\egroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+The reason that offsets are related to orientation is that we need to know in
+what direction the offsets have to be applied and this binding forces the user to
+think about it. You can also set the offsets using commands.
+
+\startbuffer
+\setbox\scratchbox\hbox{whatever}%
+1 \copy\scratchbox
+2 \boxorientation\scratchbox 2 \copy\scratchbox
+3 \boxxoffset \scratchbox -15pt \copy\scratchbox
+4 \boxyoffset \scratchbox -15pt \copy\scratchbox
+5
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\ruledhbox{\getbuffer}
+\stoplinecorrection
+
+\startbuffer
+\setbox\scratchboxone\hbox{whatever}%
+\setbox\scratchboxtwo\hbox{whatever}%
+1 \boxxoffset \scratchboxone -15pt \copy\scratchboxone
+2 \boxyoffset \scratchboxone -15pt \copy\scratchboxone
+3 \boxxoffset \scratchboxone -15pt \copy\scratchboxone
+4 \boxyoffset \scratchboxone -15pt \copy\scratchboxone
+5 \boxxmove \scratchboxtwo -15pt \copy\scratchboxtwo
+6 \boxymove \scratchboxtwo -15pt \copy\scratchboxtwo
+7 \boxxmove \scratchboxtwo -15pt \copy\scratchboxtwo
+8 \boxymove \scratchboxtwo -15pt \copy\scratchboxtwo
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\ruledhbox{\getbuffer}
+\stoplinecorrection
+
+The move commands are provides as convenience and contrary to the offsets they do
+adapt the dimensions. Internally, with the box, we register the orientation and
+the offsets and when you apply these commands multiple times the current values
+get overwritten. But \unknown\ because an orientation can be more complex you
+might not get the effects you expect when the options we discuss next are used.
+The reason is that we store the original dimensions too and these come into play
+when these other options are used: anchoring. So, normally you will apply an
+orientation and offsets once only.
+
+% the next bit is derived from the followingup document
+
+The orientation specifier is actually a three byte number that best can be seen
+hexadecimal (although we stay within the decimal domain). There are three
+components: x|-|anchoring, y|-|anchoring and orientation:
+
+\starttyping
+0x<X><Y><O>
+\stoptyping
+
+or in \TEX\ speak:
+
+\starttyping
+"<X><Y><O>
+\stoptyping
+
+The landscape and seascape variants both sit on top of the baseline while the
+flipped variant has its depth swapped with the height. Although this would be
+enough a bit more control is possible.
+
+The vertical options of the horizontal variants anchor on the baseline, lower
+corner, upper corner or center.
+
+\startbuffer
+\ruledhbox orientation "002 {\TEX} and
+\ruledhbox orientation "012 {\TEX} and
+\ruledhbox orientation "022 {\TEX} and
+\ruledhbox orientation "032 {\TEX}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\ruledhbox{\getbuffer}
+\stoplinecorrection
+
+The horizontal options of the horizontal variants anchor in the center, left,
+right, halfway left and halfway right.
+
+\startbuffer
+\ruledhbox orientation "002 {\TEX} and
+\ruledhbox orientation "102 {\TEX} and
+\ruledhbox orientation "202 {\TEX} and
+\ruledhbox orientation "302 {\TEX} and
+\ruledhbox orientation "402 {\TEX}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\ruledhbox{\getbuffer}
+\stoplinecorrection
+
+The orientation has consequences for the dimensions so they are dealt with in the
+expected way in constructing lines, paragraphs and pages, but the anchoring is
+virtual, like the offsets. There are two extra variants for orientation zero: on
+top of baseline or below, with dimensions taken into account.
+
+\startbuffer
+\ruledhbox orientation "000 {\TEX} and
+\ruledhbox orientation "004 {\TEX} and
+\ruledhbox orientation "005 {\TEX}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\ruledhbox{\getbuffer}
+\stoplinecorrection
+
+The anchoring can look somewhat confusing but you need to keep in mind that it is
+normally only used in very controlled circumstances and not in running text.
+Wrapped in macros users don't see the details. We're talking boxes here, so for
+instance:
+
+\startbuffer
+test\quad
+\hbox orientation 3 \bgroup
+ \strut test\hbox orientation "002 \bgroup\strut test\egroup test%
+\egroup \quad
+\hbox orientation 3 \bgroup
+ \strut test\hbox orientation "002 \bgroup\strut test\egroup test%
+\egroup \quad
+\hbox orientation 3 \bgroup
+ \strut test\hbox orientation "012 \bgroup\strut test\egroup test%
+\egroup \quad
+\hbox orientation 3 \bgroup
+ \strut test\hbox orientation "022 \bgroup\strut test\egroup test%
+\egroup \quad
+\hbox orientation 3 \bgroup
+ \strut test\hbox orientation "032 \bgroup\strut test\egroup test%
+\egroup \quad
+\hbox orientation 3 \bgroup
+ \strut test\hbox orientation "042 \bgroup\strut test\egroup test%
+\egroup
+\quad test
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\ruledhbox{\getbuffer}
+\stoplinecorrection
+
+\stopsection
+
+\stopdocument
diff --git a/doc/context/sources/general/manuals/lowlevel/lowlevel-conditionals.tex b/doc/context/sources/general/manuals/lowlevel/lowlevel-conditionals.tex
new file mode 100644
index 000000000..ea3c9e1a2
--- /dev/null
+++ b/doc/context/sources/general/manuals/lowlevel/lowlevel-conditionals.tex
@@ -0,0 +1,1409 @@
+% language=us
+
+\environment lowlevel-style
+
+\startdocument
+ [title=conditionals,
+ color=middleblue]
+
+\startsection[title=Preamble]
+
+\startsubsection[title=Introduction]
+
+You seldom need the low level conditionals because there are quite some so called
+support macros available in \CONTEXT . For instance, when you want to compare two
+values (or more accurate: sequences of tokens), you can do this:
+
+\starttyping[option=TEX]
+\doifelse {foo} {bar} {
+ the same
+} {
+ different
+}
+\stoptyping
+
+But if you look in the \CONTEXT\ code, you will see that often we use primitives
+that start with \type {\if} in low level macros. There are good reasons for this.
+First of all, it looks familiar when you also code in other languages. Another
+reason is performance but that is only true in cases where the snippet of code is
+expanded very often, because \TEX\ is already pretty fast. Using low level \TEX\
+can also be more verbose, which is not always nice in a document source. But, the
+most important reason (for me) is the layout of the code. I often let the look
+and feel of code determine the kind of coding. This also relates to the syntax
+highlighting that I am using, which is consistent for \TEX, \METAPOST, \LUA,
+etc.\ and evolved over decades. If code looks bad, it probably is bad. Of course
+this doesn't mean all my code looks good; you're warned. In general we can say
+that I often use \type {\if...} when coding core macros, and \type {\doifelse...}
+macros in (document) styles and modules.
+
+In the sections below I will discuss the low level conditions in \TEX. For the
+often more convenient \CONTEXT\ wrappers you can consult the source of the system
+and support modules, the wiki and|/|or manuals.
+
+Some of the primitives shown here are only available in \LUATEX, and some only in
+\LUAMETATEX . We could do without them for decades but they were added to these
+engines because of convenience and, more important, because then made for nicer
+code. Of course there's also the fun aspect. This manual is not an invitation to
+use these very low level primitives in your document source. The ones that
+probably make most sense are \type {\ifnum}, \type {\ifdim} and \type {\ifcase}.
+The others are often wrapped into support macros that are more convenient.
+
+In due time I might add more examples and explanations. Also, maybe some more
+tests will show up as part of the \LUAMETATEX\ project.
+
+\stopsubsection
+
+\startsubsection[title={Number and dimensions}]
+
+Numbers and dimensions are basic data types in \TEX. When you enter one, a number
+is just that but a dimension gets a unit. Compare:
+
+\starttyping[option=TEX]
+1234
+1234pt
+\stoptyping
+
+If you also use \METAPOST, you need to be aware of the fact that in that language
+there are not really dimensions. The \type {post} part of the name implies that
+eventually a number becomes a \POSTSCRIPT\ unit which represents a base point (\type
+{bp}) in \TEX. When in \METAPOST\ you entry \type {1234pt} you actually multiply
+\type {1234} by the variable \type {pt}. In \TEX\ on the other hand, a unit like
+\type {pt} is one of the keywords that gets parsed. Internally dimensions are
+also numbers and the unit (keyword) tells the scanner what multiplier to use.
+When that multiplier is one, we're talking of scaled points, with the unit \type
+{sp}.
+
+\startbuffer
+\the\dimexpr 12.34pt \relax
+\the\dimexpr 12.34sp \relax
+\the\dimexpr 12.99sp \relax
+\the\dimexpr 1234sp \relax
+\the\numexpr 1234 \relax
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlines \getbuffer \stoplines
+
+When we serialize a dimension it always shows the dimension in points, unless we
+serialize it as number.
+
+\startbuffer
+\scratchdimen1234sp
+\number\scratchdimen
+\the\scratchdimen
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlines \getbuffer \stoplines
+
+When a number is scanned, the first thing that is taken care of is the sign. In many
+cases, when \TEX\ scans for something specific it will ignore spaces. It will
+happily accept multiple signs:
+
+\startbuffer
+\number +123
+\number +++123
+\number + + + 123
+\number +-+-+123
+\number --123
+\number ---123
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlines \getbuffer \stoplines
+
+Watch how the negation accumulates. The scanner can handle decimal, hexadecimal
+and octal numbers:
+
+\startbuffer
+\number -123
+\number -"123
+\number -'123
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlines \getbuffer \stoplines
+
+A dimension is scanned like a number but this time the scanner checks for upto
+three parts: an either or not signed number, a period and a fraction. Here no
+number means zero, so the next is valid:
+
+\startbuffer
+\the\dimexpr . pt \relax
+\the\dimexpr 1. pt \relax
+\the\dimexpr .1pt \relax
+\the\dimexpr 1.1pt \relax
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlines \getbuffer \stoplines
+
+Again we can use hexadecimal and octal numbers but when these are entered, there
+can be no fractional part.
+
+\startbuffer
+\the\dimexpr 16 pt \relax
+\the\dimexpr "10 pt \relax
+\the\dimexpr '20 pt \relax
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlines \getbuffer \stoplines
+
+The reason for discussing numbers and dimensions here is that there are cases where
+when \TEX\ expects a number it will also accept a dimension. It is good to know that
+for instance a macro defined with \type {\chardef} or \type {\mathchardef} also is
+treated as a number. Even normal characters can be numbers, when prefixed by a \type
+{`} (backtick).
+
+The maximum number in \TEX\ is 2147483647 so we can do this:
+
+\starttyping[option=TEX]
+\scratchcounter2147483647
+\stoptyping
+
+but not this
+
+\starttyping[option=TEX]
+\scratchcounter2147483648
+\stoptyping
+
+as it will trigger an error. A dimension can be positive and negative so there we
+can do at most:
+
+\starttyping[option=TEX]
+\scratchdimen 1073741823sp
+\stoptyping
+
+\startbuffer
+\scratchdimen1073741823sp
+\number\scratchdimen
+\the\scratchdimen
+\scratchdimen16383.99998pt
+\number\scratchdimen
+\the\scratchdimen
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlines
+\getbuffer
+\stoplines
+
+We can also do this:
+
+\startbuffer
+\scratchdimen16383.99999pt
+\number\scratchdimen
+\the\scratchdimen
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlines
+\getbuffer
+\stoplines
+
+but the next one will fail:
+
+\starttyping[option=TEX]
+\scratchdimen16383.9999999pt
+\stoptyping
+
+Just keep in mind that \TEX\ scans both parts as number so the error comes from
+checking if those numbers combine well.
+
+\startbuffer
+\ifdim 16383.99999 pt = 16383.99998 pt the same \else different \fi
+\ifdim 16383.999979 pt = 16383.999980 pt the same \else different \fi
+\ifdim 16383.999987 pt = 16383.999991 pt the same \else different \fi
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+Watch the difference in dividing, the \type {/} rounds, while the \type {:}
+truncates.
+
+\startlines
+\getbuffer
+\stoplines
+
+You need to be aware of border cases, although in practice they never really
+are a problem:
+
+\startbuffer
+\ifdim \dimexpr16383.99997 pt/2\relax = \dimexpr 16383.99998 pt/2\relax
+ the same \else different
+\fi
+\ifdim \dimexpr16383.99997 pt:2\relax = \dimexpr 16383.99998 pt:2\relax
+ the same \else different
+\fi
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlines
+\getbuffer
+\stoplines
+
+\startbuffer
+\ifdim \dimexpr1.99997 pt/2\relax = \dimexpr 1.99998 pt/2\relax
+ the same \else different
+\fi
+\ifdim \dimexpr1.99997 pt:2\relax = \dimexpr 1.99998 pt:2\relax
+ the same \else different
+\fi
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlines
+\getbuffer
+\stoplines
+
+\startbuffer
+\ifdim \dimexpr1.999999 pt/2\relax = \dimexpr 1.9999995 pt/2\relax
+ the same \else different
+\fi
+\ifdim \dimexpr1.999999 pt:2\relax = \dimexpr 1.9999995 pt:2\relax
+ the same \else different
+\fi
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlines
+\getbuffer
+\stoplines
+
+This last case demonstrates that at some point the digits get dropped (still
+assuming that the fraction is within the maximum permitted) so these numbers then
+are the same. Anyway, this is not different in other programming languages and
+just something you need to be aware of.
+
+\stopsubsection
+
+\stopsection
+
+\startsection[title={\TEX\ primitives}]
+
+\startsubsection[title={\tex{if}}]
+
+I seldom use this one. Internally \TEX\ stores (and thinks) in terms of tokens.
+If you see for instance \type {\def} or \type {\dimen} or \type {\hbox} these all
+become tokens. But characters like \type {A} or {@} also become tokens. In this
+test primitive all non|-|characters are considered to be the same. In the next
+examples this is demonstrated.
+
+\startbuffer
+[\if AB yes\else nop\fi]
+[\if AA yes\else nop\fi]
+[\if CDyes\else nop\fi]
+[\if CCyes\else nop\fi]
+[\if\dimen\font yes\else nop\fi]
+[\if\dimen\font yes\else nop\fi]
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+Watch how spaces after the two characters are kept: \inlinebuffer . This primitive looks
+at the next two tokens but when doing so it expands. Just look at the following:
+
+\startbuffer
+\def\AA{AA}%
+\def\AB{AB}%
+[\if\AA yes\else nop\fi]
+[\if\AB yes\else nop\fi]
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+We get: \inlinebuffer .
+
+% protected macros
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifcat}}]
+
+In \TEX\ characters (in the input) get interpreted according to their so called
+catcodes. The most common are letters (alphabetic) and and other (symbols) but
+for instance the backslash has the property that it starts a command, the dollar
+signs trigger math mode, while the curly braced deal with grouping. If for
+instance either or not the ampersand is special (for instance as column separator
+in tables) depends on the macro package.
+
+\startbuffer
+[\ifcat AB yes\else nop\fi]
+[\ifcat AA yes\else nop\fi]
+[\ifcat CDyes\else nop\fi]
+[\ifcat CCyes\else nop\fi]
+[\ifcat C1yes\else nop\fi]
+[\ifcat\dimen\font yes\else nop\fi]
+[\ifcat\dimen\font yes\else nop\fi]
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+This time we also compare a letter with a number: \inlinebuffer . In that case
+the category codes differ (letter vs other) but in this test comparing the
+letters result in a match. This is a test that is used only once in \CONTEXT\ and
+even that occasion is dubious and will go away.
+
+You can use \type {\noexpand} to prevent expansion:
+
+\startbuffer
+\def\A{A}%
+\let\B B%
+\def\C{D}%
+\let\D D%
+[\ifcat\noexpand\A Ayes\else nop\fi]
+[\ifcat\noexpand\B Byes\else nop\fi]
+[\ifcat\noexpand\C Cyes\else nop\fi]
+[\ifcat\noexpand\C Dyes\else nop\fi]
+[\ifcat\noexpand\D Dyes\else nop\fi]
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+We get: \inlinebuffer, so who still thinks that \TEX\ is easy to understand for a
+novice user?
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifnum}}]
+
+This condition compares its argument with another one, separated by an \type {<},
+\type {=} or \type {>} character.
+
+\starttyping[option=TEX]
+\ifnum\scratchcounter<0
+ less than
+\else\ifnum\scratchcounter>0
+ more than
+\else
+ equal to
+\fi zero
+\stoptyping
+
+This is one of these situations where a dimension can be used instead. In that
+case the dimension is in scaled points.
+
+\starttyping[option=TEX]
+\ifnum\scratchdimen<0
+ less than
+\else\ifnum\scratchdimen>0
+ more than
+\else
+ equal to
+\fi zero
+\stoptyping
+
+Of course this equal treatment of a dimension and number is only true when the
+dimension is a register or box property.
+
+\stopsubsection
+
+\startsection[title={\tex{ifdim}}]
+
+This condition compares one dimension with another one, separated by an \type {<},
+\type {=} or \type {>} sign.
+
+\starttyping[option=TEX]
+\ifdim\scratchdimen<0pt
+ less than
+\else\ifdim\scratchdimen>0pt
+ more than
+\else
+ equal to
+\fi zero
+\stoptyping
+
+While when comparing numbers a dimension is a valid quantity but here you cannot
+mix them: something with a unit is expected.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifodd}}]
+
+This one can come in handy, although in \CONTEXT\ it is only used in checking for
+an odd of even page number.
+
+\startbuffer
+\scratchdimen 3sp
+\scratchcounter4
+
+\ifodd\scratchdimen very \else not so \fi odd
+\ifodd\scratchcounter very \else not so \fi odd
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+As with the previously discussed \type {\ifnum} you can use a dimension variable
+too, which is then interpreted as representing scaled points. Here we get:
+
+\startlines
+\getbuffer
+\stoplines
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifvmode}}]
+
+This is a rather trivial check. It takes no arguments and just is true when we're
+in vertical mode. Here is an example:
+
+\startbuffer
+\hbox{\ifvmode\else\par\fi\ifvmode v\else h\fi mode}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+We're always in horizontal mode and issuing a \type {\par} inside a horizontal
+box doesn't change that, so we get: \ruledhbox{\inlinebuffer}.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifhmode}}]
+
+As with \type {\ifvmode} this one has no argument and just tells if we're in
+vertical mode.
+
+\startbuffer
+\vbox {
+ \noindent \ifhmode h\else v\fi mode
+ \par
+ \ifhmode h\else \noindent v\fi mode
+}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+You can use it for instance to trigger injection of code, or prevent that some
+content (or command) is done more than once:
+
+\startlinecorrection
+\ruledhbox{\inlinebuffer}
+\stoplinecorrection
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifmmode}}]
+
+Math is something very \TEX\ so naturally you can check if you're in math mode.
+here is an example of using this test:
+
+\starttyping[option=TEX]
+\def\enforcemath#1{\ifmmode#1\else$ #1 $\fi}
+\stoptyping
+
+Of course in reality macros that do such things are more advanced than this one.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifinner}}]
+
+\startbuffer
+\def\ShowMode
+ {\ifhmode \ifinner inner \fi hmode
+ \else\ifvmode \ifinner inner \fi vmode
+ \else\ifmmode \ifinner inner \fi mmode
+ \else \ifinner inner \fi unset
+ \fi\fi\fi}
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+\startbuffer
+\ShowMode \ShowMode
+
+\vbox{\ShowMode}
+
+\hbox{\ShowMode}
+
+$\ShowMode$
+
+$$\ShowMode$$
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The first line has two tests, where the first one changes the mode to horizontal
+simply because a text has been typeset. Watch how display math is not inner.
+
+\startpacked
+\startlines
+\getbuffer
+\stoplines
+\stoppacked
+
+By the way, moving the \type {\ifinner} test outside the branches (to the top of
+the macro) won't work because once the word \type {inner} is typeset we're no
+longer in vertical mode, if we were at all.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifvoid}}]
+
+A box is one of the basic concepts in \TEX. In order to understand this primitive
+we present four cases:
+
+\startbuffer
+\setbox0\hbox{} \ifvoid0 void \else content \fi
+\setbox0\hbox{123} \ifvoid0 void \else content \fi
+\setbox0\hbox{} \box0 \ifvoid0 void \else content \fi
+\setbox0\hbox to 10pt{} \ifvoid0 void \else content \fi
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+In the first case, we have a box which is empty but it's not void. It helps to
+know that internally an hbox is actually an object with a pointer to a linked
+list of nodes. So, the first two can be seen as:
+
+\starttyping
+hlist -> [nothing]
+hlist -> 1 -> 2 -> 3 -> [nothing]
+\stoptyping
+
+but in any case there is a hlist. The third case puts something in a hlist but
+then flushes it. Now we have not even the hlist any more; the box register has
+become void. The last case is a variant on the first. It is an empty box with a
+given width. The outcome of the four lines (with a box flushed in between) is:
+
+\startlines
+\getbuffer
+\stoplines
+
+So, when you want to test if a box is really empty, you need to test also its
+dimensions, which can be up to three tests, depending on your needs.
+
+\startbuffer
+\setbox0\emptybox \ifvoid0 void\else content\fi
+\setbox0\emptybox \wd0=10pt \ifvoid0 void\else content\fi
+\setbox0\hbox to 10pt {} \ifvoid0 void\else content\fi
+\setbox0\hbox {} \wd0=10pt \ifvoid0 void\else content\fi
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+Setting a dimension of a void voix (empty) box doesn't make it less void:
+
+\startlines
+\getbuffer
+\stoplines
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifhbox}}]
+
+This test takes a box number and gives true when it is an hbox.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifvbox}}]
+
+This test takes a box number and gives true when it is an vbox. Both a \type
+{\vbox} and \type {\vtop} are vboxes, the difference is in the height and depth
+and the baseline. In a \type {\vbox} the last line determines the baseline
+
+\startlinecorrection
+\ruledvbox{vbox or vtop\par vtop or vbox}
+\stoplinecorrection
+
+And in a \type {\vtop} the first line takes control:
+
+\startlinecorrection
+\ruledvtop{vbox or vtop\par vtop or vbox}
+\stoplinecorrection
+
+but, once wrapped, both internally are just vlists.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifx}}]
+
+This test is actually used a lot in \CONTEXT: it compares two token(list)s:
+
+\startbuffer
+ \ifx a b Y\else N\fi
+ \ifx ab Y\else N\fi
+\def\A {a}\def\B{b}\ifx \A\B Y\else N\fi
+\def\A{aa}\def\B{a}\ifx \A\B Y\else N\fi
+\def\A {a}\def\B{a}\ifx \A\B Y\else N\fi
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+Here the result is: \quotation{\inlinebuffer}. It does not expand the content, if
+you want that you need to use an \type {\edef} to create two (temporary) macros
+that get compared, like in:
+
+\starttyping[option=TEX]
+\edef\TempA{...}\edef\TempB{...}\ifx\TempA\TempB ...\else ...\fi
+\stoptyping
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifeof}}]
+
+This test checks if a the pointer in a given input channel has reached its end.
+It is also true when the file is not present. The argument is a number which
+relates to the \type {\openin} primitive that is used to open files for reading.
+
+\stopsubsection
+
+\startsubsection[title={\tex{iftrue}}]
+
+It does what it says: always true.
+
+\stopsubsection
+
+\startsubsection[title={\tex{iffalse}}]
+
+It does what it says: always false.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifcase}}]
+
+The general layout of an \type {\ifcase} tests is as follows:
+
+\starttyping[option=TEX]
+\ifcase<number>
+ when zero
+\or
+ when one
+\or
+ when two
+\or
+ ...
+\else
+ when something else
+\fi
+\stoptyping
+
+As in other places a number is a sequence of signs followed by one of more digits
+
+\stopsubsection
+
+\stopsection
+
+\startsection[title={\ETEX\ primitives}]
+
+\startsubsection[title={\tex{ifdefined}}]
+
+This primitive was introduced for checking the existence of a macro (or primitive)
+and with good reason. Say that you want to know if \type {\MyMacro} is defined? One
+way to do that is:
+
+\startbuffer
+\ifx\MyMacro\undefined
+ {\bf undefined indeed}
+\fi
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+This results in: \inlinebuffer , but is this macro really undefined? When \TEX\
+scans your source and sees a the escape character (the forward slash) it will
+grab the next characters and construct a control sequence from it. Then it finds
+out that there is nothing with that name and it will create a hash entry for a
+macro with that name but with no meaning. Because \type {\undefined} is also not
+defined, these two macros have the same meaning and therefore the \type {\ifx} is
+true. Imagine that you do this many times, with different macro names, then your
+hash can fill up. Also, when a user defined \type {\undefined} you're suddenly
+get a different outcome.
+
+In order to catch the last problem there is the option to test directly:
+
+\startbuffer
+\ifdefined\MyOtherMacro \else
+ {\bf also undefined}
+\fi
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+This (or course) results in: \inlinebuffer, but the macro is still sort of
+defined (with no meaning). The next section shows how to get around this.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifcsname}}]
+
+A macro is often defined using a ready made name, as in:
+
+\starttyping[option=TEX]
+\def\OhYes{yes}
+\stoptyping
+
+The name is made from characters with catcode letter which means that you cannot
+use for instance digits or underscores unless you also give these characters that
+catcode, which is not that handy in a document. You can however use \type
+{\csname} to define a control sequence with any character in the name, like:
+
+\starttyping[option=TEX]
+\expandafter\def\csname Oh Yes : 1\endcsname{yes}
+\stoptyping
+
+Later on you can get this one with \type {\csname}:
+
+\starttyping[option=TEX]
+\csname Oh Yes : 1\endcsname
+\stoptyping
+
+However, if you say:
+
+\starttyping[option=TEX]
+\csname Oh Yes : 2\endcsname
+\stoptyping
+
+you won't get some result, nor a message about an undefined control sequence, but
+the name triggers a define anyway, this time not with no meaning (undefined) but
+as equivalent to \type {\relax}, which is why
+
+\starttyping[option=TEX]
+\expandafter\ifx\csname Oh Yes : 2\endcsname\relax
+ {\bf relaxed indeed}
+\fi
+\stoptyping
+
+is the way to test its existence. As with the test in the previous section,
+this can deplete the hash when you do lots of such tests. The way out of this
+is:
+
+\starttyping[option=TEX]
+\ifcsname Oh Yes : 2\endcsname \else
+ {\bf unknown indeed}
+\fi
+\stoptyping
+
+This time there is no hash entry created and therefore there is not even an
+undefined control sequence.
+
+In \LUATEX\ there is an option to return false in case of a messy expansion
+during this test, and in \LUAMETATEX\ that is default. This means that tests can
+be made quite robust as it is pretty safe to assume that names that make sense
+are constructed from regular characters and not boxes, font switches, etc.
+
+\stopsubsection
+
+\startsubsection[title={\tex{iffontchar}}]
+
+This test was also part of the \ETEX\ extensions and it can be used to see if
+a font has a character.
+
+\startbuffer
+\iffontchar\font`A
+ {\em This font has an A!}
+\fi
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+And, as expected, the outcome is: \quotation {\inlinebuffer}. The test takes two
+arguments, the first being a font identifier and the second a character number,
+so the next checks are all valid:
+
+\starttyping[option=TEX]
+\iffontchar\font `A yes\else nop\fi\par
+\iffontchar\nullfont `A yes\else nop\fi\par
+\iffontchar\textfont0`A yes\else nop\fi\par
+\stoptyping
+
+In the perspective of \LUAMETATEX\ I considered also supporting \type {\fontid}
+but it got a bit messy due to the fact that this primitive expands in a different
+way so this extension was rejected.
+
+\stopsubsection
+
+\startsubsection[title={\tex{unless}}]
+
+You can negate the results of a test by using the \type {\unless} prefix, so for
+instance you can replace:
+
+\starttyping[option=TEX]
+\ifdim\scratchdimen=10pt
+ \dosomething
+\else\ifdim\scratchdimen<10pt
+ \dosomething
+\fi\fi
+\stoptyping
+
+by:
+
+\starttyping[option=TEX]
+\unless\ifdim\scratchdimen>10pt
+ \dosomething
+\fi
+\stoptyping
+
+\stopsubsection
+
+\stopsection
+
+\startsection[title={\LUATEX\ primitives}]
+
+\startsubsection[title={\tex{ifincsname}}]
+
+As it had no real practical usage uit might get dropped in \LUAMETATEX, so it
+will not be discussed here.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifprimitive}}]
+
+As it had no real practical usage due to limitations, this one is not available
+in \LUAMETATEX\ so it will not be discussed here.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifabsnum}}]
+
+This test is inherited from \PDFTEX\ and behaves like \type {\ifnum} but first
+turns a negative number into a positive one.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifabsdim}}]
+
+This test is inherited from \PDFTEX\ and behaves like \type {\ifdim} but first
+turns a negative dimension into a positive one.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifcondition}}]
+
+This is not really a test but in order to unstand that you need to know how
+\TEX\ internally deals with tests.
+
+\starttyping[option=TEX]
+\ifdimen\scratchdimen>10pt
+ \ifdim\scratchdimen<20pt
+ result a
+ \else
+ result b
+ \fi
+\else
+ result c
+\fi
+\stoptyping
+
+When we end up in the branch of \quotation {result a} we need to skip two \type
+{\else} branches after we're done. The \type {\if..} commands increment a level
+while the \type {\fi} decrements a level. The \type {\else} needs to be skipped
+here. In other cases the true branch needs to be skipped till we end up a the
+right \type {\else}. When doing this skipping, \TEX\ is not interested in what it
+encounters beyond these tokens and this skipping (therefore) goes real fast but
+it does see nested conditions and doesn't interpret grouping related tokens.
+
+A side effect of this is that the next is not working as expected:
+
+\starttyping[option=TEX]
+\def\ifmorethan{\ifdim\scratchdimen>}
+\def\iflessthan{\ifdim\scratchdimen<}
+
+\ifmorethan10pt
+ \iflessthan20pt
+ result a
+ \else
+ result b
+ \fi
+\else
+ result c
+\fi
+\stoptyping
+
+The \type{\iflessthan} macro is not seen as an \type {\if...} so the nesting gets
+messed up. The solution is to fool the scanner in thinking that it is. Say we have:
+
+\startbuffer
+\scratchdimen=25pt
+
+\def\ifmorethan{\ifdim\scratchdimen>}
+\def\iflessthan{\ifdim\scratchdimen<}
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+and:
+
+\startbuffer
+\ifcondition\ifmorethan10pt
+ \ifcondition\iflessthan20pt
+ result a
+ \else
+ result b
+ \fi
+\else
+ result c
+\fi
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+When we expand this snippet we get: \quotation {\inlinebuffer} and no error
+concerning a failure in locating the right \type {\fi's}. So, when scanning the
+\type {\ifcondition} is seen as a valid \type {\if...} but when the condition is
+really expanded it gets ignored and the \type {\ifmorethan} has better come up
+with a match or not.
+
+In this perspective it is also worth mentioning that nesting problems can be
+avoided this way:
+
+\starttyping[option=TEX]
+\def\WhenTrue {something \iftrue ...}
+\def\WhenFalse{something \iffalse ...}
+
+\ifnum\scratchcounter>123
+ \let\next\WhenTrue
+\else
+ \let\next\WhenFalse
+\fi
+\next
+\stoptyping
+
+This trick is mentioned in The \TeX book and can also be found in the plain \TEX\
+format. A variant is this:
+
+\starttyping[option=TEX]
+\ifnum\scratchcounter>123
+ \expandafter\WhenTrue
+\else
+ \expandafter\WhenFalse
+\fi
+\stoptyping
+
+but using \type {\expandafter} can be quite intimidating especially when there
+are multiple in a row. It can also be confusing. Take this: an \type
+{\ifcondition} expects the code that follows to produce a test. So:
+
+\starttyping[option=TEX]
+\def\ifwhatever#1%
+ {\ifdim#1>10pt
+ \expandafter\iftrue
+ \else
+ \expandafter\iffalse
+ \fi}
+
+\ifcondition\ifwhatever{10pt}
+ result a
+\else
+ result b
+\fi
+\stoptyping
+
+This will not work! The reason is in the already mentioned fact that when we end
+up in the greater than \type {10pt} case, the scanner will happily push the \type
+{\iftrue} after the \type {\fi}, which is okay, but when skipping over the \type
+{\else} it sees a nested condition without matching \type {\fi}, which makes ity
+fail. I will spare you a solution with lots of nasty tricks, so here is the clean
+solution using \type {\ifcondition}:
+
+\starttyping[option=TEX]
+\def\truecondition {\iftrue}
+\def\falsecondition{\iffalse}
+
+\def\ifwhatever#1%
+ {\ifdim#1>10pt
+ \expandafter\truecondition
+ \else
+ \expandafter\falsecondition
+ \fi}
+
+\ifcondition\ifwhatever{10pt}
+ result a
+\else
+ result b
+\fi
+\stoptyping
+
+It will be no surprise that the two macros at the top are predefined in \CONTEXT.
+It might be more of a surprise that at the time of this writing the usage in
+\CONTEXT\ of this \type {\ifcondition} primitive is rather minimal. But that
+might change.
+
+As a further teaser I'll show another simple one,
+
+\startbuffer
+\def\HowOdd#1{\unless\ifnum\numexpr ((#1):2)*2\relax=\numexpr#1\relax}
+
+\ifcondition\HowOdd{1}very \else not so \fi odd
+\ifcondition\HowOdd{2}very \else not so \fi odd
+\ifcondition\HowOdd{3}very \else not so \fi odd
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+This renders:
+
+\startlines
+\getbuffer
+\stoplines
+
+The code demonstrates several tricks. First of all we use \type {\numexpr} which
+permits more complex arguments, like:
+
+\starttyping[option=TEX]
+\ifcondition\HowOdd{4+1}very \else not so \fi odd
+\ifcondition\HowOdd{2\scratchcounter+9}very \else not so \fi odd
+\stoptyping
+
+Another trick is that we use an integer division (the \type {:}) which is an
+operator supported by \LUAMETATEX .
+
+\stopsubsection
+
+\stopsection
+
+\startsection[title={\LUAMETATEX\ primitives}]
+
+\startsubsection[title={\tex{ifcmpnum}}]
+
+This one is part of s set of three tests that all are a variant of a \type
+{\ifcase} test. A simple example of the first test is this:
+
+\starttyping[option=TEX]
+\ifcmpnum 123 345 less \or equal \else more \fi
+\stoptyping
+
+The test scans for two numbers, which of course can be registers or expressions,
+and sets the case value to 0, 1 or 2, which means that you then use the normal
+\type {\or} and \type {\else} primitives for follow up on the test.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifchknum}}]
+
+This test scans a number and when it's okay sets the case value to 1, and otherwise
+to 2. So you can do the next:
+
+\starttyping[option=TEX]
+\ifchknum 123\or good \else bad \fi
+\ifchknum bad\or good \else bad \fi
+\stoptyping
+
+An error message is suppressed and the first \type {\or} can be seen as a sort of
+recovery token, although in fact we just use the fast scanner mode that comes
+with the \type {\ifcase}: because the result is 1 or 2, we never see invalid
+tokens.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifnumval}}]
+
+A sort of combination of the previous two is \type {\ifnumval} which checks a
+number but also if it's less, equal or more than zero:
+
+\starttyping[option=TEX]
+\ifnumval 123\or less \or equal \or more \else error \fi
+\ifnumval bad\or less \or equal \or more \else error \fi
+\stoptyping
+
+You can decide to ignore the bad number or do something that makes more sense.
+Often the to be checked value will be the content of a macro or an argument like
+\type {#1}.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifcmpdim}}]
+
+This test is like \type {\ifcmpnum} but for dimensions.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifchkdim}}]
+
+This test is like \type {\ifchknum} but for dimensions.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifdimval}}]
+
+This test is like \type {\ifnumval} but for dimensions.
+
+\stopsubsection
+
+\startsubsection[title={\tex{iftok}}]
+
+Although this test is still experimental it can be used. What happens is that
+two to be compared \quote {things} get scanned for. For each we first gobble
+spaces and \type {\relax} tokens. Then we can have several cases:
+
+\startitemize[n,packed]
+ \startitem
+ When we see a left brace, a list of tokens is scanned upto the
+ matching right brace.
+ \stopitem
+ \startitem
+ When a reference to a token register is seen, that register is taken as
+ value.
+ \stopitem
+ \startitem
+ When a reference to an internal token register is seen, that register is
+ taken as value.
+ \stopitem
+ \startitem
+ When a macro is seen, its definition becomes the to be compared value.
+ \stopitem
+ \startitem
+ When a number is seen, the value of the corresponding register is taken
+ \stopitem
+\stopitemize
+
+An example of the first case is:
+
+\starttyping[option=TEX]
+\iftok {abc} {def}%
+ ...
+\else
+ ...
+\fi
+\stoptyping
+
+The second case goes like this:
+
+\starttyping[option=TEX]
+\iftok\scratchtoksone\scratchtokstwo
+ ...
+\else
+ ...
+\fi
+\stoptyping
+
+Case one and four mixed:
+
+\starttyping[option=TEX]
+\iftok{123}\TempX
+ ...
+\else
+ ...
+\fi
+\stoptyping
+
+The last case is more a catch: it will issue an error when no number is given.
+Eventually that might become a bit more clever (depending on our needs.)
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifcstok}}]
+
+There is a subtle difference between this one and \type {iftok}: spaces
+and \type {\relax} tokens are skipped but nothing gets expanded. So, when
+we arrive at the to be compared \quote {things} we look at what is there,
+as|-|is.
+
+\stopsubsection
+
+\startsubsection[title={\tex{iffrozen}}]
+
+{\em This is an experimental test.} Commands can be defined with the \type
+{\frozen} prefix and this test can be used to check if that has been the case.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifprotected}}]
+
+Commands can be defined with the \type {\protected} prefix (or in \CONTEXT, for
+historic reasons, with \type {\unexpanded}) and this test can be used to check if
+that has been the case.
+
+\stopsubsection
+
+\startsubsection[title={\tex{ifusercmd}}]
+
+{\em This is an experimental test.} It can be used to see if the command is
+defined at the user level or is a build in one. This one might evolve.
+
+\stopsubsection
+
+\startsubsection[title={\tex{orelse}}]
+
+This it not really a test primitive but it does act that way. Say that we have this:
+
+\starttyping[option=TEX]
+\ifdim\scratchdimen>10pt
+ case 1
+\else\ifdim\scratchdimen<20pt
+ case 2
+\else\ifcount\scratchcounter>10
+ case 3
+\else\ifcount\scratchcounter<20
+ case 4
+\fi\fi\fi\fi
+\stoptyping
+
+A bit nicer looks this:
+
+\starttyping[option=TEX]
+\ifdim\scratchdimen>10pt
+ case 1
+\orelse\ifdim\scratchdimen<20pt
+ case 2
+\orelse\ifcount\scratchcounter>10
+ case 3
+\orelse\ifcount\scratchcounter<20
+ case 4
+\fi
+\stoptyping
+
+We stay at the same level and the only test that cannot be used this way is \type
+{\ifcondition} but that is no real problem. Sometimes a more flat test tree had
+advantages but if you think that it gives better performance then you will be
+disappointed. The fact that we stay at the same level is compensated by a bit
+more parsing, so unless you have millions such cases (or expansions) it might
+make a bit of a difference. As mentioned, I'm a bit sensitive for how code looks so
+that was the main motivation for introducing it.
+
+A rather neat trick is the definition of \type {\quitcondition}:
+
+\starttyping[option=TEX]
+\def\quitcondition{\orelse\iffalse}
+\stoptyping
+
+This permits:
+
+\starttyping[option=TEX]
+\ifdim\scratchdimen>10pt
+ case 1a
+ \quitcondition
+ case 4b
+\fi
+\stoptyping
+
+where, of course, the quitting normally is the result of some intermediate extra
+test. But let me play safe here: beware of side effects.
+
+\stopsubsection
+
+\stopsection
+
+\startsection[title={For the brave}]
+
+\startsubsection[title={Full expansion}]
+
+If you don't understand the following code, don't worry. There is seldom much
+reason to go this complex but obscure \TEX\ code attracts some users so \unknown
+
+When you have a macro that has for instance assignments, and when you expand that
+macro inside an \type {\edef}, these assignments are not actually expanded but
+tokenized. In \LUATEX\ there is a way to immediately apply these assignments and
+that feature can be used to write a fully expandable user test. For instance:
+
+\startbuffer
+\def\truecondition {\iftrue}
+\def\falsecondition{\iffalse}
+
+\def\fontwithidhaschar#1#2%
+ {\immediateassignment\scratchcounter\numexpr\fontid\font\relax
+ \immediateassignment\setfontid\numexpr#1\relax
+ \iffontchar\font\numexpr#2\relax
+ \immediateassignment\setfontid\scratchcounter
+ \expandafter\truecondition
+ \else
+ \expandafter\falsecondition
+ \fi}
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+The \type {\iffontchar} test doesn't handle numeric font id, simply because
+at the time it was added to \ETEX, there was no access to these id's. Now we
+can do:
+
+\startbuffer
+\edef\foo{\fontwithidhaschar{1} {75}yes\else nop\fi} \meaning\foo
+\edef\foo{\fontwithidhaschar{1}{999}yes\else nop\fi} \meaning\foo
+
+[\ifcondition\fontwithidhaschar{1} {75}yes\else nop\fi]
+[\ifcondition\fontwithidhaschar{1}{999}yes\else nop\fi]
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+These result in:
+
+\startlines
+\getbuffer
+\stoplines
+
+If you remove the \type {\immediateassignment} in the definition above then the
+typeset results are still the same but the meanings of \type {\foo} look
+different: they contain the assignments and the test for the character is
+actually done when constructing the content of the \type {\edef}, but for the
+current font. So, basically that test is now useless.
+
+\stopsubsection
+
+\startsubsection[title={User defined if's}]
+
+There is a \type {\newif} macro that defines three other macros:
+
+\starttyping[option=TEX]
+\newif\ifOnMyOwnTerms
+\stoptyping
+
+After this, not only \type {\ifOnMyOwnTerms} is defined, but also:
+
+\starttyping[option=TEX]
+\OnMyOwnTermstrue
+\OnMyOwnTermsfalse
+\stoptyping
+
+These two actually are macros that redefine \type {\ifOnMyOwnTerms} to be either
+equivalent to \type {\iftrue} and \type {\iffalse}. The (often derived from plain
+\TEX) definition of \type {\newif} is a bit if a challenge as it has to deal with
+removing the \type {if} in order to create the two extra macros and also make
+sure that it doesn't get mixed up in a catcode jungle.
+
+In \CONTEXT\ we have a variant:
+
+\starttyping[option=TEX]
+\newconditional\MyConditional
+\stoptyping
+
+that can be used with:
+
+\starttyping[option=TEX]
+\settrue\MyConditional
+\setfalse\MyConditional
+\stoptyping
+
+and tested like:
+
+\starttyping[option=TEX]
+\ifconditional\MyConditional
+ ...
+\else
+ ...
+\fi
+\stoptyping
+
+This one is cheaper on the hash and doesn't need the two extra macros per test.
+The price is the use of \type {\ifconditional}, which is {\em not} to confused
+with \type {\ifcondition} (it has bitten me already a few times).
+
+\stopsubsection
+
+\stopsection
+
+\startsubject[title=Colofon]
+
+\starttabulate
+\NC Author \NC Hans Hagen \NC \NR
+\NC \CONTEXT \NC \contextversion \NC \NR
+\NC \LUAMETATEX \NC \texengineversion \NC \NR
+\NC Support \NC www.pragma-ade.com \NC \NR
+\NC \NC contextgarden.net \NC \NR
+\stoptabulate
+
+\stopsubject
+
+\stopdocument
diff --git a/doc/context/sources/general/manuals/lowlevel/lowlevel-expansion.tex b/doc/context/sources/general/manuals/lowlevel/lowlevel-expansion.tex
new file mode 100644
index 000000000..1e2e00a35
--- /dev/null
+++ b/doc/context/sources/general/manuals/lowlevel/lowlevel-expansion.tex
@@ -0,0 +1,442 @@
+% language=us
+
+\environment lowlevel-style
+
+\startdocument
+ [title=expansion,
+ color=middleyellow]
+
+\startsection[title=Preamble]
+
+% \startsubsection[title=Introduction]
+% \stopsubsection
+
+This short manual demonstrates a couple of properties of the macro language. It
+is not the in|-|depth philosophical expose about macro languages, tokens,
+expansion and such that some \TEX ies like. I prefer to stick to the practical
+aspects.
+
+\stopsection
+
+\startsection[title={\TEX\ primitives}]
+
+The \TEX\ language provides quite some commands and those built in are called
+primitives. User defined commands are called macros. A macro is a shortcut to a
+list of primitives or macro calls. All can be mixed with characters that are to
+be typeset somehow.
+
+\starttyping[option=TEX]
+\def\MyMacro{b}
+
+a\MyMacro c
+\stoptyping
+
+When \TEX\ reads this input the \type {a} gets turned into a glyph node with a
+reference to the current font set and the character \type {a}. Then the parser
+sees a macro call, and it will enter another input level where it expands this
+macro. In this case it sees just an \type {b} and it will give this the same
+treatment as the \type {a}. The macro ends, the input level decrements and the
+\type {c} gets its treatment.
+
+A macro can contain references to macros so in practice the input can go several
+levels down.
+
+\starttyping[option=TEX]
+\def\MyMacroA{ and }
+\def\MyMacroB{1\MyMacroA 2}
+
+a\MyMacroA b
+\stoptyping
+
+When \type {\MyMacroB} is defined, its body gets three so called tokens: the
+character token \type {a} with property \quote {other}, a token that is a
+reference to the macro \type {\MyMacroB}, and a character token \type {2}, also
+with property \quote {other} The meaning of \type {\MyMacroA} became five tokens:
+a reference to a space token, then three character tokens with property \quote
+{letter}, and finally again a space token.
+
+\starttyping[option=TEX]
+\def \MyMacroA{ and }
+\edef\MyMacroB{1\MyMacroA 2}
+
+a\MyMacroA b
+\stoptyping
+
+In the previous example an \type {\edef} is used, where the \type {e} indicates
+expansion. This time the meaning gets expanded. So we get effectively the same
+as
+
+\starttyping[option=TEX]
+\def\MyMacroB{1 and 2}
+\stoptyping
+
+Characters are easy: they just expand, but not all primitives expand to their
+meaning or effect.
+
+\startbuffer
+\def\MyMacroA{\scratchcounter = 1 }
+\def\MyMacroB{\advance\scratchcounter by 1}
+\def\MyMacroC{\the\scratchcounter}
+
+\MyMacroA a
+\MyMacroB b
+\MyMacroB c
+\MyMacroB d
+\MyMacroC
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\scratchcounter0 \getbuffer
+
+\startlines \tt
+\meaning\MyMacroA
+\meaning\MyMacroB
+\meaning\MyMacroC
+\stoplines
+
+Let's assume that \type {\scratchcounter} is zero to start with and use \type
+{\edef's}:
+
+\startbuffer
+\edef\MyMacroA{\scratchcounter = 1 }
+\edef\MyMacroB{\advance\scratchcounter by 1}
+\edef\MyMacroC{\the\scratchcounter}
+
+\MyMacroA a
+\MyMacroB b
+\MyMacroB c
+\MyMacroB d
+\MyMacroC
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\scratchcounter0 \getbuffer
+
+\startlines \tt
+\meaning\MyMacroA
+\meaning\MyMacroB
+\meaning\MyMacroC
+\stoplines
+
+So, this time the third macro has basically its meaning frozen, but we can
+prevent this by applying a \type {\noexpand} when we do this:
+
+\startbuffer
+\edef\MyMacroA{\scratchcounter = 1 }
+\edef\MyMacroB{\advance\scratchcounter by 1}
+\edef\MyMacroC{\noexpand\the\scratchcounter}
+
+\MyMacroA a
+\MyMacroB b
+\MyMacroB c
+\MyMacroB d
+\MyMacroC
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\scratchcounter0 \getbuffer
+
+\startlines \tt
+\meaning\MyMacroA
+\meaning\MyMacroB
+\meaning\MyMacroC
+\stoplines
+
+Of course this is a rather useless example but it serves its purpose: you'd better
+be aware what gets expanded immediately in an \type {\edef}. In most cases you
+only need to worry about \type {\the} and embedded macros (and then of course
+their meanings).
+
+\def\MyShow{\quotation {\strut \inlinebuffer \expandafter \typ \expandafter
+{\the\scratchtoks}\strut}}
+
+You can also store tokens in a so called token register. Here we use a predefined
+scratch register:
+
+\startbuffer
+\def\MyMacroA{ and }
+\def\MyMacroB{1\MyMacroA 2}
+\scratchtoks {\MyMacroA}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The content of \type {\scratchtoks} is: \MyShow, so no expansion has happened
+here.
+
+\startbuffer
+\def\MyMacroA{ and }
+\def\MyMacroB{1\MyMacroA 2}
+\scratchtoks \expandafter {\MyMacroA}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+Now the content of \type {\scratchtoks} is: \MyShow, so this time expansion has
+happened.
+
+\startbuffer
+\def\MyMacroA{ and }
+\def\MyMacroB{1\MyMacroA 2}
+\scratchtoks \expandafter {\MyMacroB}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+Indeed the macro gets expanded but only one level: \MyShow. Compare this with:
+
+\startbuffer
+\def\MyMacroA{ and }
+\edef\MyMacroB{1\MyMacroA 2}
+\scratchtoks \expandafter {\MyMacroB}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The trick is to expand in two steps: \MyShow. Later we will see that other
+engines provide some more expansion tricks. The only way to get a grip on
+expansion is to just play with it.
+
+The \type {\expandafter} primitive expands the token (which can be a macro) after
+the next next one and injects its meaning into the stream. So:
+
+\starttyping[option=TEX]
+\expandafter \MyMacroA \MyMacroB
+\stoptyping
+
+works okay. In a normal document you will never need this kind of hackery: it
+only happens in a bit more complex macros. Here is an example:
+
+\startbuffer[a]
+\scratchcounter 1
+\bgroup
+\advance\scratchcounter 1
+\egroup
+\the\scratchcounter
+\stopbuffer
+
+\typebuffer[a][option=TEX]
+
+\startbuffer[b]
+\scratchcounter 1
+\bgroup
+\advance\scratchcounter 1
+\expandafter
+\egroup
+\the\scratchcounter
+\stopbuffer
+
+\typebuffer[b][option=TEX]
+
+The first one gives \inlinebuffer[a], while the second gives \inlinebuffer[b].
+
+% \let
+% \futurelet
+% \afterassignment
+% \aftergroup
+
+\stopsection
+
+\startsection[title={\ETEX\ primitives}]
+
+In this engine a couple of extensions were added and later on \PDFTEX\ added some
+more. We only discuss a few that relate to expansion. There is however a pitfall
+here. Before \ETEX\ showed up, \CONTEXT\ already had a few mechanism that also
+related to expansion and it used some names for macros that clash with those in
+\ETEX. This is why we will use the \type {\normal} prefix here to indicate the
+primitive.
+
+\startbuffer
+\def\MyMacroA{a}
+\def\MyMacroB{b}
+\normalprotected\def\MyMacroC{c}
+\edef\MyMacroABC{\MyMacroA\MyMacroB\MyMacroC}
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+These macros have the following meanings:
+
+\startlines \tt
+\meaning\MyMacroA
+\meaning\MyMacroB
+\meaning\MyMacroC
+\meaning\MyMacroABC
+\stoplines
+
+In \CONTEXT\ you will use the \type {\unexpanded} prefix instead because that one
+did something similar in older versions of \CONTEXT. As we were early adopters of
+\ETEX, this later became a synonym to the \ETEX\ primitive.
+
+\startbuffer
+\def\MyMacroA{a}
+\def\MyMacroB{b}
+\normalprotected\def\MyMacroC{c}
+\normalexpanded{\scratchtoks{\MyMacroA\MyMacroB\MyMacroC}}
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+Here the wrapper around the token register assignment will expand the three
+macros, unless they are protected, so its content becomes \MyShow. This saves
+either a lot of more complex \type {\expandafter} usage or using an intermediate
+\type {\edef}. In \CONTEXT\ the \type {\expanded} macro does something simpler
+but it doesn't expand the first token as it is meant as a wrapper around a command,
+like:
+
+\starttyping[option=TEX]
+\expanded{\chapter{....}} % a ConTeXt command
+\stoptyping
+
+where we do want to expand the title but not the \type {\chapter} command, not
+that this would happen actually because \type {\chapter} is a protected command.
+
+The counterpart of \type {\normalexpanded} is \type {\normalunexpanded}, as in:
+
+\startbuffer
+\def\MyMacroA{a}
+\def\MyMacroB{b}
+\normalprotected\def\MyMacroC{c}
+\normalexpanded {\scratchtoks
+ {\MyMacroA\normalunexpanded {\MyMacroB}\MyMacroC}}
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+The register now holds \MyShow: three tokens, one character token and two
+macro references.
+
+Tokens can represent characters, primitives, macros or be special entities like
+starting math mode, beginning a group, assigning a dimension to a register, etc.
+Although you can never really get back to the original input, you can come pretty
+close, with:
+
+\startbuffer
+\normaldetokenize{this can $ be anything \bgroup}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+This (when typeset monospaced) is: {\tt \inlinebuffer}. The detokenizer is like
+\type {\string} applied to each token in its argument. Compare this:
+
+\startbuffer
+\normalexpanded {
+ \normaldetokenize{10pt}
+}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+We get four tokens: {\tt\inlinebuffer}.
+
+\startbuffer
+\normalexpanded {
+ \string 1\string 0\string p\string t
+}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+So that was the same operation: {\tt\inlinebuffer}, but in both cases there is a
+subtle thing going on: characters have a catcode which distinguishes them. The
+parser needs to know what makes up a command name and normally that's only
+letters. The next snippet shows these catcodes:
+
+\startbuffer
+\normalexpanded {
+ \noexpand\the\catcode`\string 1 \noexpand\enspace
+ \noexpand\the\catcode`\string 0 \noexpand\enspace
+ \noexpand\the\catcode`\string p \noexpand\enspace
+ \noexpand\the\catcode`\string t \noexpand
+}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The result is \quotation {\tt\inlinebuffer}: two characters are marked as \quote
+{letter} and two fall in the \quote {other} category.
+
+\stopsection
+
+\startsection[title={\LUATEX\ primitives}]
+
+This engine adds a little in the expansion arena. First of all it offers a way to
+extend token lists registers
+
+\startbuffer
+\def\MyMacroA{a}
+\def\MyMacroB{b}
+\normalprotected\def\MyMacroC{b}
+\scratchtoks{\MyMacroA\MyMacroB}
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+The result is: \MyShow.
+
+\startbuffer
+\toksapp\scratchtoks{\MyMacroA\MyMacroB}
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+We're now at: \MyShow.
+
+\startbuffer
+\etoksapp\scratchtoks{\MyMacroA\space\MyMacroB\space\MyMacroC}
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+The register has this content: \MyShow, so the additional context got expanded in
+the process, except of course the protected macro \type {\MyMacroC}.
+
+There is a bunch of these combiners: \type {\toksapp} and \type {\tokspre} for
+local appending and prepending, with global companions: \type {\gtoksapp} and
+\type {\gtokspre}, as well as expanding variant: \type {\etoksapp}, \type
+{\etokspre}, \type {\xtoksapp} and \type {\xtokspre}.
+
+There are not beforehand more efficient that using intermediate expanded macros
+or token lists, simply because in the process \TEX\ has to create tokens lists
+too, but sometimes they're just more convenient to use.
+
+A second extension is \type {\immediateassignment} which instead in tokenizing
+the assignment directive applies it right now.
+
+\startbuffer
+\edef\MyMacroA
+ {\scratchcounter 123
+ \noexpand\the\scratchcounter}
+
+\edef\MyMacroB
+ {\immediateassignment\scratchcounter 123
+ \noexpand\the\scratchcounter}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\getbuffer
+
+These two macros now have the meaning:
+
+\startlines \tt
+\meaning\MyMacroA
+\meaning\MyMacroB
+\stoplines
+
+\stopsection
+
+\startsection[title={\LUAMETATEX\ primitives}]
+
+{\em todo}
+
+% \aftergroups
+
+\stopsection
+
+\stopdocument
+
diff --git a/doc/context/sources/general/manuals/lowlevel/lowlevel-registers.tex b/doc/context/sources/general/manuals/lowlevel/lowlevel-registers.tex
new file mode 100644
index 000000000..8ccb0cd3a
--- /dev/null
+++ b/doc/context/sources/general/manuals/lowlevel/lowlevel-registers.tex
@@ -0,0 +1,251 @@
+% language=us
+
+\environment lowlevel-style
+
+\startdocument
+ [title=registers,
+ color=darkmagenta]
+
+\startsection[title=Preamble]
+
+Registers are sets of variables that are accessed by index and a such resemble
+registers in a processing unit. You can store a quantity in a register, retrieve
+it, and also manipulate it.
+
+There is hardly any need to use them in \CONTEXT\ so we keep it simple.
+
+\stopsection
+
+\startsection[title={\TEX\ primitives}]
+
+There are several categories:
+
+\startitemize
+\startitem
+ Integers (int): in order to be portable (at the time it surfaced) there are only
+ integers and no floats. The only place where \TEX\ uses floats internally is
+ when glue gets effective which happens in the backend.
+\stopitem
+\startitem
+ Dimensions (dimen): internally these are just integers but when they are entered they
+ are sliced into two parts so that we have a fractional part. The internal
+ representation is called a scaled point.
+\stopitem
+\startitem
+ Glue (skip): these are dimensions with a few additional properties: stretch and
+ shrink. Being a compound entity they are stored differently and thereby a bit
+ less efficient than numbers and dimensions.
+\stopitem
+\startitem
+ Math glue (muskip): this is the same as glue but with a unit that adapts to
+ the current math style properties. It's best to think about them as being
+ relative measures.
+\stopitem
+\startitem
+ Token lists (toks): these contain a list of tokens coming from the input
+ or coming from a place where they already have been converted.
+\stopitem
+\stopitemize
+
+The original \TEX\ engine had 256 entries per set. The first ten of each set are
+normally reserved for scratch purposes: the even ones for local use, and the odd
+ones for global usage. On top of that macro packages can reserve some for its own
+use. It was quite easy to reach the maximum but there were tricks around that.
+This limitation is no longer present in the variants in use today.
+
+Let's set a few dimension registers:
+
+\startbuffer[1]
+\dimen 0 = 10 pt
+\dimen2=10pt
+\dimen4 10pt
+\scratchdimen 10pt
+\stopbuffer
+
+\typebuffer[1][option=TEX]
+
+We can serialize them with:
+
+\startbuffer[2]
+\the \dimen0
+\number \dimen2
+\meaning\dimen4
+\meaning\scratchdimen
+\stopbuffer
+
+\typebuffer[2][option=TEX]
+
+The results of these operations are:
+
+\startlines\tt
+\getbuffer[1,2]
+\stoplines
+
+The last two is not really useful but it is what you see when tracing options are
+set. Here \type {\scratchdimen} is a shortcut for a register. This is {\em not} a
+macro but a defined register. The low level \type {\dimendef} is used for this
+but in a macro package you should not use that one but the higher level \type
+{\newdimen} macro that uses it.
+
+\startbuffer[1]
+\newdimen\MyDimenA
+\def \MyDimenB{\dimen999}
+\dimendef\MyDimenC998
+\stopbuffer
+
+\typebuffer[1][option=TEX]
+
+\startbuffer[2]
+\meaning\MyDimenA
+\meaning\MyDimenB
+\meaning\MyDimenC
+\stopbuffer
+
+\typebuffer[2][option=TEX]
+
+Watch the difference:
+
+\startlines\tt
+\getbuffer[1,2]
+\stoplines
+
+The first definition uses a yet free register so you won't get a clash. The
+second one is just a shortcut using a macro and the third one too but again
+direct shortcut. Try to imagine how the second line gets interpreted:
+
+\starttyping[option=TEX]
+\MyDimenA10pt \MyDimenA10.5pt
+\MyDimenB10pt \MyDimenB10.5pt
+\MyDimenC10pt \MyDimenC10.5pt
+\stoptyping
+
+Also try to imagine what messing around with \type {\MyDimenC} will do when we
+also have defined a few hundred extra dimensions with \type {\newdimen}.
+
+In the case of dimensions the \type {\number} primitive will make the register
+serialize as scaled points without unit \type {sp}.
+
+Next we see some of the other registers being assigned:
+
+\starttyping[option=TEX]
+\count 0 = 100
+\skip 0 = 10pt plus 3pt minus 2pt
+\skip 0 = 10pt plus 1fill
+\muskip 0 = 10mu plus 3mu minus 2mu
+\muskip 0 = 10mu minus 1 fil
+\toks 0 = {hundred}
+\stoptyping
+
+When a number is expected, you can use for instance this:
+
+\starttyping[option=TEX]
+\scratchcounter\scratchcounterone
+\stoptyping
+
+Here we use a few predefined scratch registers. You can also do this:
+
+\starttyping[option=TEX]
+\scratchcounter\numexpr\scratchcounterone+\scratchcountertwo\relax
+\stoptyping
+
+There are some quantities that also qualify as number:
+
+\starttyping[option=TEX]
+\chardef\MyChar=123 % refers to character 123 (if present)
+\scratchcounter\MyChar
+\stoptyping
+
+In the past using \type {\chardef} was a way to get around the limited number of
+registers, but it still had (in traditional \TEX) a limitation: you could not go
+beyond 255. The \type {\mathchardef} could fo higher as it also encodes a family
+number and class. This limitation has been lifted in \LUATEX.
+
+A character itself can also be interpreted as number, in which case it has to be
+prefixed with a reverse quote: \type {`}, so:
+
+\startbuffer
+\scratchcounter\numexpr`0+5\relax
+\char\scratchcounter
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+produces \quotation {\inlinebuffer} because the \type {`0} expands into the
+(\ASCII\ and \UTF8) slot {\tt \number`0} which represents the character zero. In
+this case the next makes more sense:
+
+\starttyping[option=TEX]
+\char\numexpr`0+5\relax
+\stoptyping
+
+If you want to know more about all these quantities, \quotation {\TEX\ By Topic}
+provides a good summary of what \TEX\ has to offer, and there is no need to repeat
+it here.
+
+\stopsection
+
+\startsection[title={\ETEX\ primitives}]
+
+Apart from the ability to use expressions, the contribution to registers that
+\ETEX\ brought was that suddenly we could use upto 65K of them, which is more
+than enough. The extra registers were not as efficient as the first 256 because
+they were stored in the hash table, but that was not really a problem. In \OMEGA\
+and later \LUATEX\ regular arrays were used, at the cost of more memory which in
+the meantime has become cheap. As \CONTEXT\ moved to \ETEX\ rather early its
+users never had to worry about it.
+
+\stopsection
+
+\startsection[title={\LUATEX\ primitives}]
+
+The \LUATEX\ engine introduced attributes. These are numeric properties that are
+bound to the nodes that are the result of typesetting operations. They are
+basically like integer registers but when set their values get bound and when
+unset they are kind of invisible.
+
+\startitemize
+\startitem
+ Attribute (attribute): a numeric property that when set becomes part of the
+ current attribute list that gets assigned to nodes.
+\stopitem
+\stopitemize
+
+Attributes can be used to communicate properties to \LUA\ callbacks. There are
+several functions available for setting them and querying them.
+
+\starttyping[option=TEX]
+\attribute999 = 123
+\stoptyping
+
+Using attributes this way is dangerous (of course I can only speak for \CONTEXT)
+because an attribute value might trigger some action in a callback that gives
+unwanted side effects. For convenience \CONTEXT\ provides:
+
+\startbuffer
+\newattribute\MyAttribute
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+Which currently defines \type {\MyAttribute} as {\tt \meaning\MyAttribute} and is
+meant to be used as: \footnote {The low level \type {\attributedef} command is
+rather useless in the perspective of \CONTEXT.}
+
+\starttyping[option=TEX]
+\attribute\MyAttribute = 123
+\stoptyping
+
+Just be aware that defining attributes can have an impact on performance. As you
+cannot access them at the \TEX\ end you seldom need them. If you do you can
+better use the proper more high level definers (not discussed here).
+
+\stopsection
+
+\startsection[title={\LUAMETATEX\ primitives}]
+
+{\em todo}
+
+\stopsection
+
+\stopdocument
+
diff --git a/doc/context/sources/general/manuals/lowlevel/lowlevel-style.tex b/doc/context/sources/general/manuals/lowlevel/lowlevel-style.tex
new file mode 100644
index 000000000..ddd9df747
--- /dev/null
+++ b/doc/context/sources/general/manuals/lowlevel/lowlevel-style.tex
@@ -0,0 +1,104 @@
+% language=us
+
+% I started this series in June 2019 and I bet that it will never be complete or
+% extensive enough. But I'll do my best to make it as useful as possible ConTeXt
+% users out there who like to know about such details. Feel free to ask for more
+% explanations.
+
+\startenvironment lowlevel-style
+
+\usemodule[abbreviations-logos]
+\usemodule[scite]
+
+\setvariables
+ [document]
+ [title=No Title,
+ author=No Author,
+ color=NoColor]
+
+\setupbodyfont
+ [dejavu,11pt]
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ backspace=2cm,
+ topspace=15mm]
+
+\setupwhitespace
+ [big]
+
+\setuphead
+ [chapter]
+ [style=\bfc,
+ color=darkgray]
+
+\setuphead
+ [section]
+ [style=\bfb,
+ %page=right,
+ color=darkgray]
+
+\setuphead
+ [subsection]
+ [style=\bfa,
+ color=darkgray]
+
+\setupfootertexts
+ [section] % [\documentvariable{title}]
+
+\setupfooter
+ [style=bold,
+ color=darkgray]
+
+\startuseMPgraphic{titlepage}
+ fill Page
+ withcolor "\documentvariable{color}" ;
+
+ numeric d ; d := 2mm ;
+
+ picture p ; p := textext.llft("\tex{}")
+ xysized (.1PaperWidth-2d,.1PaperHeight-2d)
+ shifted (.1PaperWidth- d,.1PaperHeight -d)
+ ;
+
+ draw image (
+ for i = 0 step .1 PaperWidth until PaperWidth :
+ for j = 0 step .1 PaperHeight until PaperHeight :
+ draw p shifted (i,j) ;
+ endfor ;
+ endfor ;
+ ) withcolor .5resolvedcolor("middlegray") ;
+
+ draw textext.d("\strut low level")
+ xsized (.8PaperWidth)
+ shifted center topboundary Page
+ shifted -(0,.2PaperHeight)
+ withcolor "white" ;
+ draw textext.d("\strut \TeX")
+ xsized (.4PaperWidth)
+ shifted center topboundary Page
+ shifted -(0,.4PaperHeight)
+ withcolor "white" ;
+ draw textext.d("\strut\documentvariable{title}")
+ ysized 3cm
+ shifted center bottomboundary Page
+ shifted (0,.1PaperHeight)
+ withcolor "white" ;
+\stopuseMPgraphic
+
+\startsetups document:start
+
+ \startMPpage
+ \includeMPgraphic{titlepage} ;
+ \stopMPpage
+
+ \page
+
+ \startsubject[title=Contents]
+ \placelist[section][criterium=previous]
+ \stopsubject
+
+\stopsetups
+
+\stopenvironment
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-arrow.tex b/doc/context/sources/general/manuals/luametafun/luametafun-arrow.tex
new file mode 100644
index 000000000..72c9528e8
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-arrow.tex
@@ -0,0 +1,166 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-arrow
+
+\startchapter[title={Arrow}]
+
+Arrows are somewhat complicated because they follow the path, are constructed
+using a pen, have a fill and draw, and need to scale. One problem is that the
+size depends on the pen but the pen normally is only known afterwards.
+
+\startbuffer[1a]
+\startMPcode
+draw lmt_arrow [
+ path = (fullcircle scaled 3cm),
+]
+ withpen pencircle scaled 2mm
+ withcolor "darkred" ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[1b]
+\startMPcode
+draw lmt_arrow [
+ path = (fullcircle scaled 3cm),
+ length = 8,
+]
+ withpen pencircle scaled 2mm
+ withcolor "darkgreen" ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[1c]
+\startMPcode
+draw lmt_arrow [
+ path = (fullcircle scaled 3cm rotated 45),
+ pen = (pencircle xscaled 2mm yscaled 1mm rotated 45),
+]
+ withpen pencircle xscaled 2mm yscaled 1mm rotated 45
+ withcolor "darkblue" ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[1d]
+\startMPcode
+pickup pencircle xscaled 2mm yscaled 1mm rotated 45 ;
+draw lmt_arrow [
+ path = (fullcircle scaled 3cm rotated 45),
+ pen = "auto",
+]
+ withcolor "darkyellow" ;
+\stopMPcode
+\stopbuffer
+
+To some extent \METAFUN\ can help you with this issue. In \in {figure} [arrows:1]
+we see some variants. The definitions are given below:
+
+\typebuffer[1a][option=TEX]
+\typebuffer[1b][option=TEX]
+\typebuffer[1c][option=TEX]
+\typebuffer[1d][option=TEX]
+
+\startplacefigure[reference=arrows:1]
+ \startcombination[4*1]
+ {\getbuffer[1a]} {default}
+ {\getbuffer[1b]} {length}
+ {\getbuffer[1c]} {pen}
+ {\getbuffer[1d]} {auto}
+ \stopcombination
+\stopplacefigure
+
+There are some options that influence the shape of the arrowhead and its
+location on the path. You can for instance ask for two arrowheads:
+
+\startbuffer[3]
+\startMPcode
+ pickup pencircle scaled 1mm ;
+ draw lmt_arrow [
+ pen = "auto",
+ location = "both"
+ path = fullcircle scaled 3cm rotated 90,
+ ] withcolor "darkgreen" ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[3][option=TEX]
+
+\startlinecorrection
+\getbuffer[3]
+\stoplinecorrection
+
+The shape can also be influenced although often this is not that visible:
+
+\startbuffer[4]
+\startMPcode
+ pickup pencircle scaled 1mm ;
+ draw lmt_arrow [
+ kind = "draw",
+ pen = "auto",
+ penscale = 4,
+ location = "middle",
+ alternative = "curved",
+ path = fullcircle scaled 3cm,
+ ] withcolor "darkblue" ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[4][option=TEX]
+
+\startlinecorrection
+\getbuffer[4]
+\stoplinecorrection
+
+The location can also be given as percentage, as this example demonstrates. Watch
+how we draw only arrow heads:
+
+\startbuffer[5]
+\startMPcode
+ pickup pencircle scaled 1mm ;
+ for i = 0 step 5 until 100 :
+ draw lmt_arrow [
+ alternative = "dimpled",
+ pen = "auto",
+ location = "percentage",
+ percentage = i,
+ dimple = (1/5 + i/200),
+ headonly = (i = 0),
+ path = fullcircle scaled 3cm,
+ ] withcolor "darkyellow" ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[5][option=TEX]
+
+\startlinecorrection
+\getbuffer[5]
+\stoplinecorrection
+
+The supported parameters are:
+
+\starttabulate[|T|T|T|p|]
+\FL
+\BC name \BC type \BC default \BC comment \NC \NR
+\ML
+\NC path \NC path \NC \NC \NC \NR
+\NC pen \NC path \NC \NC \NC \NR
+\NC \NC string \NC auto \NC \NC \NR
+\NC kind \NC string \NC fill \NC \type {fill} or \type {draw} \NC \NR
+\NC dimple \NC numeric \NC 1/5 \NC \NC \NR
+\NC scale \NC numeric \NC 3/4 \NC \NC \NR
+\NC penscale \NC numeric \NC 3 \NC \NC \NR
+\NC length \NC numeric \NC 4 \NC \NC \NR
+\NC angle \NC numeric \NC 45 \NC \NC \NR
+\NC location \NC string \NC end \NC \type {end}, \type {middle} or \type {both} \NC \NR % middle both
+\NC alternative \NC string \NC normal \NC \type {normal}, \type {dimpled} or \type {curved} \NC \NR
+\NC percentage \NC numeric \NC 50 \NC \NC \NR
+\NC headonly \NC boolean \NC false \NC \NC \NR
+\LL
+\stoptabulate
+
+\stopchapter
+
+\stopcomponent
+
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-axis.tex b/doc/context/sources/general/manuals/luametafun/luametafun-axis.tex
new file mode 100644
index 000000000..f9483039c
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-axis.tex
@@ -0,0 +1,83 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-axis
+
+\startchapter[title={Axis}]
+
+The axis macro is the result of one of the first experiments with the key|/|value
+interface in \METAFUN. Let's show a lot in one example:
+
+\startbuffer[1]
+\startMPcode
+ draw lmt_axis [
+ sx = 5mm, sy = 5mm,
+ nx = 20, ny = 10,
+ dx = 5, dy = 2,
+ tx = 10, ty = 10,
+
+ list = {
+ [
+ connect = true,
+ color = "darkred",
+ close = true,
+ points = { (1, 1), (15, 8), (2, 10) },
+ texts = { "segment 1", "segment 2", "segment 3" }
+ ],
+ [
+ connect = true,
+ color = "darkgreen",
+ points = { (2, 2), (4, 1), (10, 3), (16, 8), (19, 2) },
+ labels = { "a", "b", "c", "d", "e" }
+ ],
+ [
+ connect = true,
+ color = "darkblue",
+ close = true,
+ points = { (5, 3), (8, 8), (16, 1) },
+ labels = { "1", "2", "3" }
+ ]
+ },
+
+ ] withpen pencircle scaled 1mm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[1][option=TEX]
+
+\startplacefigure[reference=axis:1]
+ \getbuffer[1]
+\stopplacefigure
+
+This macro will probably be extended at some point.
+
+\starttabulate[|T|T|T|p|]
+\FL
+\BC name \BC type \BC default \BC comment \NC \NR
+\ML
+\NC nx \NC numeric \NC 1 \NC \NC \NR
+\NC dx \NC numeric \NC 1 \NC \NC \NR
+\NC tx \NC numeric \NC 0 \NC \NC \NR
+\NC sx \NC numeric \NC 1 \NC \NC \NR
+\NC startx \NC numeric \NC 0 \NC \NC \NR
+\NC ny \NC numeric \NC 1 \NC \NC \NR
+\NC dy \NC numeric \NC 1 \NC \NC \NR
+\NC ty \NC numeric \NC 0 \NC \NC \NR
+\NC sy \NC numeric \NC 1 \NC \NC \NR
+\NC starty \NC numeric \NC 0 \NC \NC \NR
+\ML \NC \NC \NR
+\NC samples \NC list \NC \NC \NC \NR
+\NC list \NC list \NC \NC \NC \NR
+\NC connect \NC boolean \NC false \NC \NC \NR
+\NC list \NC list \NC \NC \NC \NR
+\NC close \NC boolean \NC false \NC \NC \NR
+\NC samplecolors \NC list \NC \NC \NC \NR
+\NC axiscolor \NC string \NC \NC \NC \NR
+\NC textcolor \NC string \NC \NC \NC \NR
+\LL
+\stoptabulate
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-chart.tex b/doc/context/sources/general/manuals/luametafun/luametafun-chart.tex
new file mode 100644
index 000000000..1bd89d350
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-chart.tex
@@ -0,0 +1,441 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-chart
+
+\startchapter[title={Chart}]
+
+This is another example implementation but it might be handy for simple cases of
+presenting results. Of course one can debate the usefulness of certain ways of
+presenting but here we avoid that discussion. Let's start with a simple pie
+chart (\in {figure} [chart:1]).
+
+\startbuffer[1]
+\startMPcode
+ draw lmt_chart_circle [
+ samples = { { 1, 4, 3, 2, 5, 7, 6 } },
+ percentage = true,
+ trace = true,
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[1][option=TEX]
+
+\startplacefigure[reference=chart:1]
+ \getbuffer[1]
+\stopplacefigure
+
+As with all these \LMTX\ extensions, you're invited to play with the parameters.
+in \in {figure} [chart:2] we see a variant that adds labels as well as one that
+has a legend.
+
+\startbuffer[2a]
+\startMPcode
+draw lmt_chart_circle [
+ height = 4cm,
+ samples = { { 1, 4, 3, 2, 5, 7, 6 } },
+ percentage = true,
+ trace = true,
+ labelcolor = "white",
+ labelformat = "@0.1f",
+ labelstyle = "ttxx"
+] ;
+\stopMPcode
+\stopbuffer
+
+The styling of labels and legends can be influenced independently.
+
+\typebuffer[2a][option=TEX]
+
+\startbuffer[2b]
+\startMPcode
+draw lmt_chart_circle [
+ height = 4cm,
+ samples = { { 1, 4, 3, 2, 5, 7, 6 } },
+ percentage = false,
+ trace = true,
+ linewidth = .125mm,
+ originsize = 0,
+ labeloffset = 3cm,
+ labelstyle = "bfxx",
+ legendstyle = "tfxx",
+ legend = {
+ "first", "second", "third", "fourth",
+ "fifth", "sixths", "sevenths"
+ }
+] ;
+
+\stopMPcode
+\stopbuffer
+
+\typebuffer[2b][option=TEX]
+
+\startplacefigure[reference=chart:2]
+ \startcombination
+ {\getbuffer[2a]} {}
+ {\getbuffer[2b]} {}
+ \stopcombination
+\stopplacefigure
+
+A second way of rendering are histograms, and the interface is mostly the same.
+In \in {figure} [chart:3] we see two variants
+
+\startbuffer[3a]
+\startMPcode
+ draw lmt_chart_histogram [
+ samples = { { 1, 4, 3, 2, 5, 7, 6 } },
+ percentage = true,
+ cumulative = true,
+ trace = true,
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[3b]
+\startMPcode
+ draw lmt_chart_histogram [
+ samples = {
+ { 1, 4, 3, 2, 5, 7, 6 },
+ { 1, 2, 3, 4, 5, 6, 7 }
+ },
+ background = "lightgray",
+ trace = true,
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[3a][option=TEX]
+
+and one with two datasets:
+
+\typebuffer[3b][option=TEX]
+
+\startplacefigure[reference=chart:3]
+ \startcombination
+ {\getbuffer[3a]} {}
+ {\getbuffer[3b]} {}
+ \stopcombination
+\stopplacefigure
+
+\startbuffer[4]
+\startMPpage[offset=5mm]
+ draw lmt_chart_histogram [
+ samples = {
+ { 1, 4, 3, 2, 5, 7, 6 },
+ { 1, 2, 3, 4, 5, 6, 7 }
+ },
+ percentage = true,
+ cumulative = true,
+ showlabels = false,
+ backgroundcolor = "lightgray",
+ ] ;
+\stopMPpage
+\stopbuffer
+
+A cumulative variant is shown in \in {figure} [chart:4] where we also add a
+background (color).
+
+\typebuffer[4][option=TEX]
+
+\startplacefigure[reference=chart:4]
+ \getbuffer[4]
+\stopplacefigure
+
+A different way of using colors is shown in \in {figure} [chart:5] where each
+sample gets its own (same) color.
+
+\startbuffer[5]
+\startMPcode
+ draw lmt_chart_histogram [
+ samples = {
+ { 1, 4, 3, 2, 5, 7, 6 },
+ { 1, 2, 3, 4, 5, 6, 7 }
+ },
+ percentage = true,
+ cumulative = true,
+ showlabels = false,
+ background = "lightgray",
+ colormode = "local",
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[5][option=TEX]
+
+\startplacefigure[reference=chart:5]
+ \getbuffer[5]
+\stopplacefigure
+
+As with pie charts you can add labels and a legend:
+
+\startbuffer[6a]
+\startMPcode
+ draw lmt_chart_histogram [
+ height = 6cm,
+ samples = { { 1, 4, 3, 2, 5, 7, 6 } },
+ percentage = true,
+ cumulative = true,
+ trace = true,
+ labelstyle = "ttxx",
+ labelanchor = "top",
+ labelcolor = "white",
+ backgroundcolor = "middlegray",
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[6a][option=TEX]
+
+The previous and next examples are shown in \in {figure} [chart:6]. The height
+specified here concerns the graphic and excludes the labels,
+
+\startbuffer[6b]
+\startMPcode
+ draw lmt_chart_histogram [
+ height = 6cm,
+ width = 10mm,
+ samples = { { 1, 4, 3, 2, 5, 7, 6 } },
+ trace = true,
+ maximum = 7.5,
+ linewidth = 1mm,
+ originsize = 0,
+ labelanchor = "bot",
+ labelcolor = "black"
+ labelstyle = "bfxx"
+ legendstyle = "tfxx",
+ labelstrut = "yes",
+ legend = {
+ "first", "second", "third", "fourth",
+ "fifth", "sixths", "sevenths"
+ }
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[6b][option=TEX]
+
+\startplacefigure[reference=chart:6]
+ \startcombination
+ {\getbuffer[6a]} {}
+ {\getbuffer[6b]} {}
+ \stopcombination
+\stopplacefigure
+
+The third category concerns bar charts that run horizontal. Again we see similar
+options driving the rendering (\in {figure} [chart:7]).
+
+\startbuffer[7a]
+\startMPcode
+ draw lmt_chart_bar [
+ samples = { { 1, 4, 3, 2, 5, 7, 6 } },
+ percentage = true,
+ cumulative = true,
+ trace = true,
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[7a][option=TEX]
+
+\startbuffer[7b]
+\startMPcode
+ draw lmt_chart_bar [
+ samples = { { 1, 4, 3, 2, 5, 7, 6 } },
+ percentage = true,
+ cumulative = true,
+ showlabels = false,
+ backgroundcolor = "lightgray",
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[7b][option=TEX]
+
+Determining the offset of labels is manual work:
+
+\startbuffer[7c]
+\startMPcode
+draw lmt_chart_bar [
+ width = 4cm,
+ height = 5mm,
+ samples = { { 1, 4, 3, 2, 5, 7, 6 } },
+ percentage = true,
+ cumulative = true,
+ trace = true,
+ labelcolor = "white",
+ labelstyle = "ttxx",
+ labelanchor = "rt",
+ labeloffset = .25EmWidth,
+ backgroundcolor = "middlegray",
+] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[7c][option=TEX]
+
+\startplacefigure[reference=chart:7]
+ \startcombination[3*1]
+ {\getbuffer[7a]} {}
+ {\getbuffer[7b]} {}
+ {\getbuffer[7c]} {}
+ \stopcombination
+\stopplacefigure
+
+Here is one with a legend (rendered in \in {figure} [chart:8]):
+
+\startbuffer[8]
+\startMPcode
+draw lmt_chart_bar [
+ width = 8cm,
+ height = 10mm,
+ samples = { { 1, 4, 3, 2, 5, 7, 6 } },
+ trace = true,
+ maximum = 7.5,
+ linewidth = 1mm,
+ originsize = 0,
+ labelanchor = "lft",
+ labelcolor = "black"
+ labelstyle = "bfxx"
+ legendstyle = "tfxx",
+ labelstrut = "yes",
+ legend = {
+ "first", "second", "third", "fourth",
+ "fifth", "sixths", "sevenths"
+ }
+] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[8][option=TEX]
+
+\startplacefigure[reference=chart:8]
+ \getbuffer[8]
+\stopplacefigure
+
+You can have labels per dataset as well as draw multiple datasets in
+one image, see \in {figure} [chart:9]:
+
+\startbuffer[9]
+\startMPcode
+ draw lmt_chart_bar [
+ samples = {
+ { 1, 4, 3, 2, 5, 7, 6 },
+ { 3, 2, 5, 7, 5, 6, 1 }
+ },
+ labels = {
+ { "a1", "b1", "c1", "d1", "e1", "f1", "g1" },
+ { "a2", "b2", "c2", "d2", "e2", "f2", "g2" }
+ },
+ labeloffset = -EmWidth,
+ labelanchor = "center",
+ labelstyle = "ttxx",
+ trace = true,
+ center = true,
+ ] ;
+
+ draw lmt_chart_bar [
+ samples = {
+ { 1, 4, 3, 2, 5, 7, 6 }
+ },
+ labels = {
+ { "a", "b", "c", "d", "e", "f", "g" }
+ },
+ labeloffset = -EmWidth,
+ labelanchor = "center",
+ trace = true,
+ center = true,
+ ] shifted (10cm,0) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[9][option=TEX]
+
+\startplacefigure[reference=chart:9]
+ \getbuffer[9]
+\stopplacefigure
+
+\starttabulate[|T|T|T|p|]
+\FL
+\BC name \BC type \BC default \BC comment \NC \NR
+\ML
+\NC originsize \NC numeric \NC 1mm \NC \NC \NR
+\NC trace \NC boolean \NC false \NC \NC \NR
+\NC showlabels \NC boolean \NC true \NC \NC \NR
+\NC center \NC boolean \NC false \NC \NC \NR
+\ML
+\NC samples \NC list \NC \NC \NC \NR
+\NC
+\NC cumulative \NC boolean \NC false \NC \NC \NR
+\NC percentage \NC boolean \NC false \NC \NC \NR
+\NC maximum \NC numeric \NC 0 \NC \NC \NR
+\NC distance \NC numeric \NC 1mm \NC \NC \NR
+\ML
+\NC labels \NC list \NC \NC \NC \NR
+\NC labelstyle \NC string \NC \NC \NC \NR
+\NC labelformat \NC string \NC \NC \NC \NR
+\NC labelstrut \NC string \NC auto \NC \NC \NR
+\NC labelanchor \NC string \NC \NC \NC \NR
+\NC labeloffset \NC numeric \NC 0 \NC \NC \NR
+\NC labelfraction \NC numeric \NC 0.8 \NC \NC \NR
+\NC labelcolor \NC string \NC \NC \NC \NR
+\ML
+\NC backgroundcolor \NC string \NC \NC \NC \NR
+\NC drawcolor \NC string \NC white \NC \NC \NR
+\NC fillcolors \NC list \NC \NC primary (dark) colors \NC \NR
+\NC colormode \NC string \NC global \NC \NC or \type {local} \NC \NR
+\ML
+\NC linewidth \NC numeric \NC .25mm \NC \NC \NR
+\ML
+\NC legendcolor \NC string \NC \NC \NC \NR
+\NC legendstyle \NC string \NC \NC \NC \NR
+\NC legend \NC list \NC \NC \NC \NR
+\LL
+\stoptabulate
+
+Pie charts have:
+
+\starttabulate[|T|T|]
+\FL
+\BC name \BC default \NC \NR
+\ML
+\NC height \NC 5cm \NC \NR
+\NC width \NC 5mm \NC \NR
+\NC labelanchor \NC \NC \NR
+\NC labeloffset \NC 0 \NC \NR
+\NC labelstrut \NC no \NC \NR
+\LL
+\stoptabulate
+
+Histograms come with:
+
+\starttabulate[|T|T|]
+\FL
+\BC name \BC default \NC \NR
+\ML
+\NC height \NC 5cm \NC \NR
+\NC width \NC 5mm \NC \NR
+\NC labelanchor \NC bot \NC \NR
+\NC labeloffset \NC 1mm \NC \NR
+\NC labelstrut \NC auto \NC \NR
+\LL
+\stoptabulate
+
+Bar charts use:
+
+\starttabulate[|T|T|]
+\FL
+\BC name \BC default \NC \NR
+\ML
+\NC height \NC 5cm \NC \NR
+\NC width \NC 5mm \NC \NR
+\NC labelanchor \NC lft \NC \NR
+\NC labeloffset \NC 1mm \NC \NR
+\NC labelstrut \NC no \NC \NR
+\LL
+\stoptabulate
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-contents.tex b/doc/context/sources/general/manuals/luametafun/luametafun-contents.tex
new file mode 100644
index 000000000..73800ba8b
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-contents.tex
@@ -0,0 +1,11 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-contents
+
+\starttitle[title={Contents}]
+ \placelist[chapter]
+\stoptitle
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-contour.tex b/doc/context/sources/general/manuals/luametafun/luametafun-contour.tex
new file mode 100644
index 000000000..11eca8b7a
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-contour.tex
@@ -0,0 +1,771 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-contour
+
+\startchapter[title={Contour}]
+
+This feature started out as experiment triggered by a request on the mailing
+list. In the end it was a nice exploration of what is possible with a bit of
+\LUA. In a sense it is more subsystem than a simple \METAPOST\ macro because
+quite some \LUA\ code is involved and more might be used in the future. It's part
+of the fun.
+
+A contour is a line through equivalent values $z$ that result from applying a
+function to two variables $x$ and $y$. There is quite a bit of analysis needed
+to get these lines. In \METAFUN\ we currently support three methods for generating
+a colorful background and three for putting lines on top:
+
+One solution is to use the the isolines and isobands methods are described on the
+marching squares page of wikipedia:
+
+\starttyping
+https://en.wikipedia.org/wiki/Marching_squares
+\stoptyping
+
+This method is relative efficient as we don't do much optimization, simply
+because it takes time and the gain is not that much relevant. Because we support
+filling of multiple curves in one go, we get efficient paths anyway without side
+effects that normally can occur from many small paths alongside. In these days of
+multi megabyte movies and sound clips a request of making a \PDF\ file small is kind
+of strange anyway. In practice the penalty is not that large.
+
+As background we can use a bitmap. This method is also quite efficient because we
+use indexed colors which results in a very good compression. We use a simple
+mapping on a range of values.
+
+A third method is derived from the one that is distributed as \CCODE\ source
+file at:
+
+\starttyping
+https://physiology.arizona.edu/people/secomb/contours
+https://github.com/secomb/GreensV4
+\stoptyping
+
+We can create a background image, which uses a sequence of closed curves
+\footnote {I have to figure out how to improve it a bit so that multiple path
+don't get connected.}. It can also provide two variants of lines around the
+contours (we tag them shape and shade). It's all a matter of taste. In the
+meantime I managed to optimize the code a bit and I suppose that when I buy a new
+computer (the code was developed on an 8 year old machine) performance is
+probably acceptable.
+
+In order of useability you can think of isoband (band) with isolines (cell),
+bitmap (bitmap) with isolines (cell) and finally shapes (shape) with edges
+(edge). But let's start with a couple of examples.
+
+\startbuffer[1]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = 0, xmax = 4*pi, xstep = .05,
+ ymin = -6, ymax = 6, ystep = .05,
+
+ levels = 7,
+ height = 5cm,
+ preamble = "local sin, cos = math.sin, math.cos",
+ function = "cos(x) + sin(y)",
+ background = "bitmap",
+ foreground = "edge",
+ linewidth = 1/2,
+ cache = true,
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\startplacefigure[reference=contour:1]
+ \getbuffer[1]
+\stopplacefigure
+
+\typebuffer[1][option=TEX]
+
+In \in {figure} [contour:1] we see the result. There is a in this case black and
+white image generated and on top of that we see lines. The step determines the
+resolution of the image. In practice using a bitmap is quite okay and also rather
+efficient: we use an indexed colorspace and, as already was mentioned, because
+the number of colors is limited such an image compresses well. A different
+rendering is seen in \in {figure} [contour:2] where we use the shape method for
+the background. That method creates outlines but is much slower, and when you use
+a high resolution (small step) it can take quite a while to identify the shapes.
+This is why we set the cache flag.
+
+\startbuffer[2]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = 0, xmax = 4*pi, xstep = .10,
+ ymin = -6, ymax = 6, ystep = .10,
+
+ levels = 7,
+ preamble = "local sin, cos = math.sin, math.cos",
+ function = "cos(x) - sin(y)",
+ background = "shape",
+ foreground = "shape",
+ linewidth = 1/2,
+ cache = true,
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[2][option=TEX]
+
+\startplacefigure[reference=contour:2]
+ \getbuffer[2]
+\stopplacefigure
+
+We mentioned colorspace but haven't seen any color yet, so let's set some in \in
+{figure} [contour:3]. Two variants are shown: a background \type {shape} with
+foreground \type {shape} and a background \type {bitmap} with a foreground \type
+{edge}. The bitmap renders quite fast, definitely when we compare with the shape,
+while the quality is as good at this size.
+
+\startbuffer[3a]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = -10, xmax = 10, xstep = .1,
+ ymin = -10, ymax = 10, ystep = .1,
+
+ levels = 10,
+ height = 7cm,
+ color = "shade({1/2,1/2,0},{0,0,1/2})",
+ function = "x^2 + y^2",
+ background = "shape",
+ foreground = "shape",
+ linewidth = 1/2,
+ cache = true,
+ ] xsized .45TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[3b]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = -10, xmax = 10, xstep = .1,
+ ymin = -10, ymax = 10, ystep = .1,
+
+ levels = 10,
+ height = 7cm,
+ color = "shade({1/2,0,0},{0,0,1/2})",
+ function = "x^2 + y^2",
+ background = "bitmap",
+ foreground = "edge",
+ linewidth = 1/2,
+ cache = true,
+ ] xsized .45TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[3a][option=TEX]
+
+\startplacefigure[reference=contour:3]
+ \startcombination
+ {\getbuffer[3a]} {\bf shape}
+ {\getbuffer[3b]} {\bf bitmap}
+ \stopcombination
+\stopplacefigure
+
+We use the \type {doublefun} instance because we need to be sure that we don't
+run into issues with scaled numbers, the default model in \METAPOST. The
+function that gets passed is {\em not} using \METAPOST\ but \LUA, so basically
+you can do very complex things. Here we directly pass code, but you can for
+instance also do this:
+
+\starttyping[option=TEX]
+\startluacode
+ function document.MyContourA(x,y)
+ return x^2 + y^2
+ end
+\stopluacode
+\stoptyping
+
+and then \type {function = "document.MyContourA(x,y)"}. As long as the function
+returns a valid number we're okay. When you pass code directly you can use the
+\type {preamble} key to set local shortcuts. In the previous examples we took
+\type {sin} and \type {cos} from the math library but you can also roll out your
+own functions and|/|or use the more elaborate \type {xmath} library. The color
+parameter is also a function, one that returns one or three arguments. In the
+next example we use \type {lin} to calculate a fraction of the current level and
+total number of levels.
+
+\startbuffer[4a]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = -3, xmax = 3, xstep = .01,
+ ymin = -1, ymax = 1, ystep = .01,
+
+ levels = 10,
+ default = .5,
+ height = 5cm,
+ function = "x^2 + y^2 + x + y/2",
+ color = "lin(l), 0, 1/2",
+ background = "bitmap"
+ foreground = "none",
+ cache = true,
+ ] xsized TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[4a][option=TEX]
+
+\startplacefigure[reference=contour:4a]
+ \getbuffer[4a]
+\stopplacefigure
+
+Instead of a bitmap we can use an isoband, which boils down to a set of tiny
+shapes that make up a bigger one. This is shown in \in {figure} [contour:4b].
+
+\startbuffer[4b]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = -3, xmax = 3, xstep = .01,
+ ymin = -1, ymax = 1, ystep = .01,
+
+ levels = 10,
+ default = .5,
+ height = 5cm,
+ function = "x^2 + y^2 + x + y/2",
+ color = "lin(l), 1/2, 0",
+ background = "band",
+ foreground = "none",
+ cache = true,
+ ] xsized TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[4b][option=TEX]
+
+\startplacefigure[reference=contour:4b]
+ \getbuffer[4b]
+\stopplacefigure
+
+You can draw several functions and see where they overlap:
+
+\startbuffer[5]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = -pi, xmax = 4*pi, xstep = .1,
+ ymin = -3, ymax = 3, ystep = .1,
+
+ range = { -.1, .1 },
+ preamble = "local sin, cos = math.sin, math.cos",
+ functions = {
+ "sin(x) + sin(y)", "sin(x) + cos(y)",
+ "cos(x) + sin(y)", "cos(x) + cos(y)"
+ },
+ background = "bitmap",
+ linecolor = "black",
+ linewidth = 1/10,
+ color = "shade({1,1,0},{0,0,1})"
+ cache = true,
+ ] xsized TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[5][option=TEX]
+
+\startplacefigure[reference=contour:5]
+ \getbuffer[5]
+\stopplacefigure
+
+The range determines the $z$ value(s) that we take into account. You can also
+pass a list of colors to be used. In \in {figure} [contour:6] this is
+demonstrated. There we also show a variant foreground \type {cell}, which uses a
+bit different method for calculating the edges. \footnote {This a bit of a
+playground: more variants might show up in due time.}
+
+\startbuffer[6]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = -2*pi, xmax = 2*pi, xstep = .01,
+ ymin = -3, ymax = 3, ystep = .01,
+
+ range = { -.1, .1 },
+ preamble = "local sin, cos = math.sin, math.cos",
+ functions = { "sin(x) + sin(y)", "sin(x) + cos(y)" },
+ background = "bitmap",
+ foreground = "cell",
+ linecolor = "white",
+ linewidth = 1/10,
+ colors = { (1/2,1/2,1/2), red, green, blue }
+ level = 3,
+ linewidth = 6,
+ cache = true,
+ ] xsized TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[6][option=TEX]
+
+Here the number of levels depends on the number of functions as each can overlap
+with another; for instance the outcome of two functions can overlap or not which
+means 3 cases, and with a value not being seen that gives 4 different cases.
+
+\startplacefigure[reference=contour:6]
+ \getbuffer[6]
+\stopplacefigure
+
+\startbuffer[7]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = -2*pi, xmax = 2*pi, xstep = .01,
+ ymin = -3, ymax = 3, ystep = .01,
+
+ range = { -.1, .1 },
+ preamble = "local sin, cos = math.sin, math.cos",
+ functions = {
+ "sin(x) + sin(y)",
+ "sin(x) + cos(y)",
+ "cos(x) + sin(y)",
+ "cos(x) + cos(y)"
+ },
+ background = "bitmap",
+ foreground = "none",
+ level = 3,
+ color = "shade({2/3,0,0},{2/3,1,2/3})"
+ cache = true,
+ ] xsized TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[7][option=TEX]
+
+Of course one can wonder how useful showing many functions but it can give nice
+pictures, as shown in \in {figure} [contour:7].
+
+\startplacefigure[reference=contour:7]
+ \getbuffer[7]
+\stopplacefigure
+
+\startbuffer[8]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = -2*pi, xmax = 2*pi, xstep = .01,
+ ymin = -3, ymax = 3, ystep = .01,
+
+ range = { -.3, .3 },
+ preamble = "local sin, cos = math.sin, math.cos",
+ functions = {
+ "sin(x) + sin(y)",
+ "sin(x) + cos(y)",
+ "cos(x) + sin(y)",
+ "cos(x) + cos(y)"
+ },
+ background = "bitmap",
+ foreground = "none",
+ level = 3,
+ color = "shade({1,0,0},{0,1,0})"
+ cache = true,
+ ] xsized TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[8][option=TEX]
+
+We can enlargen the window, which is demonstrated in \in {figure} [contour:8]. I
+suppose that such images only make sense in educational settings.
+
+\startplacefigure[reference=contour:8]
+ \getbuffer[8]
+\stopplacefigure
+
+% \startbuffer[9a]
+% \startMPcode{doublefun}
+% draw lmt_contour [
+% xmin = -10, xmax = 10, xstep = 1,
+% ymin = -10, ymax = 10, ystep = 1,
+% function = "math.random(1,3)", levels = 3,
+% linecolor = "white", linewidth = 1/10,
+% width = .3TextWidth, legend = "none",
+% color = "shade({1/2,1/2,0},{0,0,1})"
+%
+% background = "bitmap", foreground = "edge",
+% ] ;
+% \stopMPcode
+% \stopbuffer
+%
+% \typebuffer[9a][option=TEX]
+%
+% \startbuffer[9b]
+% \startMPcode{doublefun}
+% draw lmt_contour [
+% xmin = -10, xmax = 10, xstep = 1,
+% ymin = -10, ymax = 10, ystep = 1,
+% function = "math.random(1,3)", levels = 3,
+% linecolor = "white", linewidth = 1/10,
+% width = .3TextWidth, legend = "none",
+% color = "shade({1/2,1/2,0},{0,0,1/2})"
+%
+% background = "bitmap", foreground = "cell",
+% ] ;
+% \stopMPcode
+% \stopbuffer
+%
+% \startbuffer[9c]
+% \startMPcode{doublefun}
+% draw lmt_contour [
+% xmin = -10, xmax = 10, xstep = 1,
+% ymin = -10, ymax = 10, ystep = 1,
+% function = "math.random(1,3)", levels = 3,
+% linecolor = "white", linewidth = 1/10,
+% width = .3TextWidth, legend = "none",
+% color = "shade({1/2,1/2,0},{0,0,1})"
+%
+% background = "bitmap", foreground = "none",
+% ] ;
+% \stopMPcode
+% \stopbuffer
+%
+% \startbuffer[9d]
+% \startMPcode{doublefun}
+% draw lmt_contour [
+% xmin = -10, xmax = 10, xstep = 1,
+% ymin = -10, ymax = 10, ystep = 1,
+% function = "math.random(1,3)", levels = 3,
+% linecolor = "white", linewidth = 1/10,
+% width = .3TextWidth, legend = "none",
+% color = "shade({1/2,1/2,0},{0,0,1})"
+%
+% background = "shape", foreground = "shape",
+% ] ;
+% \stopMPcode
+% \stopbuffer
+%
+% \startbuffer[9e]
+% \startMPcode{doublefun}
+% draw lmt_contour [
+% xmin = -10, xmax = 10, xstep = 1,
+% ymin = -10, ymax = 10, ystep = 1,
+% function = "math.random(1,3)", levels = 3,
+% linecolor = "white", linewidth = 1/10,
+% width = .3TextWidth, legend = "none",
+% color = "shade({1/2,1/2,0},{0,0,1})"
+%
+% background = "shape", foreground = "edge",
+% ] ;
+% \stopMPcode
+% \stopbuffer
+%
+% \startbuffer[9f]
+% \startMPcode{doublefun}
+% draw lmt_contour [
+% xmin = -10, xmax = 10, xstep = 1,
+% ymin = -10, ymax = 10, ystep = 1,
+% function = "math.random(1,3)", levels = 3,
+% linecolor = "white", linewidth = 1/10,
+% width = .3TextWidth, legend = "none",
+% color = "shade({1/2,1/2,0},{0,0,1})"
+%
+% background = "shape", foreground = "none",
+% ] ;
+% \stopMPcode
+% \stopbuffer
+%
+% \startbuffer[9g]
+% \startMPcode{doublefun}
+% draw lmt_contour [
+% xmin = -10, xmax = 10, xstep = 1,
+% ymin = -10, ymax = 10, ystep = 1,
+% function = "math.random(1,3)", levels = 3,
+% linecolor = "white", linewidth = 1/10,
+% width = .3TextWidth, legend = "none",
+% color = "shade({1/2,1/2,0},{0,0,1})"
+%
+% background = "band", foreground = "edge",
+% ] ;
+% \stopMPcode
+% \stopbuffer
+%
+% \startbuffer[9h]
+% \startMPcode{doublefun}
+% draw lmt_contour [
+% xmin = -10, xmax = 10, xstep = 1,
+% ymin = -10, ymax = 10, ystep = 1,
+% function = "math.random(1,3)", levels = 3,
+% linecolor = "white", linewidth = 1/10,
+% width = .3TextWidth, legend = "none",
+% color = "shade({1/2,1/2,0},{0,0,1})"
+%
+% background = "band", foreground = "cell",
+% ] ;
+% \stopMPcode
+% \stopbuffer
+%
+% \startbuffer[9i]
+% \startMPcode{doublefun}
+% draw lmt_contour [
+% xmin = -10, xmax = 10, xstep = 1,
+% ymin = -10, ymax = 10, ystep = 1,
+% function = "math.random(1,3)", levels = 3,
+% linecolor = "white", linewidth = 1/10,
+% width = .3TextWidth, legend = "none",
+% color = "shade({1/2,1/2,0},{0,0,1})"
+%
+% background = "band", foreground = "none",
+% ] ;
+% \stopMPcode
+% \stopbuffer
+%
+% In \in {figure} [contour:9] we see that using the shape option doesn't work out
+% too well here, which again demonstrates that using the bitmap method is not that
+% bad. In that example we use random numbers, just to show the erratic behavior. In
+% \in {figure} [contour:10] a more sane image is used. The band and bitmap examples
+% are generated quite fast so no caching is used there. We only show one definition:
+%
+% \typebuffer[9i][option=TEX]
+%
+% \startplacefigure[reference=contour:9]
+% \startcombination[3*3]
+% {\pushrandomseed\setrandomseed{1}\getbuffer[9a]\poprandomseed} {\bf bitmap edge}
+% {\pushrandomseed\setrandomseed{1}\getbuffer[9b]\poprandomseed} {\bf bitmap cell}
+% {\pushrandomseed\setrandomseed{1}\getbuffer[9c]\poprandomseed} {\bf bitmap none}
+% {\pushrandomseed\setrandomseed{1}\getbuffer[9d]\poprandomseed} {\bf shape shape}
+% {\pushrandomseed\setrandomseed{1}\getbuffer[9e]\poprandomseed} {\bf shape edge}
+% {\pushrandomseed\setrandomseed{1}\getbuffer[9f]\poprandomseed} {\bf shape none}
+% {\pushrandomseed\setrandomseed{1}\getbuffer[9g]\poprandomseed} {\bf band edge}
+% {\pushrandomseed\setrandomseed{1}\getbuffer[9h]\poprandomseed} {\bf band cell}
+% {\pushrandomseed\setrandomseed{1}\getbuffer[9i]\poprandomseed} {\bf band none}
+% \stopcombination
+% \stopplacefigure
+
+In \in {figure} [contour:10] we see different combinations of backgrounds (in color)
+and foregrounds (edges) in action.
+
+\startbuffer[10a]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = 0, xmax = 4*pi, xstep = 0,
+ ymin = -6, ymax = 6, ystep = 0,
+
+ levels = 5, legend = false, linewidth = 1/2,
+
+ preamble = "local sin, cos = math.sin, math.cos",
+ function = "cos(x) - sin(y)",
+ color = "shade({1/2,0,0},{0,0,1/2})",
+
+ background = "bitmap", foreground = "edge",
+ ] xsized .3TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[10b]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = 0, xmax = 4*pi, xstep = 0,
+ ymin = -6, ymax = 6, ystep = 0,
+
+ levels = 5, legend = false, linewidth = 1/2,
+
+ preamble = "local sin, cos = math.sin, math.cos",
+ function = "cos(x) - sin(y)",
+ color = "shade({1/2,0,0},{0,0,1/2})",
+
+ background = "bitmap", foreground = "cell",
+ ] xsized .3TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[10c]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = 0, xmax = 4*pi, xstep = 0,
+ ymin = -6, ymax = 6, ystep = 0,
+
+ levels = 5, legend = false, linewidth = 1/2,
+
+ preamble = "local sin, cos = math.sin, math.cos",
+ function = "cos(x) - sin(y)",
+ color = "shade({1/2,0,0},{0,0,1/2})",
+
+ background = "bitmap", foreground = "none",
+ ] xsized .3TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[10d]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = 0, xmax = 4*pi, xstep = 0,
+ ymin = -6, ymax = 6, ystep = 0,
+
+ levels = 5, legend = false, linewidth = 1/2,
+
+ preamble = "local sin, cos = math.sin, math.cos",
+ function = "cos(x) - sin(y)",
+ color = "shade({1/2,0,0},{0,0,1/2})",
+
+ background = "shape", foreground = "shape", cache = true,
+ ] xsized .3TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[10e]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = 0, xmax = 4*pi, xstep = 0,
+ ymin = -6, ymax = 6, ystep = 0,
+
+ levels = 5, legend = false, linewidth = 1/2,
+
+ preamble = "local sin, cos = math.sin, math.cos",
+ function = "cos(x) - sin(y)",
+ color = "shade({1/2,0,0},{0,0,1/2})",
+
+ background = "shape", foreground = "edge", cache = true,
+ ] xsized .3TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[10f]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = 0, xmax = 4*pi, xstep = 0,
+ ymin = -6, ymax = 6, ystep = 0,
+
+ levels = 5, legend = false, linewidth = 1/2,
+
+ preamble = "local sin, cos = math.sin, math.cos",
+ function = "cos(x) - sin(y)",
+ color = "shade({1/2,0,0},{0,0,1/2})",
+
+ background = "shape", foreground = "none", cache = true,
+ ] xsized .3TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[10g]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = 0, xmax = 4*pi, xstep = 0,
+ ymin = -6, ymax = 6, ystep = 0,
+
+ levels = 5, legend = false, linewidth = 1/2,
+
+ preamble = "local sin, cos = math.sin, math.cos",
+ function = "cos(x) - sin(y)",
+ color = "shade({1/2,0,0},{0,0,1/2})",
+
+ background = "band", foreground = "edge",
+ ] xsized .3TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[10h]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = 0, xmax = 4*pi, xstep = 0,
+ ymin = -6, ymax = 6, ystep = 0,
+
+ levels = 5, legend = false, linewidth = 1/2,
+
+ preamble = "local sin, cos = math.sin, math.cos",
+ function = "cos(x) - sin(y)",
+ color = "shade({1/2,0,0},{0,0,1/2})",
+
+ background = "band", foreground = "cell",
+ ] xsized .3TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[10i]
+\startMPcode{doublefun}
+ draw lmt_contour [
+ xmin = 0, xmax = 4*pi, xstep = 0,
+ ymin = -6, ymax = 6, ystep = 0,
+
+ levels = 5, legend = false, linewidth = 1/2,
+
+ preamble = "local sin, cos = math.sin, math.cos",
+ function = "cos(x) - sin(y)",
+ color = "shade({1/2,0,0},{0,0,1/2})",
+
+ background = "band", foreground = "none",
+ ] xsized .3TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[10b][option=TEX]
+
+% \page
+
+There are quite some settings. Some deal with the background, some with the
+foreground and quite some deal with the legend.
+
+\starttabulate[|T|T|T|p|]
+\FL
+\BC name \BC type \BC default \BC comment \NC \NR
+\ML
+\NC xmin \NC numeric \NC 0 \NC needs to be set \NC \NR
+\NC xmax \NC numeric \NC 0 \NC needs to be set \NC \NR
+\NC ymin \NC numeric \NC 0 \NC needs to be set \NC \NR
+\NC ymax \NC numeric \NC 0 \NC needs to be set \NC \NR
+\NC xstep \NC numeric \NC 0 \NC auto 1/200 when zero \NC \NR
+\NC ystep \NC numeric \NC 0 \NC auto 1/200 when zero \NC \NR
+\NC checkresult \NC boolean \NC false \NC checks for overflow and NaN \NC \NR
+\NC defaultnan \NC numeric \NC 0 \NC the value to be used when NaN \NC \NR
+\NC defaultinf \NC numeric \NC 0 \NC the value to be used when overflow \NC \NR
+\ML
+\NC levels \NC numeric \NC 10 \NC number of different levels to show \NC \NR
+\NC level \NC numeric \NC \NC only show this level (foreground) \NC \NR
+\ML
+\NC preamble \NC string \NC \NC shortcuts \NC \NR
+\NC function \NC string \NC x + y \NC the result z value \NC \NR
+\NC functions \NC list \NC \NC multiple functions (overlapping levels) \NC \NR
+\NC color \NC string \NC lin(l) \NC the result color value for level l (1 or 3 values) \NC \NR
+\NC colors \NC numeric \NC \NC used when set \NC \NR
+\ML
+\NC background \NC string \NC bitmap \NC band, bitmap, shape \NC \NR
+\NC foreground \NC string \NC auto \NC cell, edge, shape auto \NC \NR
+\ML
+\NC linewidth \NC numeric \NC .25 \NC \NC \NR
+%NC backgroundcolor \NC string \NC black \NC \NC \NR
+\NC linecolor \NC string \NC gray \NC \NC \NR
+\ML
+\NC width \NC numeric \NC 0 \NC automatic when zero \NC \NR
+\NC height \NC numeric \NC 0 \NC automatic when zero \NC \NR
+\ML
+\NC trace \NC boolean \NC false \NC \NC \NR
+\ML
+\NC legend \NC string \NC all \NC x y z function range all \NC \NR
+\NC legendheight \NC numeric \NC LineHeight \NC \NC \NR
+\NC legendwidth \NC numeric \NC LineHeight \NC \NC \NR
+\NC legendgap \NC numeric \NC 0 \NC \NC \NR
+\NC legenddistance \NC numeric \NC EmWidth \NC \NC \NR
+\NC textdistance \NC numeric \NC 2EmWidth/3 \NC \NC \NR
+\NC functiondistance \NC numeric \NC ExHeight \NC \NC \NR
+\NC functionstyle \NC string \NC \NC \CONTEXT\ style name \NC \NR
+\NC xformat \NC string \NC @0.2N \NC number format template \NC \NR
+\NC yformat \NC string \NC @0.2N \NC number format template \NC \NR
+\NC zformat \NC string \NC @0.2N \NC number format template \NC \NR
+\NC xstyle \NC string \NC \NC \CONTEXT\ style name \NC \NR
+\NC ystyle \NC string \NC \NC \CONTEXT\ style name \NC \NR
+\NC zstyle \NC string \NC \NC \CONTEXT\ style name \NC \NR
+\ML
+\NC axisdistance \NC numeric \NC ExHeight \NC \NC \NR
+\NC axislinewidth \NC numeric \NC .25 \NC \NC \NR
+\NC axisoffset \NC numeric \NC ExHeight/4 \NC \NC \NR
+\NC axiscolor \NC string \NC black \NC \NC \NR
+\NC ticklength \NC numeric \NC ExHeight \NC \NC \NR
+\ML
+\NC xtick \NC numeric \NC 5 \NC \NC \NR
+\NC ytick \NC numeric \NC 5 \NC \NC \NR
+\NC xlabel \NC numeric \NC 5 \NC \NC \NR
+\NC ylabel \NC numeric \NC 5 \NC \NC \NR
+\LL
+\stoptabulate
+
+\startplacefigure[reference=contour:10]
+ \startcombination[3*3]
+ {\getbuffer[10a]} {\bf bitmap edge}
+ {\getbuffer[10b]} {\bf bitmap cell}
+ {\getbuffer[10c]} {\bf bitmap none}
+ {\getbuffer[10d]} {\bf shape shape}
+ {\getbuffer[10e]} {\bf shape edge}
+ {\getbuffer[10f]} {\bf shape none}
+ {\getbuffer[10g]} {\bf band edge}
+ {\getbuffer[10h]} {\bf band cell}
+ {\getbuffer[10i]} {\bf band none}
+ \stopcombination
+\stopplacefigure
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-followtext.tex b/doc/context/sources/general/manuals/luametafun/luametafun-followtext.tex
new file mode 100644
index 000000000..079131565
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-followtext.tex
@@ -0,0 +1,124 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-followtext
+
+\startchapter[title={Followtext}]
+
+Typesetting text along a path started as a demo if communication between \TEX\ and
+\METAPOST\ in the early days of \METAFUN. In the meantime the implementation has
+been modernized a few times and the current implementation feels okay, especially
+now that we have a better user interface. Here is an example:
+
+\startbuffer[1a]
+\startMPcode{doublefun}
+ draw lmt_followtext [
+ text = "How well does it work {\bf 1}! ",
+ path = fullcircle scaled 4cm,
+ trace = true,
+ spread = true,
+ ] ysized 5cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[1a][option=TEX]
+
+Here is the same example but with the text in the reverse order. The results of both examples
+are shown in \in {figure} [followtext:1].
+
+\startbuffer[1b]
+\startMPcode{doublefun}
+ draw lmt_followtext [
+ text = "How well does it work {\bf 2}! ",
+ path = fullcircle scaled 4cm,
+ trace = true,
+ spread = false,
+ reverse = true,
+ ] ysized 5cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[1b][option=TEX]
+
+\startplacefigure[reference=followtext:1]
+ \startcombination[2*2]
+ {\getbuffer[1a]} {}
+ {\getbuffer[1b]} {}
+ \stopcombination
+\stopplacefigure
+
+There are not that many options. One is \type {autoscale} which makes the shape
+and text match. \in {Figure} [followtext:2] shows what happens.
+
+\startbuffer[2a]
+\startMPcode{doublefun}
+ draw lmt_followtext [
+ text = "How well does it work {\bf 3}! ",
+ trace = true,
+ autoscaleup = "yes"
+ ] ysized 5cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[2a][option=TEX]
+
+\startbuffer[2b]
+\startMPcode{doublefun}
+ draw lmt_followtext [
+ text = "How well does it work {\bf 4}! ",
+ path = fullcircle scaled 2cm,
+ trace = true,
+ autoscaleup = "max"
+ ] ysized 5cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[2b][option=TEX]
+
+\startplacefigure[reference=followtext:2]
+ \startcombination[2*2]
+ {\getbuffer[2a]} {}
+ {\getbuffer[2b]} {}
+ \stopcombination
+\stopplacefigure
+
+You can use quite strange paths, like the one show in \in {figure}
+[followtext:3]. Watch the parenthesis around the path. this is really needed in
+order for the scanner to pick up the path (otherwise it sees a pair).
+
+\startbuffer[3]
+\startMPcode{doublefun}
+ draw lmt_followtext [
+ text = "\samplefile {zapf}",
+ path = ((3,0) .. (1,0) .. (5,0) .. (2,0) .. (4,0) .. (3,0)),
+ autoscaleup = "max"
+ ] xsized TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[3][option=TEX]
+
+\startplacefigure[reference=followtext:3]
+ \getbuffer[3]
+\stopplacefigure
+
+The small set of options is:
+
+\starttabulate[|T|T|T|p|]
+\FL
+\BC name \BC type \BC default \BC comment \NC \NR
+\ML
+\NC text \NC string \NC \NC \NC \NR
+\NC spread \NC string \NC true \NC \NC \NR
+\NC trace \NC numeric \NC false \NC \NC \NR
+\NC reverse \NC numeric \NC false \NC \NC \NR
+\NC autoscaleup \NC numeric \NC no \NC \NC \NR
+\NC autoscaledown \NC string \NC no \NC \NC \NR
+\NC path \NC string \NC (fullcircle) \NC \NC \NR
+\LL
+\stoptabulate
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-function.tex b/doc/context/sources/general/manuals/luametafun/luametafun-function.tex
new file mode 100644
index 000000000..79fa97a21
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-function.tex
@@ -0,0 +1,296 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-function
+
+\startchapter[title={Function}]
+
+It is tempting to make helpers that can do a lot. However, that also means that
+we need to explain a lot. Instead it makes more sense to have specific helpers
+and just make another one when needed. Rendering functions falls into this
+category. At some point users will come up with specific cases that other users
+can use. Therefore, the solution presented here is not the ultimate answer. We
+start with a simple example:
+
+\startbuffer[1]
+\startMPcode{doublefun}
+ draw lmt_function [
+ xmin = 0, xmax = 20, xstep = .1,
+ ymin = -2, ymax = 2,
+
+ sx = 1mm, xsmall = 80, xlarge = 20,
+ sy = 4mm, ysmall = 40, ylarge = 4,
+
+ linewidth = .025mm, offset = .1mm,
+
+ code = "1.5 * math.sind (50 * x - 150)",
+ ]
+ xsized 8cm
+ ;
+\stopMPcode
+\stopbuffer
+
+\startplacefigure
+ \getbuffer[1]
+\stopplacefigure
+
+This image is defined as follows:
+
+\typebuffer[1][option=TEX]
+
+\startbuffer[2]
+\startMPcode{doublefun}
+ draw lmt_function [
+ xmin = 0, xmax = 20, xstep = .1,
+ ymin = -2, ymax = 2,
+
+ sx = 1mm, xsmall = 80, xlarge = 20,
+ sy = 4mm, ysmall = 40, ylarge = 4,
+
+ linewidth = .025mm, offset = .1mm,
+
+ xticks = "bottom",
+ yticks = "left",
+ xlabels = "nolimits",
+ ylabels = "yes",
+ code = "1.5 * math.sind (50 * x - 150)",
+ % frame = "ticks",
+ frame = "sticks",
+ ycaption = "\strut \rotate[rotation=90]{something vertical, using $\sin{x}$}",
+ xcaption = "\strut something horizontal",
+ functions = {
+ [ xmin = 1.0, xmax = 7.0, close = true, fillcolor = "darkred" ],
+ [ xmin = 7.0, xmax = 12.0, close = true, fillcolor = "darkgreen" ],
+ [ xmin = 12.0, xmax = 19.0, close = true, fillcolor = "darkblue" ],
+ [
+ drawcolor = "darkyellow",
+ drawsize = 2
+ ]
+ }
+ ]
+ xsized TextWidth
+ ;
+\stopMPcode
+\stopbuffer
+
+We can draw multiple functions in one go. The next sample split the drawing over
+a few ranges and is defined as follows; in \in {figure} [function:2] we see the
+result.
+
+\typebuffer[2][option=TEX]
+
+
+\startplacefigure[reference=function:2]
+ \getbuffer[2]
+\stopplacefigure
+
+Instead of the same function, we can draw different ones and when we use transparency
+we get nice results too.
+
+\startbuffer[3]
+\definecolor[MyColorR][r=.5,t=.5,a=1]
+\definecolor[MyColorG][g=.5,t=.5,a=1]
+\definecolor[MyColorB][b=.5,t=.5,a=1]
+
+\startMPcode{doublefun}
+ draw lmt_function [
+ xmin = 0, xmax = 20, xstep = .1,
+ ymin = -1, ymax = 1,
+
+ sx = 1mm, xsmall = 80, xlarge = 20,
+ sy = 4mm, ysmall = 40, ylarge = 4,
+
+ linewidth = .025mm, offset = .1mm,
+
+ functions = {
+ [
+ code = "math.sind (50 * x - 150)",
+ close = true,
+ fillcolor = "MyColorR"
+ ],
+ [
+ code = "math.cosd (50 * x - 150)",
+ close = true,
+ fillcolor = "MyColorB"
+ ]
+ },
+ ]
+ xsized TextWidth
+ ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[3][option=TEX]
+
+\startplacefigure[reference=function:3]
+ \getbuffer[3]
+\stopplacefigure
+
+It is important to choose a good step. In \in {figure} [function:4] we show 4
+variants and it is clear that in this case using straight line segments is better
+(or at least more efficient with small steps).
+
+\startbuffer[4a]
+\startMPcode{doublefun}
+ draw lmt_function [
+ xmin = 0, xmax = 10, xstep = .1,
+ ymin = -1, ymax = 1,
+
+ sx = 1mm, sy = 4mm,
+
+ linewidth = .025mm, offset = .1mm,
+
+ code = "math.sind (50 * x^2 - 150)",
+ shape = "curve"
+ ]
+ xsized .45TextWidth
+ ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[4b]
+\startMPcode{doublefun}
+ draw lmt_function [
+ xmin = 0, xmax = 10, xstep = .01,
+ ymin = -1, ymax = 1,
+
+ sx = 1mm, sy = 4mm,
+
+ linewidth = .025mm, offset = .1mm,
+
+ code = "math.sind (50 * x^2 - 150)",
+ shape = "curve"
+ ]
+ xsized .45TextWidth
+ ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[4c]
+\startMPcode{doublefun}
+ draw lmt_function [
+ xmin = 0, xmax = 10, xstep = .1,
+ ymin = -1, ymax = 1,
+
+ sx = 1mm, sy = 4mm,
+
+ linewidth = .025mm, offset = .1mm,
+
+ code = "math.sind (50 * x^2 - 150)",
+ shape = "line"
+ ]
+ xsized .45TextWidth
+ ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[4d]
+\startMPcode{doublefun}
+ draw lmt_function [
+ xmin = 0, xmax = 10, xstep = .01,
+ ymin = -1, ymax = 1,
+
+ sx = 1mm, sy = 4mm,
+
+ linewidth = .025mm, offset = .1mm,
+
+ code = "math.sind (50 * x^2 - 150)",
+ shape = "line"
+ ]
+ xsized .45TextWidth
+ ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[4a][option=TEX]
+
+\startplacefigure[reference=function:4]
+ \startcombination[2*2]
+ {\getbuffer[4a]} {\type {xstep=.10} and \type {shape="curve"}}
+ {\getbuffer[4b]} {\type {xstep=.01} and \type {shape="curve"}}
+ {\getbuffer[4c]} {\type {xstep=.10} and \type {shape="line"}}
+ {\getbuffer[4d]} {\type {xstep=.01} and \type {shape="line"}}
+ \stopcombination
+\stopplacefigure
+
+You can manipulate the axis (a bit) by tweaking the first and last ticks. In the
+case of \in {figure} [function:5] we also put the shape on top of the axis.
+
+\startbuffer[5]
+\startMPcode{doublefun}
+ draw lmt_function [
+ xfirst = 9, xlast = 21, ylarge = 2, ysmall = 1/5,
+ yfirst = -1, ylast = 1, xlarge = 2, xsmall = 1/4,
+
+ xmin = 10, xmax = 20, xstep = .25,
+ ymin = -1, ymax = 1,
+
+ drawcolor = "darkmagenta",
+ shape = "steps",
+ code = "0.5 * math.random(-2,2)",
+ linewidth = .025mm,
+ offset = .1mm,
+ reverse = true,
+ ]
+ xsized TextWidth
+ ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[5][option=TEX]
+
+\startplacefigure[reference=function:5]
+ \getbuffer[5]
+\stopplacefigure
+
+The whole repertoire of parameters (in case of doubt just check the source code as this
+kind of code is not that hard to follow) is:
+
+\starttabulate[|T|T|T|p|]
+\FL
+\BC name \BC type \BC default \BC comment \NC \NR
+\ML
+\NC sx \NC numeric \NC 1mm \NC horizontal scale factor \NC \NR
+\NC sy \NC numeric \NC 1mm \NC vertical scale factor \NC \NR
+\NC offset \NC numeric \NC 0 \NC \NC \NR
+\NC xmin \NC numeric \NC 1 \NC \NC \NR
+\NC xmax \NC numeric \NC 1 \NC \NC \NR
+\NC xstep \NC numeric \NC 1 \NC \NC \NR
+\NC xsmall \NC numeric \NC \NC optional step of small ticks \NC \NR
+\NC xlarge \NC numeric \NC \NC optional step of large ticks \NC \NR
+\NC xlabels \NC string \NC no \NC \type {yes}, \type {no} or \type {nolimits} \NC \NR
+\NC xticks \NC string \NC bottom \NC possible locations are \type {top}, \type {middle} and \type {bottom} \NC \NR
+\NC xcaption \NC string \NC \NC \NC \NR
+\NC ymin \NC numeric \NC 1 \NC \NC \NR
+\NC ymax \NC numeric \NC 1 \NC \NC \NR
+\NC ystep \NC numeric \NC 1 \NC \NC \NR
+\NC ysmall \NC numeric \NC \NC optional step of small ticks \NC \NR
+\NC ylarge \NC numeric \NC \NC optional step of large ticks \NC \NR
+\NC xfirst \NC numeric \NC \NC left of \type {xmin} \NC \NR
+\NC xlast \NC numeric \NC \NC right of \type {xmax} \NC \NR
+\NC yfirst \NC numeric \NC \NC below \type {ymin} \NC \NR
+\NC ylast \NC numeric \NC \NC above \type {ymax} \NC \NR
+\NC ylabels \NC string \NC no \NC \type {yes}, \type {no} or \type {nolimits} \NC \NR
+\NC yticks \NC string \NC left \NC possible locations are \type {left}, \type {middle} and \type {right} \NC \NR
+\NC ycaption \NC string \NC \NC \NC \NR
+\NC code \NC string \NC \NC \NC \NR
+\NC close \NC boolean \NC false \NC \NC \NR
+\NC shape \NC string \NC curve \NC or \type {line} \NC \NR
+\NC fillcolor \NC string \NC \NC \NC \NR
+\NC drawsize \NC numeric \NC 1 \NC \NC \NR
+\NC drawcolor \NC string \NC \NC \NC \NR
+\NC frame \NC string \NC \NC options are \type {yes}, \type {ticks} and \type {sticks} \NC \NR
+\NC linewidth \NC numeric \NC .05mm \NC \NC \NR
+\NC pointsymbol \NC string \NC \NC like type {dots} \NC \NR
+\NC pointsize \NC numeric \NC 2 \NC \NC \NR
+\NC pointcolor \NC string \NC \NC \NC \NR
+\NC xarrow \NC string \NC \NC \NC \NR
+\NC yarrow \NC string \NC \NC \NC \NR
+\NC reverse \NC boolean \NC false \NC when \type {true} draw the function between axis and labels \NC \NR
+\LL
+\stoptabulate
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-grid.tex b/doc/context/sources/general/manuals/luametafun/luametafun-grid.tex
new file mode 100644
index 000000000..719d8023d
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-grid.tex
@@ -0,0 +1,11 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-grid
+
+\startchapter[title={Grid}]
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-interface.tex b/doc/context/sources/general/manuals/luametafun/luametafun-interface.tex
new file mode 100644
index 000000000..662ae61a8
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-interface.tex
@@ -0,0 +1,155 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-interface
+
+\startchapter[title={Interface}]
+
+Because graphic solutions are always kind of personal or domain driven it makes not
+much sense to cook up very generic solutions. If you have a project where \METAPOST\
+can be of help, it also makes sense to spend some time on implementing the basics that
+you need. In that case you can just copy and tweak what is there. The easiest way to
+do that is to make a test file and use:
+
+\starttyping[option=TEX]
+\startMPpage
+ % your code
+\stopMPpage
+\stoptyping
+
+Often you don't need to write macros, and standard drawing commands will do the
+job, but when you find yourself repeating code, a wapper might make sense. And
+this is why we have this key|/|value interface: it's easier to abstract your
+settings than to pass them as (expression or text) arguments to a macro,
+especially when there are many.
+
+You can find many examples of the key|/|value driven user interface in the source
+files and these are actually not that hard to understand when you know a bit of
+\METAPOST\ and the additional macros that come with \METAFUN. In case you wonder
+about overhead: the performance of this mechanism is pretty good.
+
+Although the parameter handler runs on top of the \LUA\ interface, you don't need
+to use \LUA\ unless you find that \METAPOST\ can't do the job. I won't give
+examples of coding because I think that the source of \METAFUN\ provides enough
+clues, especially the file \type {mp-lmtx.mpxl}. As the name suggests this is
+part of the \CONTEXT\ version \LMTX, which runs on top of \LUAMETATEX. I leave it
+open if I will backport this functionality to \LUATEX\ and therefore \MKIV.
+
+An excellent explanation of this interface can be found at:
+
+\starttyping
+https://adityam.github.io/context-blog/post/new-metafun-interface/
+\stoptyping
+
+So (at least for now) here I can stick to just mentioning the currently stable
+interface macros:
+
+\starttabulate[|T|l|pl|]
+\FL
+\NC presetparameters \NC \type {name [...]} \NC
+ Assign default values to a category of parameters. Sometimes it makes sense
+ not to set a default, because then you can check if a parameter has been set
+ at all.
+ \NC \NR
+\NC applyparameters \NC \type {name macro} \NC
+ This prepares the parameter handler for the given category and calls the
+ given macro when that is done.
+ \NC \NR
+\NC getparameters \NC \type {name [...]} \NC
+ The parameters given after the category name are set.
+ \NC \NR
+\ML
+\NC hasparameter \NC \type {names} \NC
+ Returns \type {true} when a parameter is set, and \type {false} otherwise.
+ \NC \NR
+\NC hasoption \NC \type {names options} \NC
+ Returns \type {true} when there is overlap in given options, and \type
+ {false} otherwise.
+ \NC \NR
+\ML
+\NC getparameter \NC \type {names} \NC
+ Resolves the parameter with the given name. because a parameter itself can
+ have a parameter list you can pass additional names to reach the final
+ destination.
+ \NC \NR
+\NC getparameterdefault \NC \type {names} \NC
+ Resolves the parameter with the given name. because a parameter itself can
+ have a parameter list you can pass additional names to reach the final
+ destination. The last value is used when no parameter is found.
+ \NC \NR
+\ML
+\NC getparametercount \NC \type {names} \NC
+ Returns the size if a list (array).
+ \NC \NR
+\NC getmaxparametercount \NC \type {names} \NC
+ Returns the size if a list (array) but descends into lists to find the largest size
+ of a sublist.
+ \NC \NR
+\ML
+\NC getparameterpath \NC \type {names string boolean} \NC
+ Returns the parameter as path. The optional string is one of \type {--},
+ \type {..} or \type {...} and the also optional boolean will force a closed
+ path.
+ \NC \NR
+\NC getparameterpen \NC \type {names} \NC
+ Returns the parameter as pen (path).
+ \NC \NR
+\NC getparametertext \NC \type {names boolean} \NC
+ Returns the parameter as string. The boolean can be used to force prepending
+ a so called \type {\strut}.
+ \NC \NR
+\ML
+\NC pushparameters \NC \type {category} \NC
+ Pushed the given (sub) category onto the stack so that we don't need to give
+ the category each time.
+ \NC \NR
+\NC popparameters \NC \NC
+ Pops the current (sub) category from the stack.
+ \NC \NR
+\LL
+\stoptabulate
+
+Most commands accept a list of strings separated by one or more spaces, The
+resolved will then stepwise descend into the parameter tree. This means that a
+parameter itself can refer to a list. When a value is an array and the last name
+is a number, the value at the given index will be returned.
+
+\starttyping
+"category" "name" ... "name"
+"category" "name" ... number
+\stoptyping
+
+The \type {category} is not used when we have pushed a (sub) category which can
+save you some typing and also is more efficient. Of course than can mean that you
+need to store values at a higher level when you need them at a deeper level.
+
+There are quite some extra helpers that relate to this mechanism, at the
+\METAPOST\ end as well as at the \LUA\ end. They aim for instance at efficiently
+dealing with paths and can be seen at work in the mentioned module.
+
+There is one thing you should notice. While \METAPOST\ has numeric, string,
+boolean and path variables that can be conveniently be passed to and from \LUA,
+communicating colors is a bit of a hassle. This is because \RGB\ and \CMYK\
+colors and gray scales use different types. For this reason it is strongly
+recommended to use strings that refer to predefined colors instead. This also
+enforces consistency with the \TEX\ end. As convenience you can define colors at
+the \METAFUN\ end.
+
+\startbuffer
+\startMPcode
+ definecolor [ name = "MyColor", r = .5, g = .25, b = .25 ]
+
+ fill fullsquare xyscaled (TextWidth,5mm) withcolor "MyColor" ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-introduction.tex b/doc/context/sources/general/manuals/luametafun/luametafun-introduction.tex
new file mode 100644
index 000000000..6892b21ce
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-introduction.tex
@@ -0,0 +1,88 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-introduction
+
+\startchapter[title={Introduction}]
+
+For quite a while, around since 1996, the integration of \METAPOST\ into
+\CONTEXT\ became sort of mature but, it took decades of stepwise refinement to
+reach the state that we're in now. In this manual I will discuss some of the
+features that became possible by combining \LUA\ and \METAPOST. We already had
+quite a bit of that for a decade but in 2018, when \LUAMETATEX\ showed up a next
+stage was started.
+
+Before we go into details it is good to summarize the steps that were involved in
+integrating \METAPOST\ and \TEX\ in \CONTEXT. It indicates a bit what we had and
+have to deal with which in turn lead to the interfaces we now have.
+
+Originally, \TEX\ had no graphic capabilities: it just needed to know dimensions
+of the graphics and pass some basic information about what to include to the
+\DVI\ post processor. So, a \METAPOST\ graphic was normally processed outside the
+current run, resulting in \POSTSCRIPT\ graphic, that then had to be included. In
+\PDFTEX\ there were some more built in options, and therefore the \METAPOST\ code
+could be processed runtime using some (generic) \TEX\ macros that I wrote.
+However, that engine still had to launch \METAPOST\ for each graphic, although we
+could accumulate them and do that between runs. Immediate processing means that
+we immediately know the dimensions, while a collective run is faster. In \LUATEX\
+this all changed to very fast runtime processing, made possible because the
+\METAPOST\ library is embedded in the engine, a decision that we made early in
+the project and never regret.
+
+With \PDFTEX\ the process was managed by the \type {texexec} \CONTEXT\ runner but
+with \LUATEX\ it stayed under the control of the current run. In the case of
+\PDFTEX\ the actual embedding was done by \TEX\ macros that interpreted the
+(relatively simple) \POSTSCRIPT\ code and turned it into \PDF\ literals. In
+\LUATEX\ that job was delegated to \LUA.
+
+When using \PDFTEX\ with independent \METAPOST\ runs support for special color
+spaces, transparency, embedded graphics, outline text, shading and more was
+implemented using specials and special colors where the color served as reference
+to some special extension. This works quite well. In \LUATEX\ the pre- and
+postscript features, which are properties of picture objects, are used.
+
+In all cases, some information about the current run, for instance layout related
+information, or color information, has to be passed to the rather isolated
+\METAPOST\ run. In the case if \LUATEX\ (and \MKIV) the advantage is that
+processing optional text happens in the same process so there we don't need to
+pass information about for instance the current font setup.
+
+In \LUATEX\ the \METAPOST\ library has a \type {runscript} feature, which will
+call \LUA\ with the given code. This permitted a better integration: we could now
+ask for specific information (to the \TEX\ end) instead of passing it from the
+\TEX\ end with each run. In \LUAMETATEX\ another feature was added: access to the
+scanners from the \LUA\ end. Although we could already fetch some variables when
+in \LUA\ this made it possible to extend the \METAPOST\ language in ways not
+possible before.
+
+Already for a while Alan Braslau and I were working on some new \METAFUN\ code
+that exploits all these new features. When the scanners came available I sat down
+and started working on new interfaces and in this manual I will discuss some of
+these. Some of them are illustrative, others are probably rather useful. The core
+of what we could call \LUAMETAFUN\ (or \METAFUN\ XL when we use the file
+extension as indicator) is a key|-|value interface as we have at the \TEX\ end.
+This interface relates to \CONTEXT\ \LMTX\ development and therefore related
+files have a different suffix: \type {mpxl}. However, keep in mind that some are
+just wrappers around regular \METAPOST\ code so you have the full power of
+traditional \METAPOST\ at hand.
+
+We can never satisfy all needs, so to some extent this manual also demonstrates
+how to roll out your own code, but for that you also need to peek into the
+\METAFUN\ source code too. It will take a while for this manual to complete. I
+also expect other users to come up with solutions, so maybe in the end we will
+have a collection of modules for specific tasks.
+
+\startlines
+Hans Hagen
+Hasselt NL
+August 2019 (and beyond)
+\stoplines
+
+\stopchapter
+
+\stopcomponent
+
+% I started writing this in 2019, a few days after seeing Wende live in Zeist (
+% (YT: WENDE - # MENS), one of the best shows of that year, a clear reminder of
+% timeless versatility.
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-mesh-examples.tex b/doc/context/sources/general/manuals/luametafun/luametafun-mesh-examples.tex
new file mode 100644
index 000000000..87f6d105f
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-mesh-examples.tex
@@ -0,0 +1,161 @@
+\startbuffer[1]
+\startuseMPgraphic{MyPath1}
+ fill OverlayBox withcolor "darkyellow" ;
+ save p ; path p[] ;
+ p1 := unitsquare xysized( OverlayWidth/4, OverlayHeight/4) ;
+ p2 := unitsquare xysized(2OverlayWidth/4,3OverlayHeight/5) shifted ( OverlayWidth/4,0) ;
+ p3 := unitsquare xysized( OverlayWidth/4, OverlayHeight ) shifted (3OverlayWidth/4,0) ;
+ fill p1 withcolor "darkred" ;
+ fill p2 withcolor "darkblue" ;
+ fill p3 withcolor "darkgreen" ;
+ draw lmt_mesh [ paths = { p1, p2, p3 } ] ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[2]
+\startuseMPgraphic{MyPath2}
+ save q ; path q ; q := unitcircle xysized(OverlayWidth,OverlayHeight) ;
+ save p ; path p ; p := for i=1 upto length(q) :
+ (center q) -- (point (i-1) of q) -- (point i of q) -- (center q) --
+ endfor cycle ;
+ fill q withcolor "darkgray" ;
+ draw lmt_mesh [
+ trace = true,
+ paths = { p }
+ ] withcolor "darkred" ;
+
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[3]
+\startuseMPgraphic{MyPath3}
+ save q ; path q ; q := unitcircle xysized(OverlayWidth,OverlayHeight) randomized 3mm ;
+ fill q withcolor "darkgray" ;
+ draw lmt_mesh [
+ trace = true,
+ paths = { meshed(q,OverlayBox,.05) }
+ ] withcolor "darkgreen" ;
+ % draw OverlayMesh(q,.025) withcolor "darkgreen" ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[4]
+\startuseMPgraphic{MyPath4}
+ save q ; path q ; q := unitcircle xysized(OverlayWidth,OverlayHeight) randomized 3mm ;
+ fill q withcolor "darkgray" ;
+ draw lmt_mesh [
+ trace = true,
+ auto = true,
+ step = 0.0125,
+ paths = { q }
+ ] withcolor "darkyellow" ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[5]
+\startuseMPgraphic{MyPath5}
+ save q ; path q ; q := unitdiamond xysized(OverlayWidth,OverlayHeight) randomized 2mm ;
+ q := q shifted - center q shifted center OverlayBox ;
+ fill q withcolor "darkgray" ;
+ draw lmt_mesh [
+ trace = true,
+ auto = true,
+ step = 0.0125,
+ paths = { q }
+ ] withcolor "darkmagenta" ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[6]
+\startuseMPgraphic{MyPath6}
+ save p ; path p[] ;
+ p1 := p2 := fullcircle xysized(2OverlayWidth/5,2OverlayHeight/3) ;
+ p1 := p1 shifted - center p1 shifted center OverlayBox shifted (-1OverlayWidth/4,0) ;
+ p2 := p2 shifted - center p2 shifted center OverlayBox shifted ( 1OverlayWidth/4,0) ;
+ fill p1 withcolor "middlegray" ;
+ fill p2 withcolor "middlegray" ;
+ draw lmt_mesh [
+ trace = true,
+ auto = true,
+ step = 0.02,
+ paths = { p1, p2 }
+ ] withcolor "darkcyan" ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[7]
+\startuseMPgraphic{MyPath7}
+ save p ; path p[] ;
+ p1 := p2 := fullcircle xysized(2OverlayWidth/5,2OverlayHeight/3) rotated 45 ;
+ p1 := p1 shifted - center p1 shifted center OverlayBox shifted (-1OverlayWidth/4,0) ;
+ p2 := p2 shifted - center p2 shifted center OverlayBox shifted ( 1OverlayWidth/4,0) ;
+ fill p1 withcolor "middlegray" ;
+ fill p2 withcolor "middlegray" ;
+ draw lmt_mesh [
+ trace = true,
+ auto = true,
+ step = 0.01,
+ box = OverlayBox enlarged -5mm,
+ paths = { p1, p2 }
+ ] withcolor "darkcyan" ;
+ draw OverlayBox enlarged -5mm withcolor "darkgray" ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\stopbuffer
+
+\continueifinputfile {luametafun-mesh-examples.tex}
+
+\setupbodyfont[dejavu]
+
+\setupinteraction
+ [state=start,
+ color=white,
+ contrastcolor=white]
+
+\starttext
+
+ \getbuffer[1,2,3,4,5,6,7]
+
+ \defineoverlay[MyPath1][\useMPgraphic{MyPath1}]
+ \defineoverlay[MyPath2][\useMPgraphic{MyPath2}]
+ \defineoverlay[MyPath3][\useMPgraphic{MyPath3}]
+ \defineoverlay[MyPath4][\useMPgraphic{MyPath4}]
+ \defineoverlay[MyPath5][\useMPgraphic{MyPath5}]
+ \defineoverlay[MyPath6][\useMPgraphic{MyPath6}]
+ \defineoverlay[MyPath7][\useMPgraphic{MyPath7}]
+
+ \startTEXpage
+ \button[height=3cm,width=4cm,background=MyPath1,frame=off]{Example 1}[realpage(2)]
+ \stopTEXpage
+
+ \startTEXpage
+ \button[height=3cm,width=4cm,background=MyPath2,frame=off]{Example 2}[realpage(3)]
+ \stopTEXpage
+
+ \startTEXpage
+ \button[height=3cm,width=4cm,background=MyPath3,frame=off]{Example 3}[realpage(4)]
+ \stopTEXpage
+
+ \startTEXpage
+ \button[height=3cm,width=4cm,background=MyPath4,frame=off]{Example 4}[realpage(5)]
+ \stopTEXpage
+
+ \startTEXpage
+ \button[height=3cm,width=4cm,background=MyPath5,frame=off]{Example 5}[realpage(6)]
+ \stopTEXpage
+
+ \startTEXpage
+ \button[height=3cm,width=4cm,background=MyPath6,frame=off]{Example 6}[realpage(7)]
+ \stopTEXpage
+
+ \startTEXpage
+ \button[height=3cm,width=4cm,background=MyPath7,frame=off]{Example 7}[realpage(1)]
+ \stopTEXpage
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-mesh.tex b/doc/context/sources/general/manuals/luametafun/luametafun-mesh.tex
new file mode 100644
index 000000000..2fdb31250
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-mesh.tex
@@ -0,0 +1,78 @@
+% language=us
+
+\environment luametafun-style
+\environment luametafun-mesh-examples
+
+\startcomponent luametafun-mesh
+
+\startchapter[title={Mesh}]
+
+This is more a gimmick than of real practical use. A mesh is a set of paths that
+gets transformed into hyperlinks. So, as a start you need to enable these:
+
+\starttyping[option=TEX]
+\setupinteraction
+ [state=start,
+ color=white,
+ contrastcolor=white]
+\stoptyping
+
+We just give a bunch of examples of meshes. A path is divided in smaller paths and
+each of them is part of the same hyperlink. An application is for instance clickable
+maps but (so far) only Acrobat supports such paths.
+
+\typebuffer[1][option=TEX]
+
+Such a definition is used as follows. First we define the mesh as overlay:
+
+\starttyping[option=TEX]
+\defineoverlay[MyPath1][\useMPgraphic{MyPath1}]
+\stoptyping
+
+Then, later on, this overlay can be used as background for a button. Here we just
+jump to another page. The rendering is shown in \in {figure} [mesh:1].
+
+\starttyping[option=TEX]
+\button
+ [height=3cm,
+ width=4cm,
+ background=MyPath1,
+ frame=off]
+ {Example 1}
+ [realpage(2)]
+\stoptyping
+
+\startplacefigure[reference=mesh:1]
+ \externalfigure[luametafun-mesh-examples][page=1,width=.45\textwidth]
+\stopplacefigure
+
+More interesting are non|-|rectangular shapes so we show a bunch of them. You can
+pass multiple paths, influence the accuracy by setting the number of steps and show
+the mesh with the tracing option.
+
+\typebuffer[2][option=TEX]
+\typebuffer[3][option=TEX]
+\typebuffer[4][option=TEX]
+\typebuffer[5][option=TEX]
+\typebuffer[6][option=TEX]
+\typebuffer[7][option=TEX]
+
+This is typical a feature that, if used at all, needs some experimenting but at
+least the traced images look interesting enough. The six examples are shown in
+\in {figure} [mesh:2].
+
+\startplacefigure[reference=mesh:2]
+ \startcombination[2*3]
+ {\externalfigure[luametafun-mesh-examples][page=2,width=.45\textwidth]} {\type {MyPath2}}
+ {\externalfigure[luametafun-mesh-examples][page=3,width=.45\textwidth]} {\type {MyPath3}}
+ {\externalfigure[luametafun-mesh-examples][page=4,width=.45\textwidth]} {\type {MyPath4}}
+ {\externalfigure[luametafun-mesh-examples][page=5,width=.45\textwidth]} {\type {MyPath5}}
+ {\externalfigure[luametafun-mesh-examples][page=6,width=.45\textwidth]} {\type {MyPath6}}
+ {\externalfigure[luametafun-mesh-examples][page=7,width=.45\textwidth]} {\type {MyPath7}}
+ \stopcombination
+\stopplacefigure
+
+\stopchapter
+
+\stopcomponent
+
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-outline.tex b/doc/context/sources/general/manuals/luametafun/luametafun-outline.tex
new file mode 100644
index 000000000..e2cdb4226
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-outline.tex
@@ -0,0 +1,188 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-outline
+
+\startchapter[title={Outline}]
+
+In a regular text you can have outline characters by setting a (pseudo) font
+feature but sometimes you want to play a bit more with this. In \METAFUN\ we
+always had that option. In \MKII\ we call \type {pstoedit} to turn text into
+outlines, in \MKIV\ we do that by manipulating the shapes directly. And, as with
+some other extensions, in \LMTX\ a new interface has been added, but the
+underlying code is the same as in \MKIV.
+
+\startbuffer[1a]
+\startMPcode{doublefun}
+ draw lmt_outline [
+ text = "hello"
+ kind = "draw",
+ drawcolor = "darkblue",
+ ] xsized .45TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[1b]
+\startMPcode{doublefun}
+ draw lmt_outline [
+ text = "hello",
+ kind = "both",
+ fillcolor = "middlegray",
+ drawcolor = "darkgreen",
+ rulethickness = 1/5,
+ ] xsized .45TextWidth ;
+\stopMPcode
+\stopbuffer
+
+In \in {figure} [outline:1] we see two examples:
+
+\typebuffer[1a][option=TEX]
+
+and
+
+\typebuffer[1b][option=TEX]
+
+\startplacefigure[reference=outline:1,title={Drawing and|/|or filling an outline.}]
+ \startcombination
+ {\getbuffer[1a]} {\type {kind=draw}}
+ {\getbuffer[1b]} {\type {kind=both}}
+ \stopcombination
+\stopplacefigure
+
+Normally the fill ends up below the draw but we can reverse the order, as in
+\in {figure} [outline:2], where we coded the leftmost example as:
+
+\startbuffer[2a]
+\startMPcode{doublefun}
+ draw lmt_outline [
+ text = "hello",
+ kind = "reverse",
+ fillcolor = "darkred",
+ drawcolor = "darkblue",
+ rulethickness = 1/2,
+ ] xsized .45TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[2b]
+\startMPcode{doublefun}
+ draw lmt_outline [
+ text = "hello",
+ kind = "both",
+ fillcolor = "darkred",
+ drawcolor = "darkblue",
+ rulethickness = 1/2,
+ ] xsized .45TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[2a][option=TEX]
+
+\startplacefigure[reference=outline:2,title={Reversing the order of drawing and filling.}]
+ \startcombination
+ {\getbuffer[2a]} {\type {kind=reverse}}
+ {\getbuffer[2b]} {\type {kind=both}}
+ \stopcombination
+\stopplacefigure
+
+It is possible to fill and draw in one operation, in which case the same color is
+used for both, see \in {figure} [outline:3] for an example fo this. This is a low
+level optimization where the shape is only output once.
+
+\startbuffer[3a]
+\startMPcode{doublefun}
+ draw lmt_outline [
+ text = "hello",
+ kind = "fillup",
+ fillcolor = "darkgreen",
+ rulethickness = 1/5,
+ ] xsized .45TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[3b]
+\startMPcode{doublefun}
+ draw lmt_outline [
+ text = "hello",
+ kind = "fill",
+ fillcolor = "darkgreen",
+ rulethickness = 1/5,
+ ] xsized .45TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startplacefigure[reference=outline:3,title={Combining a fill with a draw in the same color.}]
+ \startcombination
+ {\getbuffer[3a]} {\type {kind=fillup}}
+ {\getbuffer[3b]} {\type {kind=fill}}
+ \stopcombination
+\stopplacefigure
+
+
+This interface is much nicer than the one where each variant (the parameter \type
+{kind} above) had its own macro due to the need to group properties of the
+outline and fill. Let's show some more:
+
+\startbuffer[4]
+\startMPcode{doublefun}
+ draw lmt_outline [
+ text = "\obeydiscretionaries\samplefile{tufte}",
+ align = "normal",
+ kind = "draw",
+ drawcolor = "darkblue",
+ ] xsized TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[4][option=TEX]
+
+In this case we feed the text into the \type {\framed} macro so that we get a
+properly aligned paragraph of text, as demonstrated in \in {figure} [outline:4]
+\in {and} [outline:5]. If you want more trickery you can of course use any
+\CONTEXT\ command (including \type {\framed} with all kind of options) in the
+text.
+
+\startplacefigure[reference=outline:4,title={Outlining a paragraph of text.}]
+ \getbuffer[4]
+\stopplacefigure
+
+\startbuffer[5]
+\startMPcode{doublefun}
+ draw lmt_outline [
+ text = "\obeydiscretionaries\samplefile{ward}",
+ align = "normal,tolerant",
+ style = "bold",
+ width = 10cm,
+ kind = "draw",
+ drawcolor = "darkblue",
+ ] xsized TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[5][option=TEX]
+
+\startplacefigure[reference=outline:4,title={Outlining a paragraph of text with a specific width.}]
+ \getbuffer[5]
+\stopplacefigure
+
+We summarize the parameters:
+
+\starttabulate[|T|T|T|p|]
+\FL
+\BC name \BC type \BC default \BC comment \NC \NR
+\ML
+\NC text \NC string \NC \NC \NC \NR
+\NC kind \NC string \NC draw \NC One of \type {draw}, \type {fill}, \type {both}, \type {reverse} and \type {fillup}. \NC \NR
+\NC fillcolor \NC string \NC \NC \NC \NR
+\NC drawcolor \NC string \NC \NC \NC \NR
+\NC rulethickness \NC numeric \NC 1/10 \NC \NC \NR
+\NC align \NC string \NC \NC \NC \NR
+\NC style \NC string \NC \NC \NC \NR
+\NC width \NC numeric \NC \NC \NC \NR
+\LL
+\stoptabulate
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-placeholder.tex b/doc/context/sources/general/manuals/luametafun/luametafun-placeholder.tex
new file mode 100644
index 000000000..3627bbfd0
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-placeholder.tex
@@ -0,0 +1,163 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-placeholder
+
+\startchapter[title={Placeholder}]
+
+Placeholders are an old \CONTEXT\ features and have been around since we started using
+\METAPOST. They are used as dummy figure, just in case one is not (yet) present. They
+are normally activated by loading a \METAFUN\ library:
+
+\starttyping[option=TEX]
+\useMPLibrary[dum]
+\stoptyping
+
+Just because it could be done conveniently, placeholders are now defined at the
+\METAPOST\ end instead of as useable \METAPOST\ graphic at the \TEX\ end. The
+variants and options are demonstrated using side floats.
+
+\startbuffer[1]
+\startMPcode
+ lmt_placeholder [
+ width = 4cm,
+ height = 3cm,
+ color = "red",
+ alternative = "circle".
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\startplacefigure[location=left]
+ \getbuffer[1]
+\stopplacefigure
+
+\typebuffer[1][option=TEX]
+
+In addition to the traditional random circle we now also provide rectangles
+and triangles. Maybe some day more variants will show up.
+
+\startbuffer[2]
+\startMPcode
+ lmt_placeholder [
+ width = 4cm,
+ height = 3cm,
+ color = "green",
+ alternative = "square".
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\startplacefigure[location=left]
+ \getbuffer[2]
+\stopplacefigure
+
+\typebuffer[2][option=TEX]
+
+Here we set the colors but in the image placeholder mechanism we cycle through
+colors automatically. Here we use primary, rather dark, colors.
+
+\startbuffer[3]
+\startMPcode
+ lmt_placeholder [
+ width = 4cm,
+ height = 3cm,
+ color = "blue",
+ alternative = "triangle".
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\startplacefigure[location=left]
+ \getbuffer[3]
+\stopplacefigure
+
+\typebuffer[3][option=TEX]
+
+\startbuffer[4a]
+\startMPcode
+ lmt_placeholder [
+ width = 4cm,
+ height = 3cm,
+ color = "yellow",
+ alternative = "circle".
+ reduction = 0,
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[4b]
+\startMPcode
+ lmt_placeholder [
+ width = 4cm,
+ height = 3cm,
+ color = "yellow",
+ alternative = "circle".
+ reduction = 0.25,
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[4c]
+\startMPcode
+ lmt_placeholder [
+ width = 4cm,
+ height = 3cm,
+ color = "yellow",
+ alternative = "circle".
+ reduction = 0.50,
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[4d]
+\startMPcode
+ lmt_placeholder [
+ width = 4cm,
+ height = 3cm,
+ color = "yellow",
+ alternative = "circle".
+ reduction = 0.75,
+ ] ;
+\stopMPcode
+\stopbuffer
+
+If you want less dark colors, the \type {reduction} parameter can be used to
+interpolate between the given color and white; its value is therefore a value
+between zero (default) and 1 (rather pointless as it produces white).
+
+\startplacefigure[location=left]
+ \startcombination[2*2]
+ {\getbuffer[4a]} {0}
+ {\getbuffer[4b]} {0.25}
+ {\getbuffer[4c]} {0.50}
+ {\getbuffer[4d]} {0.75}
+ \stopcombination
+\stopplacefigure
+
+We demonstrate this with four variants, all circles. Of course you can also use
+lighter colors, but this option was needed for the image placeholders anyway.
+
+\typebuffer[4b][option=TEX]
+
+\flushsidefloats
+
+There are only a few possible parameters. As you can see, proper dimensions need
+to be given because the defaults are pretty small.
+
+\starttabulate[|T|T|T|p|]
+\FL
+\BC name \BC type \BC default \BC comment \NC \NR
+\ML
+\NC color \NC string \NC red \NC \NC \NR
+\NC width \NC numeric \NC 1 \NC \NC \NR
+\NC height \NC numeric \NC 1 \NC \NC \NR
+\NC reduction \NC numeric \NC 0 \NC \NC \NR
+\NC alternative \NC string \NC circle \NC \NC \NR
+\LL
+\stoptabulate
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-shade.tex b/doc/context/sources/general/manuals/luametafun/luametafun-shade.tex
new file mode 100644
index 000000000..a139be954
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-shade.tex
@@ -0,0 +1,230 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-shade
+
+\startchapter[title={Shade}]
+
+{\em This interface is still experimental!}
+
+Shading is complex. We go from one color to another on a continuum either linear
+or circular. We have to make sure that we cover the whole shape and that means
+that we have to guess a little, although one can influence this with parameters.
+It can involve a bit of trial and error, which is more complex that using a
+graphical user interface but this is the price we pay. It goes like this:
+
+\startbuffer[1]
+\startMPcode
+definecolor [ name = "MyColor3", r = 0.22, g = 0.44, b = 0.66 ] ;
+definecolor [ name = "MyColor4", r = 0.66, g = 0.44, b = 0.22 ] ;
+
+draw lmt_shade [
+ path = fullcircle scaled 4cm,
+ direction = "right",
+ domain = { 0, 2 },
+ colors = { "MyColor3", "MyColor4" },
+] ;
+
+draw lmt_shade [
+ path = fullcircle scaled 3cm,
+ direction = "left",
+ domain = { 0, 2 },
+ colors = { "MyColor3", "MyColor4" },
+] shifted (45mm,0) ;
+
+draw lmt_shade [
+ path = fullcircle scaled 5cm,
+ direction = "up",
+ domain = { 0, 2 },
+ colors = { "MyColor3", "MyColor4" },
+] shifted (95mm,0) ;
+
+draw lmt_shade [
+ path = fullcircle scaled 1cm,
+ direction = "down",
+ domain = { 0, 2 },
+ colors = { "MyColor3", "MyColor4" },
+] shifted (135mm,0) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[1][option=TEX]
+
+Normally this is good enough as demonstrated in \in {figure} [shade:1] because
+we use shades as backgrounds. In the case of a circular shade we need to tweak
+the domain because guessing doesn't work well.
+
+\startplacefigure[reference=shade:1,title={Simple circular shades.}]
+ \getbuffer[1]
+\stopplacefigure
+
+\startbuffer[2]
+\startMPcode
+draw lmt_shade [
+ path = fullsquare scaled 4cm,
+ alternative = "linear",
+ direction = "right",
+ colors = { "MyColor3", "MyColor4" },
+] ;
+
+draw lmt_shade [
+ path = fullsquare scaled 3cm,
+ direction = "left",
+ alternative = "linear",
+ colors = { "MyColor3", "MyColor4" },
+] shifted (45mm,0) ;
+
+draw lmt_shade [
+ path = fullsquare scaled 5cm,
+ direction = "up",
+ alternative = "linear",
+ colors = { "MyColor3", "MyColor4" },
+] shifted (95mm,0) ;
+
+draw lmt_shade [
+ path = fullsquare scaled 1cm,
+ direction = "down",
+ alternative = "linear",
+ colors = { "MyColor3", "MyColor4" },
+] shifted (135mm,0) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[2][option=TEX]
+
+\startplacefigure[reference=shade:2,title={Simple rectangular shades.}]
+ \getbuffer[2]
+\stopplacefigure
+
+The \type {direction} relates to the boundingbox. Instead of a keyword you can
+also give two values, indicating points on the boundingbox. Because a boundingbox
+has four points, the \type {up} direction is equivalent to \type {{0.5,2.5}}.
+
+The parameters \type {center}, \type {factor}, \type {vector} and \type {domain}
+are a bit confusing but at some point the way they were implemented made sense,
+so we keep them as they are. The center moves the center of the path that is used
+as anchor for one color proportionally to the bounding box: the given factor is
+multiplied by half the width and height.
+
+\startbuffer[3]
+\startMPcode
+draw lmt_shade [
+ path = fullcircle scaled 5cm,
+ domain = { .2, 1.6 },
+ center = { 1/10, 1/10 },
+ direction = "right",
+ colors = { "MyColor3", "MyColor4" },
+ trace = true,
+] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[3][option=TEX]
+
+\startplacefigure[reference=shade:3,title={Moving the centers.}]
+ \getbuffer[3]
+\stopplacefigure
+
+A vector takes the given points on the path as centers for the colors, see \in
+{figure} [shade:4].
+
+\startbuffer[4]
+\startMPcode
+draw lmt_shade [
+ path = fullcircle scaled 5cm,
+ domain = { .2, 1.6 },
+ vector = { 2, 4 },
+ direction = "right",
+ colors = { "MyColor3", "MyColor4" },
+ trace = true,
+] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[4][option=TEX]
+
+\startplacefigure[reference=shade:4,title={Using a vector (points).}]
+ \getbuffer[4]
+\stopplacefigure
+
+Messing with the radius in combination with the previously mentioned domain
+is really trial and error, as seen in \in {figure} [shade:5].
+
+\startbuffer[5]
+\startMPcode
+draw lmt_shade [
+ path = fullcircle scaled 5cm,
+ domain = { 0.5, 2.5 },
+ radius = { 2cm, 6cm },
+ direction = "right",
+ colors = { "MyColor3", "MyColor4" },
+ trace = true,
+] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[5][option=TEX]
+
+\startplacefigure[reference=shade:5,title={Tweaking the radius.}]
+ \getbuffer[5]
+\stopplacefigure
+
+But actually the radius used alone works quite well as shown in \in {figure}
+[shade:6].
+
+\startbuffer[6]
+\startMPcode
+draw lmt_shade [
+ path = fullcircle scaled 5cm,
+ colors = { "red", "green" },
+ trace = true,
+] ;
+
+draw lmt_shade [
+ path = fullcircle scaled 5cm,
+ colors = { "red", "green" },
+ radius = 2.5cm,
+ trace = true,
+] shifted (6cm,0) ;
+
+draw lmt_shade [
+ path = fullcircle scaled 5cm,
+ colors = { "red", "green" },
+ radius = 2.0cm,
+ trace = true,
+] shifted (12cm,0) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[6][option=TEX]
+
+\startplacefigure[reference=shade:6,title={Just using the radius.}]
+ \getbuffer[6]
+\stopplacefigure
+
+\starttabulate[|T|T|T|p|]
+\FL
+\BC name \BC type \BC default \BC comment \NC \NR
+\ML
+\NC alternative \NC string \NC circular \NC or \type {linear} \NC \NR
+\NC path \NC path \NC \NC \NC \NR
+\NC trace \NC boolean \NC false \NC \NC \NR
+\NC domain \NC set of numerics \NC \NC \NC \NR
+\NC radius \NC numeric \NC \NC \NC \NR
+\NC \NC set of numerics \NC \NC \NC \NR
+\NC factor \NC numeric \NC \NC \NC \NR
+\NC origin \NC pair \NC \NC \NC \NR
+\NC \NC set of pairs \NC \NC \NC \NR
+\NC vector \NC set of numerics \NC \NC \NC \NR
+\NC colors \NC set of strings \NC \NC \NC \NR
+\NC center \NC numeric \NC \NC \NC \NR
+\NC \NC set of numerics \NC \NC \NC \NR
+\NC direction \NC string \NC \NC \type{up}, \type {down}, \type {left}, \type {right} \NC \NR
+\NC \NC set of numerics \NC \NC two points on the boundingbox \NC \NR
+\LL
+\stoptabulate
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-style.tex b/doc/context/sources/general/manuals/luametafun/luametafun-style.tex
new file mode 100644
index 000000000..df469d0c0
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-style.tex
@@ -0,0 +1,55 @@
+\startenvironment luametafun-style
+
+\usemodule[abbreviations-smallcaps]
+
+\usemodule[scite]
+
+\setupbodyfont
+ [ibmplex,rm,10pt]
+
+\setupwhitespace
+ [big]
+
+\setuplayout
+ [topspace=10mm,
+ bottomspace=1cm,
+ backspace=2cm,
+ footerdistance=10mm,
+ footer=1cm,
+ % headerdistance=10mm,
+ % header=1cm,
+ topspace=20mm,
+ headerdistance=0mm,
+ header=0cm,
+ height=middle,
+ width=middle]
+
+\setupalign
+ [verytolerant]
+
+\setupheadertexts
+ []
+
+\setupfootertexts
+ [chapter][pagenumber]
+
+\setuphead
+ [chapter]
+ [color=darkgray,
+ style=\bfd]
+
+\setuphead
+ [section]
+ [color=darkgray,
+ style=\bfc]
+
+\setupfooter
+ [color=darkgray,
+ style=\bf]
+
+\setuplist
+ [chapter]
+ [before=,
+ after=]
+
+\stopenvironment
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-svg.tex b/doc/context/sources/general/manuals/luametafun/luametafun-svg.tex
new file mode 100644
index 000000000..f7aba06fd
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-svg.tex
@@ -0,0 +1,75 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-svg
+
+\startchapter[title={SVG}]
+
+There is not that much to tell about this command. It translates an \SVG\ image
+to \METAPOST\ operators. We took a few images from a mozilla emoji font:
+
+\startbuffer[2]
+\startMPcode
+ draw lmt_svg [
+ filename = "mozilla-svg-002.svg",
+ height = 2cm,
+ width = 8cm,
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[2][option=TEX]
+
+\startlinecorrection
+ \getbuffer[2]
+\stoplinecorrection
+
+Because we get pictures, you can do mess around with them:
+
+\startbuffer[1]
+\startMPcode
+ picture p ; p := lmt_svg [ filename = "mozilla-svg-001.svg" ] ;
+ numeric w ; w := bbwidth(p) ;
+ draw p ;
+ draw p xscaled -1 shifted (2.5*w,0);
+ draw p rotatedaround(center p,45) shifted (3.0*w,0) ;
+ draw image (
+ for i within p : if filled i :
+ draw pathpart i withcolor green ;
+ fi endfor ;
+ ) shifted (4.5*w,0);
+ draw image (
+ for i within p : if filled i :
+ fill pathpart i withcolor red withtransparency (1,.25) ;
+ fi endfor ;
+ ) shifted (6*w,0);
+\stopMPcode
+\stopbuffer
+
+\typebuffer[1][option=TEX]
+
+\startlinecorrection
+ \getbuffer[1]
+\stoplinecorrection
+
+Of course. often you won't know in advance what is inside the image and how (well)
+it has been defined so the previous example is more about showing some \METAPOST\
+muscle.
+
+The supported parameters are:
+
+\starttabulate[|T|T|T|p|]
+\FL
+\BC name \BC type \BC default \BC comment \NC \NR
+\ML
+\NC filename \NC path \NC \NC \NC \NR
+\NC width \NC numeric \NC \NC \NC \NR
+\NC height \NC numeric \NC \NC \NC \NR
+\LL
+\stoptabulate
+
+\stopchapter
+
+\stopcomponent
+
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-text.tex b/doc/context/sources/general/manuals/luametafun/luametafun-text.tex
new file mode 100644
index 000000000..4f08ee00f
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-text.tex
@@ -0,0 +1,137 @@
+% language=us
+
+\environment luametafun-style
+
+\startcomponent luametafun-text
+
+\startchapter[title={Text}]
+
+The \METAFUN\ \type {textext} command normally can do the job of typesetting a
+text snippet quite well.
+
+\startbuffer
+\startMPcode
+ fill fullcircle xyscaled (8cm,1cm) withcolor "darkred" ;
+ draw textext("\bf This is text A") withcolor "white" ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+We get:
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+You can use regular \CONTEXT\ commands, so this is valid:
+
+\startbuffer
+\startMPcode
+ fill fullcircle xyscaled (8cm,1cm) withcolor "darkred" ;
+ draw textext("\framed{\bf This is text A}") withcolor "white" ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+Of course you can as well draw a frame in \METAPOST\ but the \type {\framed}
+command has more options, like alignments.
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+Here is a variant using the \METAFUN\ interface:
+
+\startbuffer
+\startMPcode
+ fill fullcircle xyscaled (8cm,1cm) withcolor "darkred" ;
+ draw lmt_text [
+ text = "This is text A",
+ color = "white",
+ style = "bold"
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+The outcome is more or less the same:
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+Here is another example. The \type {format} option is actually why this command
+is provided.
+
+\startbuffer
+\startMPcode
+ fill fullcircle xyscaled (8cm,1cm) withcolor "darkred" ;
+ draw lmt_text [
+ text = decimal 123.45678,
+ color = "white",
+ style = "bold",
+ format = "@0.3F",
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+The following parameters can be set:
+
+\starttabulate[|T|T|T|p|]
+\FL
+\BC name \BC type \BC default \BC comment \NC \NR
+\ML
+\NC offset \NC numeric \NC 0 \NC \NC \NR
+\NC strut \NC string \NC auto \NC adapts the dimensions to the font (\type {yes} uses the the default strut) \NC \NR
+\NC style \NC string \NC \NC \NC \NR
+\NC color \NC string \NC \NC \NC \NR
+\NC text \NC string \NC \NC \NC \NR
+\NC anchor \NC string \NC \NC one of these \type {lft}, \type {urt} like anchors \NC \NR
+\NC format \NC string \NC \NC a format specifier using \type {@} instead of a percent sign \NC \NR
+\NC position \NC pair \NC origin \NC \NC \NR
+\NC trace \NC boolean \NC false \NC \NC \NR
+\LL
+\stoptabulate
+
+The next example demonstrates the positioning options:
+
+\startbuffer
+\startMPcode
+ fill fullcircle xyscaled (8cm,1cm) withcolor "darkblue" ;
+ fill fullcircle scaled .5mm withcolor "white" ;
+ draw lmt_text [
+ text = "left",
+ color = "white",
+ style = "bold",
+ anchor = "lft",
+ position = (-1mm,2mm),
+ ] ;
+ draw lmt_text [
+ text = "right",
+ color = "white",
+ style = "bold",
+ anchor = "rt",
+ offset = 3mm,
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun-titlepage.tex b/doc/context/sources/general/manuals/luametafun/luametafun-titlepage.tex
new file mode 100644
index 000000000..4450199e6
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun-titlepage.tex
@@ -0,0 +1,41 @@
+
+\environment luametafun-style
+
+\startcomponent luametafun-titlepage
+
+\startMPpage
+
+ fill Page withcolor "darkblue" ;
+
+ path p ; p := (0,0) -- (0,4) -- (2,2) -- (4,4) -- (4,0) ;
+
+ p := p scaled 20; p := p shifted - center p ;
+
+ draw image (
+ for i=1 upto 1000 :
+ draw p shifted (center Page randomized urcorner Page) ;
+ endfor ;
+ ) withcolor "darkgreen" ;
+
+ setbounds currentpicture to Page ;
+
+ draw
+ % textext.ulft("\ss luametafun")
+ textext.ulft("\ss metafun xl")
+ xsized .55bbwidth(Page)
+ shifted lrcorner Page
+ shifted (-15mm,35mm)
+ withcolor "white"
+ ;
+
+ draw
+ textext.ulft("\ss Hans Hagen")
+ xsized .3bbwidth(Page)
+ shifted lrcorner Page
+ shifted (-15mm,15mm)
+ withcolor "white"
+ ;
+
+\stopMPpage
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun.tex b/doc/context/sources/general/manuals/luametafun/luametafun.tex
new file mode 100644
index 000000000..0e298dcd0
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/luametafun.tex
@@ -0,0 +1,31 @@
+\setupfootertexts[{\tttf uncorrected draft}]
+
+\environment luametafun-style
+
+\startcomponent luametafun
+
+ \component luametafun-titlepage
+
+ \startfrontmatter
+ \component luametafun-contents
+ \component luametafun-introduction
+ \stopfrontmatter
+
+ \startbodymatter
+ \component luametafun-text
+ \component luametafun-function
+ \component luametafun-contour
+ % \component luametafun-grid
+ \component luametafun-axis
+ \component luametafun-outline
+ \component luametafun-followtext
+ \component luametafun-placeholder
+ \component luametafun-arrow
+ \component luametafun-chart
+ \component luametafun-mesh
+ \component luametafun-shade
+ \component luametafun-svg
+ \component luametafun-interface
+ \stopbodymatter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luametafun/mozilla-svg-001.svg b/doc/context/sources/general/manuals/luametafun/mozilla-svg-001.svg
new file mode 100644
index 000000000..f74af7dd1
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/mozilla-svg-001.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg"><path fill="#d87512" d="M17.786 44.63c-.606.115-1.23.173-1.854.173-2.444 0-4.644-.864-6.04-2.375-.855-.92-1.394-2.147-1.517-3.47-.126-1.243.067-2.638.58-4.163.325-1.016.83-2.01 1.365-3.064.216-.426.437-.858.65-1.302.702-1.454 1.504-3.164 2.11-5.05.715-2.188.943-4.287.682-6.23-.267-2.102-.994-3.972-1.74-5.685a2.992 2.992 0 0 0-4.15-1.446c-.71.375-1.23 1-1.467 1.77a2.983 2.983 0 0 0 .218 2.292c.632 1.19 1.314 2.596 1.592 3.977.238 1.137.18 2.41-.184 3.897-.37 1.538-.976 3.143-1.522 4.518-.16.406-.33.816-.507 1.234-.507 1.215-1.032 2.47-1.364 3.838-.55 2.14-.666 4.152-.348 5.97.36 2.163 1.41 4.14 2.955 5.567 2.027 1.88 4.808 2.914 7.826 2.914 1.14 0 2.274-.146 3.375-.437l-.66-2.923"/><g fill="#bc600d"><path d="M11.585 43.742s.387 1.248.104 3.05c0 0 2.045-.466 1.898-2.27 0 0-.815-.29-2-.78M9.19 41.484S8.98 42.94 7.93 44.43c0 0 2.103.42 2.774-1.265 0 0-.696-.66-1.515-1.68M8.398 37.21s-.926 1.432-3.23 2.322c0 0 1.514 2.303 3.53.904 0 0-.237-1.388-.3-3.226M12.964 15.833s-1.685.798-3.783 3.45c0 0 2.1 1.55 4.663 2.228 0 0 .285-3.093-.88-5.677M13.5 23.873s-2.988.544-5.57 2.794c0 0 1.615 1.708 3.583 2.62 0 0 1.678-3.39 1.987-5.414M10.32 31.73s-1.483 0-4.483.812c0 0-.01 2.873 2.94 2.823 0 0 .747-1.75 1.544-3.635"/></g><g fill="#d87512"><path d="M53.33 39.37c0-4.484-35.622-4.484-35.622 0 0 10.16.05 10.25 17.81 10.25 17.762 0 17.812-.09 17.812-10.25"/><path d="M42.645 56.04c1.688 2.02 9.275.043 10.504-2.28 5.01-9.482-.006-13.58-.006-13.58l-10.5 1.313s-2.154 11.977 0 14.547"/></g><g fill="#bc600d"><path d="M54.2 41.496s-.336 4.246-4.657 9.573c0 0 4.38-1.7 5.808-4.3 0 0 .448-3.02-1.15-5.274M55.08 48.69s-1.065 1.88-3.563 3.872c0 0 1.78-.03 2.576-.785 0 0 .77-1.41.987-3.086"/></g><path fill="#f29a2e" d="M35.484 60.38c1.87 2.23 8.547 2.09 10.574 0 2.904-2.995 2.78-16.656 2.904-23.314l-12.418-1.053s-3.444 21.52-1.06 24.367"/><g fill="#bc600d"><path d="M48.21 53.53s-3.578-3.443-8.738-.013c0 0 5.754 2.455 7.365 5.672 0 0 1.126-2.245 1.373-5.66M48.775 46.06s-3.852-3.09-7.938 1.43c0 0 4.452-.47 7.632 3.635 0 0 .493-3.05.305-5.065"/></g><g fill="#3e4347"><path d="M43.847 61.57l-.397-2.765 1.344 2.445zM40.41 61.996l.502-3.294.498 3.294zM36.713 61.3l1.317-2.26-.372 2.59z"/></g><path fill="#d87512" d="M28.388 56.04c-1.688 2.02-9.277.043-10.504-2.28-5.01-9.482.004-13.58.004-13.58l10.5 1.313s2.154 11.977 0 14.547"/><g fill="#bc600d"><path d="M16.833 41.496s.336 4.246 4.657 9.573c0 0-4.38-1.7-5.807-4.3 0 0-.448-3.02 1.15-5.274M15.957 48.69s1.066 1.88 3.563 3.872c0 0-1.782-.03-2.576-.785 0 0-.772-1.41-.987-3.086"/></g><path fill="#f29a2e" d="M35.548 60.38c-1.87 2.23-8.548 2.09-10.575 0-2.904-2.995-2.78-16.656-2.904-23.314l12.417-1.053s3.446 21.52 1.06 24.367"/><g fill="#bc600d"><path d="M22.822 53.53s3.58-3.443 8.74-.013c0 0-5.754 2.455-7.367 5.672 0 0-1.125-2.245-1.373-5.66M22.255 46.06s3.852-3.09 7.94 1.43c0 0-4.453-.47-7.633 3.635 0 0-.493-3.05-.307-5.065"/></g><g fill="#3e4347"><path d="M26.24 61.25l1.345-2.445-.395 2.765zM29.62 61.996l.5-3.294.5 3.294zM33.375 61.63L33 59.04l1.32 2.26zM35.516 60.46c-.395-2.48-.482-4.96-.5-7.438.015-2.48.104-4.96.5-7.44.396 2.48.485 4.96.5 7.44-.018 2.48-.106 4.96-.5 7.438"/></g><path fill="#f29a2e" d="M27.777 6.994c0 3.82-2.727 6.987-6.086 6.915C11.83 13.7 15.893 2 15.893 2c3.36 0 11.885 1.176 11.885 4.994"/><path fill="#af5a31" d="M24.05 7.752c0 2.037-1.454 3.727-3.248 3.688-5.26-.11-3.093-6.353-3.093-6.353 1.792 0 6.34.628 6.34 2.665"/><path fill="#f29a2e" d="M43.26 6.994c0 3.82 2.726 6.987 6.086 6.915 9.86-.21 5.8-11.91 5.8-11.91C51.782 2 43.26 3.176 43.26 6.994"/><path fill="#af5a31" d="M46.983 7.752c0 2.037 1.455 3.727 3.247 3.688 5.26-.11 3.094-6.353 3.094-6.353-1.794 0-6.34.628-6.34 2.665"/><path fill="#f29a2e" d="M55.806 33.378c0 7.155-9.517 8.13-20.288 8.13-10.776 0-20.29-.975-20.29-8.13 0-29.96 11.596-29.14 20.29-29.14 8.69 0 20.288-.82 20.288 29.14"/><g fill="#3e4347"><path d="M35.54 7.59c3.24 0 6.15 1.084 8.156 2.81-.77-2.945-4.135-5.16-8.173-5.16-4.06 0-7.442 2.238-8.186 5.204 2.01-1.753 4.938-2.855 8.204-2.855"/><path d="M35.535 11.193c2.217 0 4.21.744 5.584 1.925-.528-2.02-2.835-3.534-5.6-3.534-2.78 0-5.095 1.533-5.605 3.564 1.376-1.198 3.383-1.955 5.62-1.955"/></g><path fill="#ffe8bb" d="M29.553 43.727l-18.408-7.01 4.24-9.06s2.704 3.85 13.29 6.82l.878 9.243"/><path fill="#3e4347" d="M29.37 39.77c-7.462-1.27-16.325-6.673-16.48-6.75l.992-2.168c.184.092 8.806 5.342 15.853 6.544l-.366 2.374"/><path fill="#ffe8bb" d="M41.48 43.727l18.406-7.01-4.24-9.06s-2.704 3.85-13.29 6.82l-.876 9.243"/><path fill="#3e4347" d="M41.663 39.77c7.46-1.27 16.325-6.673 16.48-6.75l-.993-2.168c-.184.092-8.808 5.342-15.852 6.544l.365 2.374"/><g fill="#ffe8bb"><path d="M43.524 45.57C38.752 42.023 41.4 33.86 41.4 33.86c-5.657 5.906-12.662 8.74-12.662 8.74 1.608 5.446 5.77 6.412 5.77 6.412-.34-1.835.663-3.302.663-3.302 1.68 2.22 5.03 2.986 5.03 2.986-1.287-1.508-.948-3.835-.948-3.835 2.326.875 4.27.71 4.27.71"/><path d="M42.29 42.97c-2.634 2.247-10.917 2.247-13.553 0-2.856-2.435-2.495-7.144.1-9.884 2.397-2.527 10.958-2.527 13.355 0 2.595 2.74 2.956 7.45.098 9.883"/></g><g fill="#3e4347"><path d="M36.18 40.48a.69.69 0 0 1-.644-.477c-.227-.67-.77-3.293-.71-5.498.01-.398.325-.71.7-.698.38.01.674.343.663.74-.057 2.01.46 4.466.633 4.974.127.375-.06.786-.414.92a.607.607 0 0 1-.23.04"/><path d="M30.504 43.25c.21-.202.394-.408.582-.61.188-.204.378-.405.57-.604.385-.396.782-.78 1.2-1.145a14.125 14.125 0 0 1 2.745-1.9c.504-.263 1.032-.49 1.59-.654s1.153-.273 1.772-.253c.31.01.623.055.928.146.307.088.602.23.86.416.263.19.485.422.652.684.17.257.287.54.35.83a4.247 4.247 0 0 0-.677-.448 2.567 2.567 0 0 0-.68-.237c-.447-.088-.887-.04-1.33.06-.89.216-1.786.65-2.69 1.114-.905.466-1.818.983-2.776 1.466-.48.24-.97.473-1.48.682-.256.103-.517.202-.783.285-.27.078-.546.155-.833.167"/></g><path fill="#f15a61" d="M41.34 31.743c-1.17-.528-4.757-.57-5.83-.57-1.07 0-4.66.042-5.83.57-.832.376-.187 1.31 2.027 2.116 1.397.506 2.733.666 3.803.666 1.07 0 2.405-.16 3.805-.667 2.213-.808 2.856-1.74 2.025-2.117"/><g fill="#3e4347"><path d="M29.917 23.48l1.61 5.292L26.954 26z"/><path d="M22.645 31.828c-.522 0-.932-.056-1.17-.098-2.986-.52-4.632-1.996-6.09-4.067l.185-2.472c1.52 1.446 3.953 3.76 6.28 4.167 1.156.2 2.853-.016 4.15-1.234 1.537-1.44 2.263-4.05 2.1-7.547l1.635.132c.2 4.312-.116 7.244-2.212 9.212-1.692 1.59-3.613 1.908-4.878 1.908M41.12 23.48l-1.613 5.292L44.08 26z"/><path d="M48.39 31.828c.52 0 .93-.056 1.167-.098 2.99-.52 4.637-1.996 6.09-4.067l-.182-2.472c-1.52 1.446-3.955 3.76-6.28 4.167-1.156.2-2.855-.016-4.154-1.234-1.532-1.44-2.258-4.05-2.095-7.547l-1.636.132c-.202 4.312.114 7.244 2.213 9.212 1.69 1.59 3.61 1.908 4.877 1.908"/></g><path fill="#ffe8bb" d="M30.25 22.09c-.852 5.282-3.728 5.87-6.696 5.577-2.986-.294-5.396-2.667-5.396-6.743 0-4.28 0-4.28 6.647-5.752 6.728-1.49 6 3.437 5.445 6.918"/><path fill="#3e4347" d="M29.16 22.547c-.244 2.534-2.61 4.357-5.287 4.072-2.674-.286-4.645-2.57-4.402-5.102s.28-2.75 5.108-2.237c4.83.514 4.824.737 4.582 3.267"/><path fill="#fff" d="M27.59 21.884c-.16 1.688-1.74 2.903-3.522 2.714-1.785-.19-3.096-1.712-2.936-3.4.163-1.69.186-1.835 3.406-1.493 3.22.344 3.215.49 3.053 2.18"/><g fill="#3e4347"><ellipse cx="25.5" cy="21.08" rx="1.45" ry="1.647"/><path d="M31.27 17.896c.42 0 .807-.284.936-.728.16-.546-.133-1.122-.65-1.29l-5.98-1.924c-.516-.166-1.065.14-1.225.685-.155.543.136 1.12.652 1.287l5.98 1.924a.95.95 0 0 0 .288.046"/></g><path fill="#ffe8bb" d="M40.78 22.09c.855 5.282 3.73 5.87 6.7 5.577 2.984-.294 5.395-2.667 5.395-6.743 0-4.28-.002-4.28-6.646-5.752-6.73-1.49-6.01 3.437-5.45 6.918"/><path fill="#3e4347" d="M41.873 22.547c.243 2.534 2.61 4.357 5.287 4.072 2.674-.286 4.646-2.57 4.402-5.102-.242-2.533-.28-2.75-5.107-2.237-4.83.514-4.824.737-4.582 3.267"/><path fill="#fff" d="M43.44 21.884c.16 1.688 1.737 2.903 3.522 2.714 1.783-.19 3.098-1.712 2.936-3.4-.16-1.69-.188-1.835-3.404-1.493-3.22.344-3.217.49-3.054 2.18"/><g fill="#3e4347"><ellipse cx="47.722" cy="20.932" rx="1.45" ry="1.647"/><path d="M39.76 17.896a.982.982 0 0 1-.935-.728c-.16-.546.132-1.122.65-1.29l5.98-1.924c.517-.166 1.063.14 1.224.685.155.543-.136 1.12-.653 1.287l-5.98 1.924a.96.96 0 0 1-.287.046"/></g></svg>
diff --git a/doc/context/sources/general/manuals/luametafun/mozilla-svg-002.svg b/doc/context/sources/general/manuals/luametafun/mozilla-svg-002.svg
new file mode 100644
index 000000000..ac49c531a
--- /dev/null
+++ b/doc/context/sources/general/manuals/luametafun/mozilla-svg-002.svg
@@ -0,0 +1,10 @@
+<svg id="glyph651" xmlns="http://www.w3.org/2000/svg"><g fill="#42cde2">
+ <path d="
+ M18.06 50.947
+ l-4.45 3.732.136-9.223
+ a.623.623 0 0 0-.146-.408
+ L11.63 42.7a.62.62 0 0 0-.873-.077
+ l-8.54 7.165
+ a.62.62 0 0 0-.076.874l1.93 2.3a.62.62 0 0 0 .875.074l3.948-3.313-.058 9.45c-.002.147.05.29.144.403l1.845 2.2a.62.62 0 0 0 .874.075l9.102-7.64a.62.62 0 0 0 .077-.874l-1.946-2.318a.623.623 0 0 0-.874-.075M36.03 33.53l-6.464 3.732 2.23-11.648a.812.812 0 0 0-.095-.548l-1.97-3.412a.8.8 0 0 0-1.09-.293l-12.41 7.166a.798.798 0 0 0-.292 1.09l1.928 3.34a.798.798 0 0 0 1.09.293l5.74-3.314-2.184 11.95a.794.794 0 0 0 .093.544l1.846 3.197a.797.797 0 0 0 1.09.29l13.234-7.637a.796.796 0 0 0 .292-1.09l-1.945-3.37a.8.8 0 0 0-1.09-.29M59.33 16.792l-7.794 2.837 4.686-12.316a.894.894 0 0 0 .003-.618l-1.497-4.114a.885.885 0 0 0-1.135-.53L38.63 7.5a.886.886 0 0 0-.53 1.136l1.466 4.03a.884.884 0 0 0 1.136.53l6.92-2.52-4.695 12.658a.888.888 0 0 0-.003.612l1.402 3.854a.888.888 0 0 0 1.137.53l15.953-5.806a.887.887 0 0 0 .53-1.137l-1.48-4.06a.887.887 0 0 0-1.136-.532"/>
+ </g>
+ </svg>
diff --git a/doc/context/sources/general/manuals/metafun/metafun-basics.tex b/doc/context/sources/general/manuals/metafun/metafun-basics.tex
index df556e239..a52c7a35a 100644
--- a/doc/context/sources/general/manuals/metafun/metafun-basics.tex
+++ b/doc/context/sources/general/manuals/metafun/metafun-basics.tex
@@ -2835,7 +2835,7 @@ eofill fullsquare rotated 45 scaled 2cm
\typebuffer
The \type {eofill} is a \METAFUN\ extension. Hopefully the next explains a bit
-how this works (you can find explanations zon the internet).
+how this works (you can find explanations on the Internet).
\startlinecorrection[blank]
\processMPbuffer