summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2018-01-12 08:12:50 +0100
committerContext Git Mirror Bot <phg42.2a@gmail.com>2018-01-12 08:12:50 +0100
commitd0edf3e90e8922d9c672f24ecdc5d44fe2716f31 (patch)
tree5b618b87aa5078a8c744c94bbf058d69cd7111b2
parent409a95f63883bd3b91699d39645e39a8a761457c (diff)
downloadcontext-d0edf3e90e8922d9c672f24ecdc5d44fe2716f31.tar.gz
2018-01-08 23:11:00
-rw-r--r--context/data/scite/context/lexers/data/scite-context-data-context.lua2
-rw-r--r--context/data/scite/context/lexers/data/scite-context-data-interfaces.lua2
-rw-r--r--context/data/scite/context/scite-context-data-context.properties195
-rw-r--r--context/data/scite/context/scite-context-data-interfaces.properties256
-rw-r--r--context/data/textadept/context/data/scite-context-data-context.lua2
-rw-r--r--context/data/textadept/context/data/scite-context-data-interfaces.lua2
-rw-r--r--doc/context/documents/general/manuals/libraries-mkiv.pdfbin0 -> 64761 bytes
-rw-r--r--doc/context/documents/general/manuals/math-mkiv.pdfbin1902409 -> 1030218 bytes
-rw-r--r--doc/context/documents/general/manuals/metafun-p.pdfbin0 -> 4638894 bytes
-rw-r--r--doc/context/documents/general/manuals/metafun-s.pdfbin0 -> 3224624 bytes
-rw-r--r--doc/context/documents/general/manuals/mkiv-publications.pdfbin544239 -> 545084 bytes
-rw-r--r--doc/context/documents/general/manuals/notnow.pdfbin0 -> 103814 bytes
-rw-r--r--doc/context/documents/general/manuals/onandon.pdfbin0 -> 2920276 bytes
-rw-r--r--doc/context/documents/general/manuals/spacing-mkiv.pdfbin39828 -> 40300 bytes
-rw-r--r--doc/context/documents/general/manuals/xtables-mkiv.pdfbin138152 -> 154883 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-cs.pdfbin840821 -> 842359 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-de.pdfbin841428 -> 842143 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-en.pdfbin845323 -> 846320 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-fr.pdfbin837455 -> 839095 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-it.pdfbin842731 -> 842517 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-cs.pdfbin0 -> 358622 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-de.pdfbin0 -> 437783 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-en.pdfbin0 -> 356309 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-fr.pdfbin0 -> 358674 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-it.pdfbin0 -> 357854 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-nl.pdfbin0 -> 357284 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-ro.pdfbin0 -> 623424 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-nl.pdfbin833540 -> 835438 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-ro.pdfbin837864 -> 838201 bytes
-rw-r--r--doc/context/presentations/bachotex/2017/bachotex-2017-emoji-demo.pdfbin0 -> 46443 bytes
-rw-r--r--doc/context/presentations/bachotex/2017/bachotex-2017-emoji-demo.tex26
-rw-r--r--doc/context/presentations/bachotex/2017/bachotex-2017-emoji.pdfbin0 -> 308972 bytes
-rw-r--r--doc/context/presentations/bachotex/2017/bachotex-2017-emoji.tex374
-rw-r--r--doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts-demo.pdfbin0 -> 219237 bytes
-rw-r--r--doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts-demo.tex44
-rw-r--r--doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts.pdfbin0 -> 251093 bytes
-rw-r--r--doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts.tex500
-rw-r--r--doc/context/scripts/mkii/ctxtools.man2
-rw-r--r--doc/context/scripts/mkii/imgtopdf.man2
-rw-r--r--doc/context/scripts/mkii/mptopdf.man2
-rw-r--r--doc/context/scripts/mkii/pdftools.man2
-rw-r--r--doc/context/scripts/mkii/pstopdf.man2
-rw-r--r--doc/context/scripts/mkii/rlxtools.man2
-rw-r--r--doc/context/scripts/mkii/texexec.man2
-rw-r--r--doc/context/scripts/mkii/texmfstart.man2
-rw-r--r--doc/context/scripts/mkii/textools.man2
-rw-r--r--doc/context/scripts/mkii/texutil.man2
-rw-r--r--doc/context/scripts/mkii/tmftools.man2
-rw-r--r--doc/context/scripts/mkii/xmltools.man2
-rw-r--r--doc/context/scripts/mkiv/context.man2
-rw-r--r--doc/context/scripts/mkiv/luatools.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-babel.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-base.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-bibtex.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-cache.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-chars.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-check.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-colors.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-context.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-dvi.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-epub.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-evohome.html3
-rw-r--r--doc/context/scripts/mkiv/mtx-evohome.man8
-rw-r--r--doc/context/scripts/mkiv/mtx-evohome.xml3
-rw-r--r--doc/context/scripts/mkiv/mtx-fcd.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-flac.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-fonts.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-grep.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-interface.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-metapost.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-metatex.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-modules.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-package.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-patterns.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-pdf.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-plain.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-profile.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-rsync.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-scite.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-server.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-texworks.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-timing.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-tools.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-unicode.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-unzip.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-update.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-watch.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-youless.html18
-rw-r--r--doc/context/scripts/mkiv/mtx-youless.man15
-rw-r--r--doc/context/scripts/mkiv/mtx-youless.xml16
-rw-r--r--doc/context/scripts/mkiv/mtxrun.man2
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-environment.tex42
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-extensions.tex86
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-features.tex82
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-mkiv.tex1
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-tricks.tex183
-rw-r--r--doc/context/sources/general/manuals/about/about-metafun.tex2
-rw-r--r--doc/context/sources/general/manuals/libraries/libraries-mkiv.tex199
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-enhancements.tex14
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-fonts.tex25
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-nodes.tex11
-rw-r--r--doc/context/sources/general/manuals/math/math-alignments.tex253
-rw-r--r--doc/context/sources/general/manuals/math/math-definitions.tex101
-rw-r--r--doc/context/sources/general/manuals/math/math-features.tex78
-rw-r--r--doc/context/sources/general/manuals/math/math-input.tex100
-rw-r--r--doc/context/sources/general/manuals/math/math-introduction.tex2
-rw-r--r--doc/context/sources/general/manuals/math/math-layout.tex9
-rw-r--r--doc/context/sources/general/manuals/math/math-mkiv.tex4
-rw-r--r--doc/context/sources/general/manuals/math/math-numbering.tex55
-rw-r--r--doc/context/sources/general/manuals/math/math-suboptimal.tex41
-rw-r--r--doc/context/sources/general/manuals/math/math-tricks.tex150
-rw-r--r--doc/context/sources/general/manuals/metafun/cow-fun.mps154
-rw-r--r--doc/context/sources/general/manuals/metafun/hacker.pngbin0 -> 60848 bytes
-rw-r--r--doc/context/sources/general/manuals/metafun/m-1.pngbin0 -> 27420 bytes
-rw-r--r--doc/context/sources/general/manuals/metafun/m-2.pngbin0 -> 1002 bytes
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-backgrounds.tex878
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-backpage.tex53
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-basics.tex3587
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-colofon-paper.tex19
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-colofon-screen.tex21
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-colofon.tex56
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-contents.tex17
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-conventions.tex117
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-debugging.tex383
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-document.tex118
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-effects.tex2596
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-embedding.tex1208
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-environment-layout.tex151
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-environment-samples.tex321
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-environment-screen.tex139
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-environment.tex595
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-examples.tex3269
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-functions.tex611
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-gadgets.tex548
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-graphics.tex21
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-index.tex25
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-introduction.tex101
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-layout.tex990
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-lua.tex1060
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-macros.tex91
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-positioning.tex1013
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-reference.tex659
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-sneaky.tex60
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-styles.tex445
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-syntax.tex1130
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-text.tex1784
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-titlepage-paper.tex23
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-titlepage-screen.tex30
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-welcome.tex3502
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun.tex108
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-700.tex17
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-771.tex9
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-772.tex9
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-773.tex9
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-774.tex103
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-775.tex9
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-776.tex9
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-800.tex27
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-900.tex48
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-901.tex11
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-902.tex11
-rw-r--r--doc/context/sources/general/manuals/metafun/mfun-mrun-demo.mp212
-rw-r--r--doc/context/sources/general/manuals/metafun/mycow.mp299
-rw-r--r--doc/context/sources/general/manuals/metafun/mycow.pdfbin0 -> 4301 bytes
-rw-r--r--doc/context/sources/general/manuals/metafun/somecow.pdfbin0 -> 3592 bytes
-rw-r--r--doc/context/sources/general/manuals/notnow/notnow-columns-and-notes.tex26
-rw-r--r--doc/context/sources/general/manuals/notnow/notnow-sidefloats.tex59
-rw-r--r--doc/context/sources/general/manuals/notnow/notnow.tex175
-rw-r--r--doc/context/sources/general/manuals/onandon/m-fonts-plugins-timings-luajittex.lua90
-rw-r--r--doc/context/sources/general/manuals/onandon/m-fonts-plugins-timings-luatex.lua90
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-decade.tex90
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-editing.tex393
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-emoji.tex457
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-ffi.tex554
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-performance.tex785
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-seguiemj.pdfbin0 -> 50494 bytes
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-seguiemj.tex54
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-speed-000.tex116
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-speed-001.tex15
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-speed-002.tex16
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-speed-003.tex15
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-speed-005.tex17
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-speed-006.tex17
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-speed-007.tex31
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-speed-008.tex32
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-speed-009.tex15
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-speed-010.tex15
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-speed-011.tex20
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-speed-012.tex20
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-variable.tex557
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon.tex54
-rw-r--r--doc/context/sources/general/manuals/publications/publications-database.tex23
-rw-r--r--doc/context/sources/general/manuals/spacing/spacing-mkiv.tex2
-rw-r--r--doc/context/sources/general/manuals/spacing/spacing-periods.tex79
-rw-r--r--doc/context/sources/general/manuals/spacing/spacing-spaces.tex236
-rw-r--r--doc/context/sources/general/manuals/spacing/spacing-style.tex9
-rw-r--r--doc/context/sources/general/manuals/xtables/xtables-mkiv.tex312
-rw-r--r--metapost/context/base/mpiv/mp-crop.mpiv22
-rw-r--r--metapost/context/base/mpiv/mp-node.mpiv144
-rw-r--r--scripts/context/lua/mtx-evohome.lua30
-rw-r--r--scripts/context/lua/mtx-fonts.lua11
-rw-r--r--scripts/context/lua/mtx-youless.lua35
-rw-r--r--scripts/context/lua/mtxrun.lua110
-rw-r--r--scripts/context/stubs/mswin/mtxrun.lua110
-rw-r--r--scripts/context/stubs/unix/mtxrun110
-rw-r--r--scripts/context/stubs/win64/mtxrun.lua110
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkii/mult-cs.mkii7
-rw-r--r--tex/context/base/mkii/mult-de.mkii10
-rw-r--r--tex/context/base/mkii/mult-en.mkii12
-rw-r--r--tex/context/base/mkii/mult-fr.mkii7
-rw-r--r--tex/context/base/mkii/mult-it.mkii12
-rw-r--r--tex/context/base/mkii/mult-pe.mkii9
-rw-r--r--tex/context/base/mkii/mult-ro.mkii12
-rw-r--r--tex/context/base/mkiv/buff-imp-parsed-xml.lua1
-rw-r--r--tex/context/base/mkiv/char-def.lua16
-rw-r--r--tex/context/base/mkiv/char-ini.lua48
-rw-r--r--tex/context/base/mkiv/char-tex.lua24
-rw-r--r--tex/context/base/mkiv/char-utf.lua1
-rw-r--r--tex/context/base/mkiv/colo-icc.lua1
-rw-r--r--tex/context/base/mkiv/colo-ini.mkiv18
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv9
-rw-r--r--tex/context/base/mkiv/core-two.lua1
-rw-r--r--tex/context/base/mkiv/data-env.lua1
-rw-r--r--tex/context/base/mkiv/data-tmp.lua1
-rw-r--r--tex/context/base/mkiv/font-agl.lua2
-rw-r--r--tex/context/base/mkiv/font-aux.lua2
-rw-r--r--tex/context/base/mkiv/font-con.lua103
-rw-r--r--tex/context/base/mkiv/font-ext.lua52
-rw-r--r--tex/context/base/mkiv/font-fbk.lua1
-rw-r--r--tex/context/base/mkiv/font-gbn.lua2
-rw-r--r--tex/context/base/mkiv/font-ini.mkvi2
-rw-r--r--tex/context/base/mkiv/font-lig.lua2
-rw-r--r--tex/context/base/mkiv/font-ocl.lua136
-rw-r--r--tex/context/base/mkiv/font-ots.lua16
-rw-r--r--tex/context/base/mkiv/font-pre.mkiv4
-rw-r--r--tex/context/base/mkiv/font-sel.lua2
-rw-r--r--tex/context/base/mkiv/font-shp.lua2
-rw-r--r--tex/context/base/mkiv/font-tra.mkiv8
-rw-r--r--tex/context/base/mkiv/grph-fig.mkiv5
-rw-r--r--tex/context/base/mkiv/grph-inc.lua27
-rw-r--r--tex/context/base/mkiv/grph-rul.lua2
-rw-r--r--tex/context/base/mkiv/l-lua.lua2
-rw-r--r--tex/context/base/mkiv/l-unicode.lua26
-rw-r--r--tex/context/base/mkiv/l-url.lua2
-rw-r--r--tex/context/base/mkiv/lang-dis.lua152
-rw-r--r--tex/context/base/mkiv/lang-exp.lua219
-rw-r--r--tex/context/base/mkiv/lang-hyp.lua53
-rw-r--r--tex/context/base/mkiv/lang-ini.lua2
-rw-r--r--tex/context/base/mkiv/lang-rep.lua2
-rw-r--r--tex/context/base/mkiv/lang-wrd.lua2
-rw-r--r--tex/context/base/mkiv/lpdf-epa.lua13
-rw-r--r--tex/context/base/mkiv/lpdf-epd.lua2
-rw-r--r--tex/context/base/mkiv/lpdf-fld.lua64
-rw-r--r--tex/context/base/mkiv/lpdf-wid.lua2
-rw-r--r--tex/context/base/mkiv/luat-cod.lua4
-rw-r--r--tex/context/base/mkiv/luat-run.lua1
-rw-r--r--tex/context/base/mkiv/lxml-sor.lua1
-rw-r--r--tex/context/base/mkiv/lxml-xml.lua2
-rw-r--r--tex/context/base/mkiv/math-act.lua49
-rw-r--r--tex/context/base/mkiv/math-fbk.lua2
-rw-r--r--tex/context/base/mkiv/math-ini.lua42
-rw-r--r--tex/context/base/mkiv/math-ini.mkiv2
-rw-r--r--tex/context/base/mkiv/meta-fnt.lua1
-rw-r--r--tex/context/base/mkiv/mlib-lua.lua18
-rw-r--r--tex/context/base/mkiv/mlib-pdf.lua4
-rw-r--r--tex/context/base/mkiv/mlib-pps.lua2
-rw-r--r--tex/context/base/mkiv/mlib-run.lua2
-rw-r--r--tex/context/base/mkiv/mult-aux.lua1
-rw-r--r--tex/context/base/mkiv/mult-def.lua43
-rw-r--r--tex/context/base/mkiv/mult-ini.lua2
-rw-r--r--tex/context/base/mkiv/mult-low.lua3
-rw-r--r--tex/context/base/mkiv/node-fnt.lua62
-rw-r--r--tex/context/base/mkiv/node-nut.lua111
-rw-r--r--tex/context/base/mkiv/node-tra.lua1
-rw-r--r--tex/context/base/mkiv/page-brk.mkiv2
-rw-r--r--tex/context/base/mkiv/page-ffl.mkiv211
-rw-r--r--tex/context/base/mkiv/page-flt.lua1
-rw-r--r--tex/context/base/mkiv/page-lay.mkiv35
-rw-r--r--tex/context/base/mkiv/page-mix.lua25
-rw-r--r--tex/context/base/mkiv/page-mix.mkiv48
-rw-r--r--tex/context/base/mkiv/page-mrk.mkiv40
-rw-r--r--tex/context/base/mkiv/page-otr.mkvi2
-rw-r--r--tex/context/base/mkiv/page-sid.mkiv89
-rw-r--r--tex/context/base/mkiv/publ-ini.lua177
-rw-r--r--tex/context/base/mkiv/scrn-wid.lua2
-rw-r--r--tex/context/base/mkiv/scrp-ini.lua2
-rw-r--r--tex/context/base/mkiv/spac-hor.mkiv6
-rw-r--r--tex/context/base/mkiv/spac-ver.mkiv75
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin25825 -> 25766 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin250644 -> 249431 bytes
-rw-r--r--tex/context/base/mkiv/strc-blk.lua2
-rw-r--r--tex/context/base/mkiv/strc-enu.mkvi3
-rw-r--r--tex/context/base/mkiv/strc-flt.mkvi102
-rw-r--r--tex/context/base/mkiv/strc-itm.mkvi13
-rw-r--r--tex/context/base/mkiv/strc-lst.lua2
-rw-r--r--tex/context/base/mkiv/strc-lst.mkvi3
-rw-r--r--tex/context/base/mkiv/strc-mat.mkiv13
-rw-r--r--tex/context/base/mkiv/strc-not.mkvi10
-rw-r--r--tex/context/base/mkiv/strc-ref.lua2
-rw-r--r--tex/context/base/mkiv/strc-reg.lua1
-rw-r--r--tex/context/base/mkiv/strc-sec.mkiv48
-rw-r--r--tex/context/base/mkiv/strc-syn.mkiv24
-rw-r--r--tex/context/base/mkiv/supp-box.lua2
-rw-r--r--tex/context/base/mkiv/supp-box.mkiv3
-rw-r--r--tex/context/base/mkiv/syst-aux.lua2
-rw-r--r--tex/context/base/mkiv/syst-ini.mkiv5
-rw-r--r--tex/context/base/mkiv/tabl-mis.mkiv13
-rw-r--r--tex/context/base/mkiv/tabl-tbl.mkiv21
-rw-r--r--tex/context/base/mkiv/tabl-xtb.lua70
-rw-r--r--tex/context/base/mkiv/tabl-xtb.mkvi65
-rw-r--r--tex/context/base/mkiv/task-ini.lua2
-rw-r--r--tex/context/base/mkiv/toks-ini.lua1
-rw-r--r--tex/context/base/mkiv/trac-ctx.lua2
-rw-r--r--tex/context/base/mkiv/trac-fil.lua2
-rw-r--r--tex/context/base/mkiv/trac-lmx.lua2
-rw-r--r--tex/context/base/mkiv/trac-pro.lua2
-rw-r--r--tex/context/base/mkiv/trac-vis.lua206
-rw-r--r--tex/context/base/mkiv/typo-dir.mkiv2
-rw-r--r--tex/context/base/mkiv/typo-krn.lua28
-rw-r--r--tex/context/base/mkiv/typo-pnc.lua169
-rw-r--r--tex/context/base/mkiv/typo-pnc.mkiv55
-rw-r--r--tex/context/base/mkiv/typo-sus.lua2
-rw-r--r--tex/context/base/mkiv/typo-tal.lua128
-rw-r--r--tex/context/base/mkiv/typo-tal.mkiv111
-rw-r--r--tex/context/base/mkiv/util-evo-imp-server.lua127
-rw-r--r--tex/context/base/mkiv/util-evo.lua847
-rw-r--r--tex/context/base/mkiv/util-jsn.lua2
-rw-r--r--tex/context/base/mkiv/util-prs.lua12
-rw-r--r--tex/context/base/mkiv/util-str.lua129
-rw-r--r--tex/context/base/mkiv/util-tpl.lua2
-rw-r--r--tex/context/base/mkiv/util-you.lua327
-rw-r--r--tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv4
-rw-r--r--tex/context/interface/mkii/keys-cs.xml7
-rw-r--r--tex/context/interface/mkii/keys-de.xml10
-rw-r--r--tex/context/interface/mkii/keys-en.xml12
-rw-r--r--tex/context/interface/mkii/keys-fr.xml7
-rw-r--r--tex/context/interface/mkii/keys-it.xml12
-rw-r--r--tex/context/interface/mkii/keys-pe.xml9
-rw-r--r--tex/context/interface/mkii/keys-ro.xml12
-rw-r--r--tex/context/interface/mkiv/context-en.xml13
-rw-r--r--tex/context/interface/mkiv/i-backend.xml2
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin845323 -> 846320 bytes
-rw-r--r--tex/context/interface/mkiv/i-floats.xml10
-rw-r--r--tex/context/interface/mkiv/i-initial.xml4
-rw-r--r--tex/context/interface/mkiv/i-itemgroup.xml3
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin60775 -> 60774 bytes
-rw-r--r--tex/context/interface/mkiv/i-section.xml1
-rw-r--r--tex/context/interface/mkiv/i-strut.xml4
-rw-r--r--tex/context/interface/mkiv/i-todo.xml21
-rw-r--r--tex/context/modules/mkiv/m-timing.mkiv2
-rw-r--r--tex/context/modules/mkiv/m-typesetting.mkiv92
-rw-r--r--tex/context/modules/mkiv/s-evohome.mkiv24
-rw-r--r--tex/context/modules/mkiv/s-fonts-ligatures.mkiv4
-rw-r--r--tex/context/modules/mkiv/s-fonts-variable.mkiv12
-rw-r--r--tex/context/modules/mkiv/s-youless.mkiv228
-rw-r--r--tex/context/modules/mkiv/x-asciimath.lua2
-rw-r--r--tex/context/modules/mkiv/x-calcmath.lua1
-rw-r--r--tex/context/modules/mkiv/x-cals.lua2
-rw-r--r--tex/context/modules/mkiv/x-setups-basics.mkiv143
-rw-r--r--tex/context/modules/mkiv/x-setups-overview.mkiv67
-rw-r--r--tex/generic/context/luatex/luatex-core.lua46
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua186
-rw-r--r--tex/generic/context/luatex/luatex-mplib.lua211
-rw-r--r--tex/generic/context/luatex/luatex-swiglib.lua8
367 files changed, 38371 insertions, 2235 deletions
diff --git a/context/data/scite/context/lexers/data/scite-context-data-context.lua b/context/data/scite/context/lexers/data/scite-context-data-context.lua
index c58767270..2cba8b9d0 100644
--- a/context/data/scite/context/lexers/data/scite-context-data-context.lua
+++ b/context/data/scite/context/lexers/data/scite-context-data-context.lua
@@ -1,4 +1,4 @@
return {
["constants"]={ "zerocount", "minusone", "minustwo", "plusone", "plustwo", "plusthree", "plusfour", "plusfive", "plussix", "plusseven", "pluseight", "plusnine", "plusten", "plussixteen", "plushundred", "plustwohundred", "plusthousand", "plustenthousand", "plustwentythousand", "medcard", "maxcard", "maxcardminusone", "zeropoint", "onepoint", "halfapoint", "onebasepoint", "maxcount", "maxdimen", "scaledpoint", "thousandpoint", "points", "halfpoint", "zeroskip", "zeromuskip", "onemuskip", "pluscxxvii", "pluscxxviii", "pluscclv", "pluscclvi", "normalpagebox", "endoflinetoken", "outputnewlinechar", "emptytoks", "empty", "undefined", "voidbox", "emptybox", "emptyvbox", "emptyhbox", "bigskipamount", "medskipamount", "smallskipamount", "fmtname", "fmtversion", "texengine", "texenginename", "texengineversion", "texenginefunctionality", "luatexengine", "pdftexengine", "xetexengine", "unknownengine", "activecatcode", "bgroup", "egroup", "endline", "conditionaltrue", "conditionalfalse", "attributeunsetvalue", "uprotationangle", "rightrotationangle", "downrotationangle", "leftrotationangle", "inicatcodes", "ctxcatcodes", "texcatcodes", "notcatcodes", "txtcatcodes", "vrbcatcodes", "prtcatcodes", "nilcatcodes", "luacatcodes", "tpacatcodes", "tpbcatcodes", "xmlcatcodes", "ctdcatcodes", "escapecatcode", "begingroupcatcode", "endgroupcatcode", "mathshiftcatcode", "alignmentcatcode", "endoflinecatcode", "parametercatcode", "superscriptcatcode", "subscriptcatcode", "ignorecatcode", "spacecatcode", "lettercatcode", "othercatcode", "activecatcode", "commentcatcode", "invalidcatcode", "tabasciicode", "newlineasciicode", "formfeedasciicode", "endoflineasciicode", "endoffileasciicode", "spaceasciicode", "hashasciicode", "dollarasciicode", "commentasciicode", "ampersandasciicode", "colonasciicode", "backslashasciicode", "circumflexasciicode", "underscoreasciicode", "leftbraceasciicode", "barasciicode", "rightbraceasciicode", "tildeasciicode", "delasciicode", "lessthanasciicode", "morethanasciicode", "doublecommentsignal", "atsignasciicode", "exclamationmarkasciicode", "questionmarkasciicode", "doublequoteasciicode", "singlequoteasciicode", "forwardslashasciicode", "primeasciicode", "hyphenasciicode", "activemathcharcode", "activetabtoken", "activeformfeedtoken", "activeendoflinetoken", "batchmodecode", "nonstopmodecode", "scrollmodecode", "errorstopmodecode", "bottomlevelgroupcode", "simplegroupcode", "hboxgroupcode", "adjustedhboxgroupcode", "vboxgroupcode", "vtopgroupcode", "aligngroupcode", "noaligngroupcode", "outputgroupcode", "mathgroupcode", "discretionarygroupcode", "insertgroupcode", "vcentergroupcode", "mathchoicegroupcode", "semisimplegroupcode", "mathshiftgroupcode", "mathleftgroupcode", "vadjustgroupcode", "charnodecode", "hlistnodecode", "vlistnodecode", "rulenodecode", "insertnodecode", "marknodecode", "adjustnodecode", "ligaturenodecode", "discretionarynodecode", "whatsitnodecode", "mathnodecode", "gluenodecode", "kernnodecode", "penaltynodecode", "unsetnodecode", "mathsnodecode", "charifcode", "catifcode", "numifcode", "dimifcode", "oddifcode", "vmodeifcode", "hmodeifcode", "mmodeifcode", "innerifcode", "voidifcode", "hboxifcode", "vboxifcode", "xifcode", "eofifcode", "trueifcode", "falseifcode", "caseifcode", "definedifcode", "csnameifcode", "fontcharifcode", "fontslantperpoint", "fontinterwordspace", "fontinterwordstretch", "fontinterwordshrink", "fontexheight", "fontemwidth", "fontextraspace", "slantperpoint", "mathexheight", "mathemwidth", "interwordspace", "interwordstretch", "interwordshrink", "exheight", "emwidth", "extraspace", "mathsupdisplay", "mathsupnormal", "mathsupcramped", "mathsubnormal", "mathsubcombined", "mathaxisheight", "muquad", "startmode", "stopmode", "startnotmode", "stopnotmode", "startmodeset", "stopmodeset", "doifmode", "doifelsemode", "doifmodeelse", "doifnotmode", "startmodeset", "stopmodeset", "startallmodes", "stopallmodes", "startnotallmodes", "stopnotallmodes", "doifallmodes", "doifelseallmodes", "doifallmodeselse", "doifnotallmodes", "startenvironment", "stopenvironment", "environment", "startcomponent", "stopcomponent", "component", "startproduct", "stopproduct", "product", "startproject", "stopproject", "project", "starttext", "stoptext", "startnotext", "stopnotext", "startdocument", "stopdocument", "documentvariable", "unexpandeddocumentvariable", "setupdocument", "presetdocument", "startmodule", "stopmodule", "usemodule", "usetexmodule", "useluamodule", "setupmodule", "currentmoduleparameter", "moduleparameter", "everystarttext", "everystoptext", "startTEXpage", "stopTEXpage", "enablemode", "disablemode", "preventmode", "definemode", "globalenablemode", "globaldisablemode", "globalpreventmode", "pushmode", "popmode", "typescriptone", "typescripttwo", "typescriptthree", "mathsizesuffix", "mathordcode", "mathopcode", "mathbincode", "mathrelcode", "mathopencode", "mathclosecode", "mathpunctcode", "mathalphacode", "mathinnercode", "mathnothingcode", "mathlimopcode", "mathnolopcode", "mathboxcode", "mathchoicecode", "mathaccentcode", "mathradicalcode", "constantnumber", "constantnumberargument", "constantdimen", "constantdimenargument", "constantemptyargument", "continueifinputfile", "luastringsep", "!!bs", "!!es", "lefttorightmark", "righttoleftmark", "breakablethinspace", "nobreakspace", "nonbreakablespace", "narrownobreakspace", "zerowidthnobreakspace", "ideographicspace", "ideographichalffillspace", "twoperemspace", "threeperemspace", "fourperemspace", "fiveperemspace", "sixperemspace", "figurespace", "punctuationspace", "hairspace", "zerowidthspace", "zerowidthnonjoiner", "zerowidthjoiner", "zwnj", "zwj", "optionalspace", "asciispacechar", "Ux", "eUx", "Umathaccents", "parfillleftskip", "parfillrightskip" },
- ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", "startcontextdefinitioncode", "stopcontextdefinitioncode", "texdefinition", "doifelsesetups", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "fastsetup", "doifelsecommandhandler", "doifcommandhandlerelse", "doifnotcommandhandler", "doifcommandhandler", "newmode", "setmode", "resetmode", "newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode", "booleanmodevalue", "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif", "newlanguage", "newfamily", "newfam", "newhelp", "then", "begcsname", "strippedcsname", "checkedstrippedcsname", "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", "fifthargumentfalse", "fifthsargumenttrue", "sixthargumentfalse", "sixtsargumenttrue", "doglobal", "dodoglobal", "redoglobal", "resetglobal", "donothing", "dontcomplain", "forgetall", "donetrue", "donefalse", "foundtrue", "foundfalse", "inlineordisplaymath", "indisplaymath", "forcedisplaymath", "startforceddisplaymath", "stopforceddisplaymath", "reqno", "mathortext", "htdp", "unvoidbox", "hfilll", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledmbox", "ruledhpack", "ruledvpack", "ruledtpack", "ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", "scratchcounter", "globalscratchcounter", "privatescratchcounter", "scratchdimen", "globalscratchdimen", "privatescratchdimen", "scratchskip", "globalscratchskip", "privatescratchskip", "scratchmuskip", "globalscratchmuskip", "privatescratchmuskip", "scratchtoks", "globalscratchtoks", "privatescratchtoks", "scratchbox", "globalscratchbox", "privatescratchbox", "normalbaselineskip", "normallineskip", "normallineskiplimit", "availablehsize", "localhsize", "setlocalhsize", "distributedhsize", "hsizefraction", "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "flushnextbox", "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchhsize", "scratchvsize", "scratchxoffset", "scratchyoffset", "scratchhoffset", "scratchvoffset", "scratchxposition", "scratchyposition", "scratchtopoffset", "scratchbottomoffset", "scratchleftoffset", "scratchrightoffset", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchcounterfour", "scratchcounterfive", "scratchcountersix", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchdimenfour", "scratchdimenfive", "scratchdimensix", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchskipfour", "scratchskipfive", "scratchskipsix", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchmuskipfour", "scratchmuskipfive", "scratchmuskipsix", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchtoksfour", "scratchtoksfive", "scratchtokssix", "scratchboxone", "scratchboxtwo", "scratchboxthree", "scratchboxfour", "scratchboxfive", "scratchboxsix", "scratchnx", "scratchny", "scratchmx", "scratchmy", "scratchunicode", "scratchmin", "scratchmax", "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", "doif", "doifnot", "doifelse", "doifinset", "doifnotinset", "doifelseinset", "doifinsetelse", "doifelsenextchar", "doifnextcharelse", "doifelsenextoptional", "doifnextoptionalelse", "doifelsenextoptionalcs", "doifnextoptionalcselse", "doifelsefastoptionalcheck", "doiffastoptionalcheckelse", "doifelsenextbgroup", "doifnextbgroupelse", "doifelsenextbgroupcs", "doifnextbgroupcselse", "doifelsenextparenthesis", "doifnextparenthesiselse", "doifelseundefined", "doifundefinedelse", "doifelsedefined", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifnothingelse", "doifelsesomething", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifvaluenothingelse", "doifelsedimension", "doifdimensionelse", "doifelsenumber", "doifnumberelse", "doifnumber", "doifnotnumber", "doifelsecommon", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifelseinstring", "doifinstringelse", "doifelseassignment", "doifassignmentelse", "docheckassignment", "doiftext", "doifelsetext", "doiftextelse", "doifnottext", "tracingall", "tracingnone", "loggingall", "removetoks", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "endpar", "everyendpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "emspace", "charspace", "nbsp", "crlf", "obeyspaces", "obeylines", "obeyedspace", "obeyedline", "obeyedtab", "obeyedpage", "normalspace", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", "removepunctuation", "wait", "writestatus", "define", "defineexpandable", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", "measured", "installcorenamespace", "getvalue", "getuvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "glet", "udef", "ugdef", "uedef", "uxdef", "checked", "unique", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "getdummyparameters", "dummyparameter", "directdummyparameter", "setdummyparameter", "letdummyparameter", "usedummystyleandcolor", "usedummystyleparameter", "usedummycolorparameter", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protected", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "firstoftwounexpanded", "secondoftwounexpanded", "firstofthreeunexpanded", "secondofthreeunexpanded", "thirdofthreeunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "fastloopindex", "fastloopfinal", "dowith", "newconstant", "setnewconstant", "setconstant", "setconstantvalue", "newconditional", "settrue", "setfalse", "settruevalue", "setfalsevalue", "newmacro", "setnewmacro", "newfraction", "newsignal", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "doquintupleargument", "dosixtupleargument", "doseventupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doifelsefirstchar", "doiffirstcharelse", "startnointerference", "stopnointerference", "twodigits", "threedigits", "leftorright", "offinterlineskip", "oninterlineskip", "nointerlineskip", "strut", "halfstrut", "quarterstrut", "depthstrut", "halflinestrut", "noheightstrut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "begstrut", "endstrut", "lineheight", "leftboundary", "rightboundary", "signalcharacter", "ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing", "ordopenspacing", "ordclosespacing", "ordpunctspacing", "ordinnerspacing", "opordspacing", "opopspacing", "opbinspacing", "oprelspacing", "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing", "binordspacing", "binopspacing", "binbinspacing", "binrelspacing", "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing", "relordspacing", "relopspacing", "relbinspacing", "relrelspacing", "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing", "openordspacing", "openopspacing", "openbinspacing", "openrelspacing", "openopenspacing", "openclosespacing", "openpunctspacing", "openinnerspacing", "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing", "closeopenspacing", "closeclosespacing", "closepunctspacing", "closeinnerspacing", "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing", "punctopenspacing", "punctclosespacing", "punctpunctspacing", "punctinnerspacing", "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing", "inneropenspacing", "innerclosespacing", "innerpunctspacing", "innerinnerspacing", "normalreqno", "startimath", "stopimath", "normalstartimath", "normalstopimath", "startdmath", "stopdmath", "normalstartdmath", "normalstopdmath", "normalsuperscript", "normalsubscript", "normalnosuperscript", "normalnosubscript", "superscript", "subscript", "nosuperscript", "nosubscript", "uncramped", "cramped", "triggermathstyle", "mathstylefont", "mathsmallstylefont", "mathstyleface", "mathsmallstyleface", "mathstylecommand", "mathpalette", "mathstylehbox", "mathstylevbox", "mathstylevcenter", "mathstylevcenteredhbox", "mathstylevcenteredvbox", "mathtext", "setmathsmalltextbox", "setmathtextbox", "pushmathstyle", "popmathstyle", "triggerdisplaystyle", "triggertextstyle", "triggerscriptstyle", "triggerscriptscriptstyle", "triggeruncrampedstyle", "triggercrampedstyle", "triggersmallstyle", "triggeruncrampedsmallstyle", "triggercrampedsmallstyle", "triggerbigstyle", "triggeruncrampedbigstyle", "triggercrampedbigstyle", "luaexpr", "expelsedoif", "expdoif", "expdoifnot", "expdoifelsecommon", "expdoifcommonelse", "expdoifelseinset", "expdoifinsetelse", "ctxdirectlua", "ctxlatelua", "ctxsprint", "ctxwrite", "ctxcommand", "ctxdirectcommand", "ctxlatecommand", "ctxreport", "ctxlua", "luacode", "lateluacode", "directluacode", "registerctxluafile", "ctxloadluafile", "luaversion", "luamajorversion", "luaminorversion", "ctxluacode", "luaconditional", "luaexpanded", "startluaparameterset", "stopluaparameterset", "luaparameterset", "definenamedlua", "obeylualines", "obeyluatokens", "startluacode", "stopluacode", "startlua", "stoplua", "startctxfunction", "stopctxfunction", "ctxfunction", "startctxfunctiondefinition", "stopctxfunctiondefinition", "installctxfunction", "cldprocessfile", "cldloadfile", "cldcontext", "cldcommand", "carryoverpar", "lastlinewidth", "assumelongusagecs", "Umathbotaccent", "righttolefthbox", "lefttorighthbox", "righttoleftvbox", "lefttorightvbox", "righttoleftvtop", "lefttorightvtop", "rtlhbox", "ltrhbox", "rtlvbox", "ltrvbox", "rtlvtop", "ltrvtop", "autodirhbox", "autodirvbox", "autodirvtop", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "lefttoright", "righttoleft", "synchronizelayoutdirection", "synchronizedisplaydirection", "synchronizeinlinedirection", "lesshyphens", "morehyphens", "nohyphens", "dohyphens", "Ucheckedstartdisplaymath", "Ucheckedstopdisplaymath", "break", "nobreak", "allowbreak", "goodbreak", "nospace", "nospacing", "dospacing", "naturalhbox", "naturalvbox", "naturalhpack", "naturalvpack", "frule", "compoundhyphenpenalty", "start", "stop" },
+ ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", "startcontextdefinitioncode", "stopcontextdefinitioncode", "texdefinition", "doifelsesetups", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "fastsetup", "doifelsecommandhandler", "doifcommandhandlerelse", "doifnotcommandhandler", "doifcommandhandler", "newmode", "setmode", "resetmode", "newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode", "booleanmodevalue", "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif", "newlanguage", "newfamily", "newfam", "newhelp", "then", "begcsname", "strippedcsname", "checkedstrippedcsname", "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", "fifthargumentfalse", "fifthsargumenttrue", "sixthargumentfalse", "sixtsargumenttrue", "doglobal", "dodoglobal", "redoglobal", "resetglobal", "donothing", "dontcomplain", "forgetall", "donetrue", "donefalse", "foundtrue", "foundfalse", "inlineordisplaymath", "indisplaymath", "forcedisplaymath", "startforceddisplaymath", "stopforceddisplaymath", "reqno", "mathortext", "htdp", "unvoidbox", "hfilll", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledmbox", "ruledhpack", "ruledvpack", "ruledtpack", "ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", "scratchcounter", "globalscratchcounter", "privatescratchcounter", "scratchdimen", "globalscratchdimen", "privatescratchdimen", "scratchskip", "globalscratchskip", "privatescratchskip", "scratchmuskip", "globalscratchmuskip", "privatescratchmuskip", "scratchtoks", "globalscratchtoks", "privatescratchtoks", "scratchbox", "globalscratchbox", "privatescratchbox", "normalbaselineskip", "normallineskip", "normallineskiplimit", "availablehsize", "localhsize", "setlocalhsize", "distributedhsize", "hsizefraction", "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "flushnextbox", "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchhsize", "scratchvsize", "scratchxoffset", "scratchyoffset", "scratchhoffset", "scratchvoffset", "scratchxposition", "scratchyposition", "scratchtopoffset", "scratchbottomoffset", "scratchleftoffset", "scratchrightoffset", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchcounterfour", "scratchcounterfive", "scratchcountersix", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchdimenfour", "scratchdimenfive", "scratchdimensix", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchskipfour", "scratchskipfive", "scratchskipsix", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchmuskipfour", "scratchmuskipfive", "scratchmuskipsix", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchtoksfour", "scratchtoksfive", "scratchtokssix", "scratchboxone", "scratchboxtwo", "scratchboxthree", "scratchboxfour", "scratchboxfive", "scratchboxsix", "scratchnx", "scratchny", "scratchmx", "scratchmy", "scratchunicode", "scratchmin", "scratchmax", "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", "doif", "doifnot", "doifelse", "doifinset", "doifnotinset", "doifelseinset", "doifinsetelse", "doifelsenextchar", "doifnextcharelse", "doifelsenextoptional", "doifnextoptionalelse", "doifelsenextoptionalcs", "doifnextoptionalcselse", "doifelsefastoptionalcheck", "doiffastoptionalcheckelse", "doifelsefastoptionalcheckcs", "doiffastoptionalcheckcselse", "doifelsenextbgroup", "doifnextbgroupelse", "doifelsenextbgroupcs", "doifnextbgroupcselse", "doifelsenextparenthesis", "doifnextparenthesiselse", "doifelseundefined", "doifundefinedelse", "doifelsedefined", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifnothingelse", "doifelsesomething", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifvaluenothingelse", "doifelsedimension", "doifdimensionelse", "doifelsenumber", "doifnumberelse", "doifnumber", "doifnotnumber", "doifelsecommon", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifelseinstring", "doifinstringelse", "doifelseassignment", "doifassignmentelse", "docheckassignment", "doiftext", "doifelsetext", "doiftextelse", "doifnottext", "tracingall", "tracingnone", "loggingall", "removetoks", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "endpar", "everyendpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "emspace", "charspace", "nbsp", "crlf", "obeyspaces", "obeylines", "obeyedspace", "obeyedline", "obeyedtab", "obeyedpage", "normalspace", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", "removepunctuation", "wait", "writestatus", "define", "defineexpandable", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", "measured", "installcorenamespace", "getvalue", "getuvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "glet", "udef", "ugdef", "uedef", "uxdef", "checked", "unique", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "getdummyparameters", "dummyparameter", "directdummyparameter", "setdummyparameter", "letdummyparameter", "usedummystyleandcolor", "usedummystyleparameter", "usedummycolorparameter", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protected", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "firstoftwounexpanded", "secondoftwounexpanded", "firstofthreeunexpanded", "secondofthreeunexpanded", "thirdofthreeunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "fastloopindex", "fastloopfinal", "dowith", "newconstant", "setnewconstant", "setconstant", "setconstantvalue", "newconditional", "settrue", "setfalse", "settruevalue", "setfalsevalue", "newmacro", "setnewmacro", "newfraction", "newsignal", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "doquintupleargument", "dosixtupleargument", "doseventupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doifelsefirstchar", "doiffirstcharelse", "startnointerference", "stopnointerference", "twodigits", "threedigits", "leftorright", "offinterlineskip", "oninterlineskip", "nointerlineskip", "strut", "halfstrut", "quarterstrut", "depthstrut", "halflinestrut", "noheightstrut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "strutgap", "begstrut", "endstrut", "lineheight", "leftboundary", "rightboundary", "signalcharacter", "ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing", "ordopenspacing", "ordclosespacing", "ordpunctspacing", "ordinnerspacing", "opordspacing", "opopspacing", "opbinspacing", "oprelspacing", "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing", "binordspacing", "binopspacing", "binbinspacing", "binrelspacing", "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing", "relordspacing", "relopspacing", "relbinspacing", "relrelspacing", "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing", "openordspacing", "openopspacing", "openbinspacing", "openrelspacing", "openopenspacing", "openclosespacing", "openpunctspacing", "openinnerspacing", "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing", "closeopenspacing", "closeclosespacing", "closepunctspacing", "closeinnerspacing", "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing", "punctopenspacing", "punctclosespacing", "punctpunctspacing", "punctinnerspacing", "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing", "inneropenspacing", "innerclosespacing", "innerpunctspacing", "innerinnerspacing", "normalreqno", "startimath", "stopimath", "normalstartimath", "normalstopimath", "startdmath", "stopdmath", "normalstartdmath", "normalstopdmath", "normalsuperscript", "normalsubscript", "normalnosuperscript", "normalnosubscript", "superscript", "subscript", "nosuperscript", "nosubscript", "uncramped", "cramped", "triggermathstyle", "mathstylefont", "mathsmallstylefont", "mathstyleface", "mathsmallstyleface", "mathstylecommand", "mathpalette", "mathstylehbox", "mathstylevbox", "mathstylevcenter", "mathstylevcenteredhbox", "mathstylevcenteredvbox", "mathtext", "setmathsmalltextbox", "setmathtextbox", "pushmathstyle", "popmathstyle", "triggerdisplaystyle", "triggertextstyle", "triggerscriptstyle", "triggerscriptscriptstyle", "triggeruncrampedstyle", "triggercrampedstyle", "triggersmallstyle", "triggeruncrampedsmallstyle", "triggercrampedsmallstyle", "triggerbigstyle", "triggeruncrampedbigstyle", "triggercrampedbigstyle", "luaexpr", "expelsedoif", "expdoif", "expdoifnot", "expdoifelsecommon", "expdoifcommonelse", "expdoifelseinset", "expdoifinsetelse", "ctxdirectlua", "ctxlatelua", "ctxsprint", "ctxwrite", "ctxcommand", "ctxdirectcommand", "ctxlatecommand", "ctxreport", "ctxlua", "luacode", "lateluacode", "directluacode", "registerctxluafile", "ctxloadluafile", "luaversion", "luamajorversion", "luaminorversion", "ctxluacode", "luaconditional", "luaexpanded", "startluaparameterset", "stopluaparameterset", "luaparameterset", "definenamedlua", "obeylualines", "obeyluatokens", "startluacode", "stopluacode", "startlua", "stoplua", "startctxfunction", "stopctxfunction", "ctxfunction", "startctxfunctiondefinition", "stopctxfunctiondefinition", "installctxfunction", "cldprocessfile", "cldloadfile", "cldcontext", "cldcommand", "carryoverpar", "lastlinewidth", "assumelongusagecs", "Umathbotaccent", "righttolefthbox", "lefttorighthbox", "righttoleftvbox", "lefttorightvbox", "righttoleftvtop", "lefttorightvtop", "rtlhbox", "ltrhbox", "rtlvbox", "ltrvbox", "rtlvtop", "ltrvtop", "autodirhbox", "autodirvbox", "autodirvtop", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "lefttoright", "righttoleft", "synchronizelayoutdirection", "synchronizedisplaydirection", "synchronizeinlinedirection", "lesshyphens", "morehyphens", "nohyphens", "dohyphens", "Ucheckedstartdisplaymath", "Ucheckedstopdisplaymath", "break", "nobreak", "allowbreak", "goodbreak", "nospace", "nospacing", "dospacing", "naturalhbox", "naturalvbox", "naturalhpack", "naturalvpack", "frule", "compoundhyphenpenalty", "start", "stop" },
} \ No newline at end of file
diff --git a/context/data/scite/context/lexers/data/scite-context-data-interfaces.lua b/context/data/scite/context/lexers/data/scite-context-data-interfaces.lua
index 97c4d0014..a848e923d 100644
--- a/context/data/scite/context/lexers/data/scite-context-data-interfaces.lua
+++ b/context/data/scite/context/lexers/data/scite-context-data-interfaces.lua
@@ -1,5 +1,5 @@
return {
- ["common"]={ "AEacute", "AEligature", "AEmacron", "AMSTEX", "Aacute", "Abreve", "Abreveacute", "Abrevedotbelow", "Abrevegrave", "Abrevehook", "Abrevetilde", "Acaron", "Acircumflex", "Acircumflexacute", "Acircumflexdotbelow", "Acircumflexgrave", "Acircumflexhook", "Acircumflextilde", "Adiaeresis", "Adiaeresismacron", "Adotaccent", "Adotaccentmacron", "Adotbelow", "Adoublegrave", "AfterPar", "Agrave", "Ahook", "Ainvertedbreve", "Alpha", "Alphabeticnumerals", "AmSTeX", "Amacron", "And", "Angstrom", "Aogonek", "Aring", "Aringacute", "Arrowvert", "Astroke", "Atilde", "BeforePar", "Beta", "Bhook", "Big", "Bigg", "Biggl", "Biggm", "Biggr", "Bigl", "Bigm", "Bigr", "Box", "Bumpeq", "CONTEXT", "Cacute", "Cap", "Caps", "Ccaron", "Ccedilla", "Ccircumflex", "Cdotaccent", "Character", "Characters", "Chi", "Chook", "ConTeXt", "Context", "ConvertConstantAfter", "ConvertToConstant", "Cstroke", "Cup", "DZcaronligature", "DZligature", "Dafrican", "Dcaron", "Ddownarrow", "Delta", "Dhook", "Doteq", "Downarrow", "Dstroke", "Dzcaronligature", "Dzligature", "ETEX", "Eacute", "Ebreve", "Ecaron", "Ecedilla", "Ecircumflex", "Ecircumflexacute", "Ecircumflexdotbelow", "Ecircumflexgrave", "Ecircumflexhook", "Ecircumflextilde", "Ediaeresis", "Edotaccent", "Edotbelow", "Edoublegrave", "Egrave", "Ehook", "Einvertedbreve", "Emacron", "Eogonek", "Epsilon", "Eta", "Eth", "Etilde", "Eulerconst", "EveryLine", "EveryPar", "Fhook", "Finv", "Gacute", "Game", "Gamma", "Gbreve", "Gcaron", "Gcircumflex", "Gcommaaccent", "Gdotaccent", "GetPar", "Ghook", "GotoPar", "Greeknumerals", "Gstroke", "Hat", "Hcaron", "Hcircumflex", "Hstroke", "IJligature", "INRSTEX", "Iacute", "Ibreve", "Icaron", "Icircumflex", "Idiaeresis", "Idotaccent", "Idotbelow", "Idoublegrave", "Igrave", "Ihook", "Iinvertedbreve", "Im", "Imacron", "Iogonek", "Iota", "Istroke", "Itilde", "Jcircumflex", "Join", "Kappa", "Kcaron", "Kcommaaccent", "Khook", "LAMSTEX", "LATEX", "LJligature", "LUAJITTEX", "LUATEX", "LaTeX", "Lacute", "LamSTeX", "Lambda", "Lbar", "Lcaron", "Lcommaaccent", "Ldotmiddle", "Ldsh", "Leftarrow", "Leftrightarrow", "Ljligature", "Lleftarrow", "Longleftarrow", "Longleftrightarrow", "Longmapsfrom", "Longmapsto", "Longrightarrow", "Lsh", "Lstroke", "Lua", "LuaTeX", "LuajitTeX", "METAFONT", "METAFUN", "METAPOST", "MKII", "MKIV", "MKIX", "MKVI", "MKXI", "MONTH", "MONTHLONG", "MONTHSHORT", "MPII", "MPIV", "MPVI", "MPanchor", "MPbetex", "MPc", "MPcode", "MPcolor", "MPcoloronly", "MPcolumn", "MPd", "MPdrawing", "MPfontsizehskip", "MPgetmultipars", "MPgetmultishape", "MPgetposboxes", "MPh", "MPinclusions", "MPleftskip", "MPll", "MPlr", "MPls", "MPmenubuttons", "MPn", "MPoptions", "MPoverlayanchor", "MPp", "MPpage", "MPpardata", "MPplus", "MPpos", "MPpositiongraphic", "MPposset", "MPr", "MPrawvar", "MPregion", "MPrest", "MPrightskip", "MPrs", "MPstring", "MPtext", "MPtransparency", "MPul", "MPur", "MPv", "MPvar", "MPvariable", "MPvv", "MPw", "MPwhd", "MPx", "MPxy", "MPxywhd", "MPy", "Mapsfrom", "Mapsto", "MetaFont", "MetaFun", "MetaPost", "Mu", "NJligature", "Nacute", "Ncaron", "Ncommaaccent", "Nearrow", "Neng", "Ngrave", "Njligature", "NormalizeFontHeight", "NormalizeFontWidth", "NormalizeTextHeight", "NormalizeTextWidth", "Ntilde", "Nu", "Numbers", "Nwarrow", "OEligature", "Oacute", "Obreve", "Ocaron", "Ocircumflex", "Ocircumflexacute", "Ocircumflexdotbelow", "Ocircumflexgrave", "Ocircumflexhook", "Ocircumflextilde", "Odiaeresis", "Odiaeresismacron", "Odotaccent", "Odotaccentmacron", "Odotbelow", "Odoublegrave", "Ograve", "Ohook", "Ohorn", "Ohornacute", "Ohorndotbelow", "Ohorngrave", "Ohornhook", "Ohorntilde", "Ohungarumlaut", "Oinvertedbreve", "Omacron", "Omega", "Omicron", "Oogonek", "Oogonekmacron", "Ostroke", "Ostrokeacute", "Otilde", "Otildemacron", "P", "PDFETEX", "PDFTEX", "PDFcolor", "PICTEX", "PPCHTEX", "PPCHTeX", "PRAGMA", "Phi", "Phook", "Pi", "PiCTeX", "Plankconst", "PointsToBigPoints", "PointsToReal", "PointsToWholeBigPoints", "PropertyLine", "Psi", "PtToCm", "Racute", "Rcaron", "Rcommaaccent", "Rdoublegrave", "Rdsh", "Re", "ReadFile", "Relbar", "Rho", "Rightarrow", "Rinvertedbreve", "Romannumerals", "Rrightarrow", "Rsh", "S", "Sacute", "ScaledPointsToBigPoints", "ScaledPointsToWholeBigPoints", "Scaron", "Scedilla", "Schwa", "Scircumflex", "Scommaaccent", "Searrow", "Sigma", "Smallcapped", "Subset", "Supset", "Swarrow", "TABLE", "TEX", "TaBlE", "Tau", "Tcaron", "Tcedilla", "Tcommaaccent", "TeX", "TheNormalizedFontSize", "Theta", "Thook", "Thorn", "TransparencyHack", "Tstroke", "Uacute", "Ubreve", "Ucaron", "Ucircumflex", "Udiaeresis", "Udiaeresisacute", "Udiaeresiscaron", "Udiaeresisgrave", "Udiaeresismacron", "Udotbelow", "Udoublegrave", "Ugrave", "Uhook", "Uhorn", "Uhornacute", "Uhorndotbelow", "Uhorngrave", "Uhornhook", "Uhorntilde", "Uhungarumlaut", "Uinvertedbreve", "Umacron", "Uogonek", "Uparrow", "Updownarrow", "Upsilon", "Uring", "Utilde", "Uuparrow", "VDash", "Vdash", "VerboseNumber", "Vert", "Vvdash", "WEEKDAY", "WORD", "WORDS", "Wcircumflex", "WidthSpanningText", "Word", "Words", "XETEX", "XeTeX", "Xi", "Yacute", "Ycircumflex", "Ydiaeresis", "Ydotbelow", "Ygrave", "Yhook", "Ymacron", "Ytilde", "Zacute", "Zcaron", "Zdotaccent", "Zeta", "Zhook", "Zstroke", "aacute", "abbreviation", "abjadnaivenumerals", "abjadnodotnumerals", "abjadnumerals", "about", "abreve", "abreveacute", "abrevedotbelow", "abrevegrave", "abrevehook", "abrevetilde", "acaron", "acircumflex", "acircumflexacute", "acircumflexdotbelow", "acircumflexgrave", "acircumflexhook", "acircumflextilde", "activatespacehandler", "actuarial", "acute", "acwopencirclearrow", "adaptcollector", "adaptfontfeature", "adaptlayout", "adaptpapersize", "addfeature", "addtoJSpreamble", "addtocommalist", "addvalue", "adiaeresis", "adiaeresismacron", "adotaccent", "adotaccentmacron", "adotbelow", "adoublegrave", "aeacute", "aeligature", "aemacron", "aftersplitstring", "aftertestandsplitstring", "agrave", "ahook", "ainvertedbreve", "aleph", "alignbottom", "aligned", "alignedbox", "alignedline", "alignhere", "alignmentcharacter", "allinputpaths", "alpha", "alphabeticnumerals", "alwayscitation", "alwayscite", "amacron", "amalg", "ampersand", "anchor", "angle", "aogonek", "appendetoks", "appendgvalue", "appendtocommalist", "appendtoks", "appendtoksonce", "appendvalue", "apply", "applyalternativestyle", "applyprocessor", "applytocharacters", "applytofirstcharacter", "applytosplitstringchar", "applytosplitstringcharspaced", "applytosplitstringline", "applytosplitstringlinespaced", "applytosplitstringword", "applytosplitstringwordspaced", "applytowords", "approx", "approxEq", "approxeq", "approxnEq", "arabicdecimals", "arabicexnumerals", "arabicnumerals", "arg", "aring", "aringacute", "arrowvert", "asciistr", "aside", "assignalfadimension", "assigndimen", "assigndimension", "assignifempty", "assigntranslation", "assignvalue", "assignwidth", "assumelongusagecs", "ast", "astype", "asymp", "at", "atilde", "atleftmargin", "atpage", "atrightmargin", "attachment", "autocap", "autodirhbox", "autodirvbox", "autodirvtop", "autoinsertnextspace", "autointegral", "automathematics", "autosetups", "availablehsize", "averagecharwidth", "backepsilon", "background", "backgroundimage", "backgroundimagefill", "backgroundline", "backprime", "backsim", "backslash", "bar", "barleftarrow", "barleftarrowrightarrowbar", "barovernorthwestarrow", "barwedge", "basegrid", "baselinebottom", "baselineleftbox", "baselinemiddlebox", "baselinerightbox", "bbordermatrix", "bbox", "because", "beforesplitstring", "beforetestandsplitstring", "beta", "beth", "between", "bhook", "big", "bigbodyfont", "bigcap", "bigcirc", "bigcircle", "bigcup", "bigdiamond", "bigg", "bigger", "biggl", "biggm", "biggr", "bigl", "bigm", "bigodot", "bigoplus", "bigotimes", "bigr", "bigskip", "bigsqcap", "bigsqcup", "bigsquare", "bigstar", "bigtimes", "bigtriangledown", "bigtriangleup", "bigudot", "biguplus", "bigvee", "bigwedge", "binom", "bitmapimage", "blacklozenge", "blackrule", "blackrules", "blacksquare", "blacktriangle", "blacktriangledown", "blacktriangleleft", "blacktriangleright", "blank", "blap", "bleed", "bleedheight", "bleedwidth", "blockligatures", "blockquote", "blocksynctexfile", "bodyfontenvironmentlist", "bodyfontsize", "bold", "boldface", "bolditalic", "boldslanted", "bookmark", "booleanmodevalue", "bordermatrix", "bot", "bottombox", "bottomleftbox", "bottomrightbox", "bowtie", "boxcursor", "boxdot", "boxmarker", "boxminus", "boxofsize", "boxplus", "boxreference", "boxtimes", "bpos", "breakablethinspace", "breakhere", "breve", "bstroke", "btxabbreviatedjournal", "btxaddjournal", "btxalwayscitation", "btxauthorfield", "btxdetail", "btxdirect", "btxdoif", "btxdoifcombiinlistelse", "btxdoifelse", "btxdoifelsecombiinlist", "btxdoifelsesameasprevious", "btxdoifelsesameaspreviouschecked", "btxdoifelseuservariable", "btxdoifnot", "btxdoifsameaspreviouscheckedelse", "btxdoifsameaspreviouselse", "btxdoifuservariableelse", "btxexpandedjournal", "btxfield", "btxfieldname", "btxfieldtype", "btxfirstofrange", "btxflush", "btxflushauthor", "btxflushauthorinverted", "btxflushauthorinvertedshort", "btxflushauthorname", "btxflushauthornormal", "btxflushauthornormalshort", "btxflushsuffix", "btxfoundname", "btxfoundtype", "btxhiddencitation", "btxhybridcite", "btxlabellanguage", "btxlabeltext", "btxlistcitation", "btxloadjournalist", "btxoneorrange", "btxremapauthor", "btxsavejournalist", "btxsetup", "btxsingularorplural", "btxsingularplural", "btxtextcitation", "buildmathaccent", "buildtextaccent", "buildtextbottomcomma", "buildtextbottomdot", "buildtextcedilla", "buildtextgrave", "buildtextmacron", "buildtextognek", "bullet", "button", "cacute", "calligraphic", "camel", "cap", "carriagereturn", "catcodetablename", "cbox", "ccaron", "ccedilla", "ccircumflex", "ccurl", "cdot", "cdotaccent", "cdotp", "cdots", "centeraligned", "centerbox", "centerdot", "centeredbox", "centeredlastline", "centerednextbox", "centerline", "cfrac", "chapter", "character", "characters", "chardescription", "charwidthlanguage", "check", "checkcharacteralign", "checkedchar", "checkedfiller", "checkedstrippedcsname", "checkinjector", "checkmark", "checknextindentation", "checknextinjector", "checkpage", "checkparameters", "checkpreviousinjector", "checksoundtrack", "checktwopassdata", "checkvariables", "chem", "chemical", "chemicalbottext", "chemicalmidtext", "chemicalsymbol", "chemicaltext", "chemicaltoptext", "chi", "chineseallnumerals", "chinesecapnumerals", "chinesenumerals", "chook", "circ", "circeq", "circlearrowleft", "circlearrowright", "circledR", "circledS", "circledast", "circledcirc", "circleddash", "circledequals", "circleonrightarrow", "citation", "cite", "clap", "classfont", "cldcommand", "cldcontext", "cldloadfile", "cldprocessfile", "cleftarrow", "clip", "clonefield", "clubsuit", "collect", "collectedtext", "collectexpanded", "colon", "coloncolonequals", "colonequals", "color", "colorbar", "colorcomponents", "colored", "coloronly", "colorvalue", "column", "columnbreak", "combinepages", "commalistelement", "commalistsentence", "commalistsize", "comment", "comparecolorgroup", "comparedimension", "comparedimensioneps", "comparepalet", "complement", "completebtxrendering", "completecontent", "completeindex", "completelist", "completelistofabbreviations", "completelistofchemicals", "completelistoffigures", "completelistofgraphics", "completelistofintermezzi", "completelistoflogos", "completelistofpublications", "completelistofsorts", "completelistofsynonyms", "completelistoftables", "completepagenumber", "completeregister", "complexes", "complexorsimple", "complexorsimpleempty", "component", "composedcollector", "composedlayer", "compresult", "cong", "constantdimen", "constantdimenargument", "constantemptyargument", "constantnumber", "constantnumberargument", "contentreference", "continuednumber", "continueifinputfile", "convertargument", "convertcommand", "convertedcounter", "converteddimen", "convertedsubcounter", "convertmonth", "convertnumber", "convertvalue", "convertvboxtohbox", "coprod", "copyboxfromcache", "copybtxlabeltext", "copyfield", "copyheadtext", "copylabeltext", "copymathlabeltext", "copyoperatortext", "copypages", "copyparameters", "copyposition", "copyprefixtext", "copyright", "copysuffixtext", "copytaglabeltext", "copyunittext", "correctwhitespace", "countersubs", "counttoken", "counttokens", "cramped", "crampedclap", "crampedllap", "crampedrlap", "crightarrow", "crightoverleftarrow", "cstroke", "ctop", "ctxcommand", "ctxdirectcommand", "ctxdirectlua", "ctxfunction", "ctxlatecommand", "ctxlatelua", "ctxloadluafile", "ctxlua", "ctxluabuffer", "ctxluacode", "ctxreport", "ctxsprint", "cup", "curlyeqprec", "curlyeqsucc", "curlyvee", "curlywedge", "currentassignmentlistkey", "currentassignmentlistvalue", "currentbtxuservariable", "currentcommalistitem", "currentcomponent", "currentdate", "currentenvironment", "currentfeaturetest", "currentheadnumber", "currentinterface", "currentlanguage", "currentlistentrydestinationattribute", "currentlistentrylimitedtext", "currentlistentrynumber", "currentlistentrypagenumber", "currentlistentryreferenceattribute", "currentlistentrytitle", "currentlistentrytitlerendered", "currentlistsymbol", "currentmainlanguage", "currentmessagetext", "currentmoduleparameter", "currentoutputstream", "currentproduct", "currentproject", "currentregime", "currentregisterpageuserdata", "currentresponses", "currenttime", "currentvalue", "currentxtablecolumn", "currentxtablerow", "curvearrowleft", "curvearrowright", "cwopencirclearrow", "cyrillicA", "cyrillicAE", "cyrillicAbreve", "cyrillicAdiaeresis", "cyrillicB", "cyrillicBIGYUS", "cyrillicBIGYUSiotified", "cyrillicC", "cyrillicCH", "cyrillicCHEDC", "cyrillicCHEDCabkhasian", "cyrillicCHEabkhasian", "cyrillicCHEdiaeresis", "cyrillicCHEkhakassian", "cyrillicCHEvertstroke", "cyrillicD", "cyrillicDASIAPNEUMATA", "cyrillicDJE", "cyrillicDZE", "cyrillicDZEabkhasian", "cyrillicDZHE", "cyrillicE", "cyrillicELtail", "cyrillicEMtail", "cyrillicENDC", "cyrillicENGHE", "cyrillicENhook", "cyrillicENtail", "cyrillicEREV", "cyrillicERY", "cyrillicERtick", "cyrillicEbreve", "cyrillicEdiaeresis", "cyrillicEgrave", "cyrillicEiotified", "cyrillicF", "cyrillicFITA", "cyrillicG", "cyrillicGHEmidhook", "cyrillicGHEstroke", "cyrillicGHEupturn", "cyrillicGJE", "cyrillicH", "cyrillicHA", "cyrillicHADC", "cyrillicHRDSN", "cyrillicI", "cyrillicIE", "cyrillicII", "cyrillicISHRT", "cyrillicISHRTtail", "cyrillicIZHITSA", "cyrillicIZHITSAdoublegrave", "cyrillicIdiaeresis", "cyrillicIgrave", "cyrillicImacron", "cyrillicJE", "cyrillicK", "cyrillicKADC", "cyrillicKAbashkir", "cyrillicKAhook", "cyrillicKAstroke", "cyrillicKAvertstroke", "cyrillicKJE", "cyrillicKOPPA", "cyrillicKSI", "cyrillicL", "cyrillicLITTLEYUS", "cyrillicLITTLEYUSiotified", "cyrillicLJE", "cyrillicM", "cyrillicN", "cyrillicNJE", "cyrillicO", "cyrillicOMEGA", "cyrillicOMEGAround", "cyrillicOMEGAtitlo", "cyrillicOT", "cyrillicObarred", "cyrillicObarreddiaeresis", "cyrillicOdiaeresis", "cyrillicP", "cyrillicPALATALIZATION", "cyrillicPALOCHKA", "cyrillicPEmidhook", "cyrillicPSI", "cyrillicPSILIPNEUMATA", "cyrillicR", "cyrillicS", "cyrillicSCHWA", "cyrillicSCHWAdiaeresis", "cyrillicSDSC", "cyrillicSEMISOFT", "cyrillicSFTSN", "cyrillicSH", "cyrillicSHCH", "cyrillicSHHA", "cyrillicT", "cyrillicTEDC", "cyrillicTETSE", "cyrillicTITLO", "cyrillicTSHE", "cyrillicU", "cyrillicUK", "cyrillicUSHRT", "cyrillicUdiaeresis", "cyrillicUdoubleacute", "cyrillicUmacron", "cyrillicV", "cyrillicYA", "cyrillicYAT", "cyrillicYERUdiaeresis", "cyrillicYI", "cyrillicYO", "cyrillicYU", "cyrillicYstr", "cyrillicYstrstroke", "cyrillicZ", "cyrillicZDSC", "cyrillicZEdiaeresis", "cyrillicZH", "cyrillicZHEbreve", "cyrillicZHEdescender", "cyrillicZHEdiaeresis", "cyrillica", "cyrillicabreve", "cyrillicadiaeresis", "cyrillicae", "cyrillicb", "cyrillicbigyus", "cyrillicbigyusiotified", "cyrillicc", "cyrillicch", "cyrilliccheabkhasian", "cyrillicchedc", "cyrillicchedcabkhasian", "cyrillicchediaeresis", "cyrillicchekhakassian", "cyrillicchevertstroke", "cyrillicd", "cyrillicdje", "cyrillicdze", "cyrillicdzeabkhasian", "cyrillicdzhe", "cyrillice", "cyrillicebreve", "cyrillicediaeresis", "cyrillicegrave", "cyrilliceiotified", "cyrilliceltail", "cyrillicemtail", "cyrillicendc", "cyrillicenghe", "cyrillicenhook", "cyrillicentail", "cyrillicerev", "cyrillicertick", "cyrillicery", "cyrillicf", "cyrillicfita", "cyrillicg", "cyrillicghemidhook", "cyrillicghestroke", "cyrillicgheupturn", "cyrillicgje", "cyrillich", "cyrillicha", "cyrillichadc", "cyrillichrdsn", "cyrillici", "cyrillicidiaeresis", "cyrillicie", "cyrillicigrave", "cyrillicii", "cyrillicimacron", "cyrillicishrt", "cyrillicishrttail", "cyrillicizhitsa", "cyrillicizhitsadoublegrave", "cyrillicje", "cyrillick", "cyrillickabashkir", "cyrillickadc", "cyrillickahook", "cyrillickastroke", "cyrillickavertstroke", "cyrillickje", "cyrillickoppa", "cyrillicksi", "cyrillicl", "cyrilliclittleyus", "cyrilliclittleyusiotified", "cyrilliclje", "cyrillicm", "cyrillicn", "cyrillicnje", "cyrillico", "cyrillicobarred", "cyrillicobarreddiaeresis", "cyrillicodiaeresis", "cyrillicomega", "cyrillicomegaround", "cyrillicomegatitlo", "cyrillicot", "cyrillicp", "cyrillicpemidhook", "cyrillicpsi", "cyrillicr", "cyrillics", "cyrillicschwa", "cyrillicschwadiaeresis", "cyrillicsdsc", "cyrillicsemisoft", "cyrillicsftsn", "cyrillicsh", "cyrillicshch", "cyrillicshha", "cyrillict", "cyrillictedc", "cyrillictetse", "cyrillictshe", "cyrillicu", "cyrillicudiaeresis", "cyrillicudoubleacute", "cyrillicuk", "cyrillicumacron", "cyrillicushrt", "cyrillicv", "cyrillicya", "cyrillicyat", "cyrillicyerudiaeresis", "cyrillicyi", "cyrillicyo", "cyrillicystr", "cyrillicystrstroke", "cyrillicyu", "cyrillicz", "cyrilliczdsc", "cyrilliczediaeresis", "cyrilliczh", "cyrilliczhebreve", "cyrilliczhedescender", "cyrilliczhediaeresis", "d", "dag", "dagger", "daleth", "dasharrow", "dashedleftarrow", "dashedrightarrow", "dashv", "datasetvariable", "date", "dayoftheweek", "dayspermonth", "dbinom", "dcaron", "dcurl", "ddag", "ddagger", "dddot", "ddot", "ddots", "decrement", "decrementcounter", "decrementedcounter", "decrementpagenumber", "decrementsubpagenumber", "decrementvalue", "defaultinterface", "defaultobjectpage", "defaultobjectreference", "defcatcodecommand", "defconvertedargument", "defconvertedcommand", "defconvertedvalue", "define", "defineMPinstance", "defineTABLEsetup", "defineaccent", "defineactivecharacter", "definealternativestyle", "defineanchor", "defineattachment", "defineattribute", "definebackground", "definebar", "defineblock", "definebodyfont", "definebodyfontenvironment", "definebodyfontswitch", "definebreakpoint", "definebreakpoints", "definebtx", "definebtxdataset", "definebtxregister", "definebtxrendering", "definebuffer", "definebutton", "definecapitals", "definecharacter", "definecharacterkerning", "definecharacterspacing", "definechemical", "definechemicals", "definechemicalsymbol", "definecollector", "definecolor", "definecolorgroup", "definecolumnbreak", "definecombination", "definecombinedlist", "definecommand", "definecomment", "definecomplexorsimple", "definecomplexorsimpleempty", "defineconversion", "defineconversionset", "definecounter", "definedataset", "definedelimitedtext", "definedeq", "definedescription", "definedfont", "defineeffect", "defineenumeration", "defineexpandable", "defineexternalfigure", "definefallbackfamily", "definefield", "definefieldbody", "definefieldbodyset", "definefieldcategory", "definefieldstack", "definefiguresymbol", "definefileconstant", "definefilefallback", "definefilesynonym", "definefiller", "definefirstline", "definefittingpage", "definefloat", "definefont", "definefontalternative", "definefontfallback", "definefontfamily", "definefontfamilypreset", "definefontfeature", "definefontfile", "definefontsize", "definefontsolution", "definefontstyle", "definefontsynonym", "defineformula", "defineformulaalternative", "defineformulaframed", "defineframed", "defineframedcontent", "defineframedtable", "defineframedtext", "definefrozenfont", "defineglobalcolor", "definegraphictypesynonym", "definegridsnapping", "definehbox", "definehead", "defineheadalternative", "definehelp", "definehigh", "definehighlight", "definehspace", "definehypenationfeatures", "defineindentedtext", "defineindenting", "defineinitial", "defineinsertion", "defineinteraction", "defineinteractionbar", "defineinteractionmenu", "defineinterfaceconstant", "defineinterfaceelement", "defineinterfacevariable", "defineinterlinespace", "defineintermediatecolor", "defineitemgroup", "defineitems", "definelabel", "definelabelclass", "definelayer", "definelayerpreset", "definelayout", "definelinefiller", "definelinenote", "definelinenumbering", "definelines", "definelist", "definelistalternative", "definelistextra", "definelow", "definelowhigh", "definelowmidhigh", "definemakeup", "definemarginblock", "definemargindata", "definemarker", "definemarking", "definemathaccent", "definemathalignment", "definemathcases", "definemathcommand", "definemathdouble", "definemathdoubleextensible", "definemathematics", "definemathextensible", "definemathfence", "definemathfraction", "definemathframed", "definemathmatrix", "definemathornament", "definemathover", "definemathoverextensible", "definemathovertextextensible", "definemathradical", "definemathstackers", "definemathstyle", "definemathtriplet", "definemathunder", "definemathunderextensible", "definemathundertextextensible", "definemathunstacked", "definemeasure", "definemessageconstant", "definemixedcolumns", "definemode", "definemultitonecolor", "definenamedcolor", "definenamespace", "definenarrower", "definenote", "defineornament", "defineoutputroutine", "defineoutputroutinecommand", "defineoverlay", "definepage", "definepagebreak", "definepagechecker", "definepagegrid", "definepagegridarea", "definepagegridspan", "definepageinjection", "definepageinjectionalternative", "definepageshift", "definepagestate", "definepairedbox", "definepalet", "definepapersize", "defineparagraph", "defineparagraphs", "defineparallel", "defineparbuilder", "defineplacement", "definepositioning", "defineprefixset", "defineprocesscolor", "defineprocessor", "defineprofile", "defineprogram", "definepushbutton", "definepushsymbol", "definereference", "definereferenceformat", "defineregister", "definerenderingwindow", "defineresetset", "definescale", "definescript", "definesection", "definesectionblock", "definesectionlevels", "defineselector", "defineseparatorset", "defineshift", "definesidebar", "definesort", "definesorting", "definespotcolor", "definestartstop", "definestyle", "definestyleinstance", "definesubfield", "definesubformula", "definesymbol", "definesynonym", "definesynonyms", "definesystemattribute", "definesystemconstant", "definesystemvariable", "definetabletemplate", "definetabulate", "definetabulation", "definetext", "definetextbackground", "definetextflow", "definetooltip", "definetransparency", "definetwopasslist", "definetype", "definetypeface", "definetypescriptprefix", "definetypescriptsynonym", "definetypesetting", "definetyping", "defineunit", "defineviewerlayer", "definevspace", "definevspacing", "definevspacingamount", "definextable", "delimited", "delimitedtext", "delta", "depthofstring", "depthonlybox", "depthspanningtext", "depthstrut", "determineheadnumber", "determinelistcharacteristics", "determinenoflines", "determineregistercharacteristics", "devanagarinumerals", "dfrac", "dhook", "diameter", "diamond", "diamondsuit", "differentialD", "differentiald", "digamma", "digits", "dimensiontocount", "directboxfromcache", "directcolor", "directcolored", "directconvertedcounter", "directcopyboxfromcache", "directdummyparameter", "directgetboxllx", "directgetboxlly", "directhighlight", "directlocalframed", "directluacode", "directselect", "directsetbar", "directsetup", "directsymbol", "directvspacing", "dis", "disabledirectives", "disableexperiments", "disablemode", "disableoutputstream", "disableparpositions", "disableregime", "disabletrackers", "displaymath", "displaymathematics", "displaymessage", "distributedhsize", "div", "dividedsize", "divideontimes", "divides", "doadaptleftskip", "doadaptrightskip", "doaddfeature", "doassign", "doassignempty", "doboundtext", "docheckassignment", "docheckedpagestate", "docheckedpair", "documentvariable", "dodoubleargument", "dodoubleargumentwithset", "dodoubleempty", "dodoubleemptywithset", "dodoublegroupempty", "doeassign", "doexpandedrecurse", "dofastloopcs", "dogetattribute", "dogetattributeid", "dogetcommacommandelement", "dogobbledoubleempty", "dogobblesingleempty", "doif", "doifMPgraphicelse", "doifallcommon", "doifallcommonelse", "doifalldefinedelse", "doifallmodes", "doifallmodeselse", "doifassignmentelse", "doifblackelse", "doifbothsides", "doifbothsidesoverruled", "doifboxelse", "doifbufferelse", "doifcolor", "doifcolorelse", "doifcommandhandler", "doifcommandhandlerelse", "doifcommon", "doifcommonelse", "doifcontent", "doifconversiondefinedelse", "doifconversionnumberelse", "doifcounter", "doifcounterelse", "doifcurrentfonthasfeatureelse", "doifdefined", "doifdefinedcounter", "doifdefinedcounterelse", "doifdefinedelse", "doifdimensionelse", "doifdimenstringelse", "doifdocumentargument", "doifdocumentargumentelse", "doifdocumentfilename", "doifdocumentfilenameelse", "doifdrawingblackelse", "doifelse", "doifelseMPgraphic", "doifelseallcommon", "doifelsealldefined", "doifelseallmodes", "doifelseassignment", "doifelseblack", "doifelsebox", "doifelseboxincache", "doifelsebuffer", "doifelsecolor", "doifelsecommandhandler", "doifelsecommon", "doifelseconversiondefined", "doifelseconversionnumber", "doifelsecounter", "doifelsecurrentfonthasfeature", "doifelsecurrentsortingused", "doifelsecurrentsynonymshown", "doifelsecurrentsynonymused", "doifelsedefined", "doifelsedefinedcounter", "doifelsedimension", "doifelsedimenstring", "doifelsedocumentargument", "doifelsedocumentfilename", "doifelsedrawingblack", "doifelseempty", "doifelseemptyvalue", "doifelseemptyvariable", "doifelseenv", "doifelsefastoptionalcheck", "doifelsefastoptionalcheckcs", "doifelsefieldbody", "doifelsefieldcategory", "doifelsefigure", "doifelsefile", "doifelsefiledefined", "doifelsefileexists", "doifelsefirstchar", "doifelseflagged", "doifelsefontchar", "doifelsefontpresent", "doifelsefontsynonym", "doifelsehasspace", "doifelsehelp", "doifelseincsname", "doifelseinelement", "doifelseinputfile", "doifelseinsertion", "doifelseinset", "doifelseinstring", "doifelseinsymbolset", "doifelseintoks", "doifelseintwopassdata", "doifelseitalic", "doifelselanguage", "doifelselayerdata", "doifelselayoutdefined", "doifelselayoutsomeline", "doifelselayouttextline", "doifelseleapyear", "doifelselist", "doifelselocation", "doifelselocfile", "doifelsemainfloatbody", "doifelsemarkedpage", "doifelsemarking", "doifelsemeaning", "doifelsemessage", "doifelsemode", "doifelsenextbgroup", "doifelsenextbgroupcs", "doifelsenextchar", "doifelsenextoptional", "doifelsenextoptionalcs", "doifelsenextparenthesis", "doifelsenonzeropositive", "doifelsenoteonsamepage", "doifelsenothing", "doifelsenumber", "doifelseobjectfound", "doifelseobjectreferencefound", "doifelseoddpage", "doifelseoddpagefloat", "doifelseoldercontext", "doifelseolderversion", "doifelseoverlapping", "doifelseoverlay", "doifelseparallel", "doifelseparentfile", "doifelsepath", "doifelsepathexists", "doifelsepatterns", "doifelseposition", "doifelsepositionaction", "doifelsepositiononpage", "doifelsepositionsonsamepage", "doifelsepositionsonthispage", "doifelsepositionsused", "doifelsereferencefound", "doifelserightpagefloat", "doifelserighttoleftinbox", "doifelsesamelinereference", "doifelsesamestring", "doifelsesetups", "doifelsesomebackground", "doifelsesomespace", "doifelsesomething", "doifelsesometoks", "doifelsestringinstring", "doifelsestructurelisthasnumber", "doifelsestructurelisthaspage", "doifelsesymboldefined", "doifelsesymbolset", "doifelsetext", "doifelsetextflow", "doifelsetextflowcollector", "doifelsetopofpage", "doifelsetypingfile", "doifelseundefined", "doifelseurldefined", "doifelsevalue", "doifelsevaluenothing", "doifelsevariable", "doifempty", "doifemptyelse", "doifemptytoks", "doifemptyvalue", "doifemptyvalueelse", "doifemptyvariable", "doifemptyvariableelse", "doifenv", "doifenvelse", "doiffastoptionalcheckcselse", "doiffastoptionalcheckelse", "doiffieldbodyelse", "doiffieldcategoryelse", "doiffigureelse", "doiffile", "doiffiledefinedelse", "doiffileelse", "doiffileexistselse", "doiffirstcharelse", "doifflaggedelse", "doiffontcharelse", "doiffontpresentelse", "doiffontsynonymelse", "doifhasspaceelse", "doifhelpelse", "doifincsnameelse", "doifinelementelse", "doifinputfileelse", "doifinsertionelse", "doifinset", "doifinsetelse", "doifinstring", "doifinstringelse", "doifinsymbolset", "doifinsymbolsetelse", "doifintokselse", "doifintwopassdataelse", "doifitalicelse", "doiflanguageelse", "doiflayerdataelse", "doiflayoutdefinedelse", "doiflayoutsomelineelse", "doiflayouttextlineelse", "doifleapyearelse", "doiflistelse", "doiflocationelse", "doiflocfileelse", "doifmainfloatbodyelse", "doifmarkingelse", "doifmeaningelse", "doifmessageelse", "doifmode", "doifmodeelse", "doifnextbgroupcselse", "doifnextbgroupelse", "doifnextcharelse", "doifnextoptionalcselse", "doifnextoptionalelse", "doifnextparenthesiselse", "doifnonzeropositiveelse", "doifnot", "doifnotallcommon", "doifnotallmodes", "doifnotcommandhandler", "doifnotcommon", "doifnotcounter", "doifnotdocumentargument", "doifnotdocumentfilename", "doifnotempty", "doifnotemptyvalue", "doifnotemptyvariable", "doifnotenv", "doifnoteonsamepageelse", "doifnotescollected", "doifnotfile", "doifnotflagged", "doifnothing", "doifnothingelse", "doifnotinset", "doifnotinsidesplitfloat", "doifnotinstring", "doifnotmode", "doifnotnumber", "doifnotsamestring", "doifnotsetups", "doifnotvalue", "doifnotvariable", "doifnumber", "doifnumberelse", "doifobjectfoundelse", "doifobjectreferencefoundelse", "doifoddpageelse", "doifoddpagefloatelse", "doifoldercontextelse", "doifolderversionelse", "doifoverlappingelse", "doifoverlayelse", "doifparallelelse", "doifparentfileelse", "doifpathelse", "doifpathexistselse", "doifpatternselse", "doifposition", "doifpositionaction", "doifpositionactionelse", "doifpositionelse", "doifpositiononpageelse", "doifpositionsonsamepageelse", "doifpositionsonthispageelse", "doifpositionsusedelse", "doifreferencefoundelse", "doifrightpagefloatelse", "doifrighttoleftinboxelse", "doifsamelinereferenceelse", "doifsamestring", "doifsamestringelse", "doifsetups", "doifsetupselse", "doifsomebackground", "doifsomebackgroundelse", "doifsomespaceelse", "doifsomething", "doifsomethingelse", "doifsometoks", "doifsometokselse", "doifstringinstringelse", "doifstructurelisthasnumberelse", "doifstructurelisthaspageelse", "doifsymboldefinedelse", "doifsymbolsetelse", "doiftext", "doiftextelse", "doiftextflowcollectorelse", "doiftextflowelse", "doiftopofpageelse", "doiftypingfileelse", "doifundefined", "doifundefinedcounter", "doifundefinedelse", "doifurldefinedelse", "doifvalue", "doifvalueelse", "doifvaluenothing", "doifvaluenothingelse", "doifvaluesomething", "doifvariable", "doifvariableelse", "doindentation", "dollar", "doloop", "doloopoverlist", "donothing", "dontconvertfont", "dontleavehmode", "dontpermitspacesbetweengroups", "dopositionaction", "doprocesslocalsetups", "doquadrupleargument", "doquadrupleempty", "doquadruplegroupempty", "doquintupleargument", "doquintupleempty", "doquintuplegroupempty", "dorechecknextindentation", "dorecurse", "dorepeatwithcommand", "doreplacefeature", "doresetandafffeature", "doresetattribute", "dorotatebox", "dosetattribute", "dosetleftskipadaption", "dosetrightskipadaption", "dosetupcheckedinterlinespace", "doseventupleargument", "doseventupleempty", "dosingleargument", "dosingleempty", "dosinglegroupempty", "dosixtupleargument", "dosixtupleempty", "dostepwiserecurse", "dosubtractfeature", "dot", "doteq", "doteqdot", "dotfskip", "dotlessI", "dotlessJ", "dotlessi", "dotlessj", "dotlessjstroke", "dotminus", "dotoks", "dotplus", "dotripleargument", "dotripleargumentwithset", "dotripleempty", "dotripleemptywithset", "dotriplegroupempty", "dots", "dottedrightarrow", "doublebar", "doublebond", "doublebrace", "doublebracket", "doublecap", "doublecup", "doubleparent", "doubleprime", "doubleverticalbar", "dowith", "dowithnextbox", "dowithnextboxcontent", "dowithnextboxcontentcs", "dowithnextboxcs", "dowithpargument", "dowithrange", "dowithwargument", "downarrow", "downdasharrow", "downdownarrows", "downharpoonleft", "downharpoonright", "downuparrows", "downwhitearrow", "downzigzagarrow", "dpofstring", "dstroke", "dtail", "dummydigit", "dummyparameter", "dzcaronligature", "dzligature", "eTeX", "eacute", "ebreve", "ecaron", "ecedilla", "ecircumflex", "ecircumflexacute", "ecircumflexdotbelow", "ecircumflexgrave", "ecircumflexhook", "ecircumflextilde", "edefconvertedargument", "ediaeresis", "edotaccent", "edotbelow", "edoublegrave", "efcmaxheight", "efcmaxwidth", "efcminheight", "efcminwidth", "efcparameter", "effect", "egrave", "ehook", "einvertedbreve", "elapsedseconds", "elapsedtime", "eleftarrowfill", "eleftharpoondownfill", "eleftharpoonupfill", "eleftrightarrowfill", "ell", "em", "emacron", "emdash", "emphasisboldface", "emphasistypeface", "emptylines", "emptyset", "emspace", "enabledirectives", "enableexperiments", "enablemode", "enableoutputstream", "enableparpositions", "enableregime", "enabletrackers", "endash", "endnote", "enskip", "enspace", "env", "environment", "envvar", "eogonek", "eoverbarfill", "eoverbracefill", "eoverbracketfill", "eoverparentfill", "epos", "epsilon", "eq", "eqcirc", "eqeq", "eqeqeq", "eqgtr", "eqless", "eqsim", "eqslantgtr", "eqslantless", "equaldigits", "equalscolon", "equiv", "erightarrowfill", "erightharpoondownfill", "erightharpoonupfill", "eta", "eth", "ethiopic", "etilde", "etwoheadrightarrowfill", "eunderbarfill", "eunderbracefill", "eunderbracketfill", "eunderparentfill", "exclamdown", "executeifdefined", "exists", "exitloop", "exitloopnow", "expandcheckedcsname", "expanded", "expandfontsynonym", "expdoif", "expdoifcommonelse", "expdoifelse", "expdoifelsecommon", "expdoifelseinset", "expdoifinsetelse", "expdoifnot", "exponentiale", "externalfigure", "externalfigurecollectionmaxheight", "externalfigurecollectionmaxwidth", "externalfigurecollectionminheight", "externalfigurecollectionminwidth", "externalfigurecollectionparameter", "fakebox", "fallingdotseq", "fastdecrement", "fastincrement", "fastlocalframed", "fastloopfinal", "fastloopindex", "fastscale", "fastsetup", "fastsetupwithargument", "fastsetupwithargumentswapped", "fastswitchtobodyfont", "fastsxsy", "feature", "fence", "fenced", "fetchallmarkings", "fetchallmarks", "fetchmark", "fetchmarking", "fetchonemark", "fetchonemarking", "fetchruntinecommand", "fetchtwomarkings", "fetchtwomarks", "ffiligature", "ffligature", "fflligature", "fhook", "field", "fieldbody", "fieldstack", "fifthoffivearguments", "fifthofsixarguments", "figurefilename", "figurefilepath", "figurefiletype", "figurefullname", "figureheight", "figurenaturalheight", "figurenaturalwidth", "figurespace", "figuresymbol", "figurewidth", "filename", "filigature", "filledhboxb", "filledhboxc", "filledhboxg", "filledhboxk", "filledhboxm", "filledhboxr", "filledhboxy", "filler", "fillinline", "fillinrules", "fillintext", "filterfromnext", "filterfromvalue", "filterpages", "filterreference", "findtwopassdata", "finishregisterentry", "firstcharacter", "firstcounter", "firstcountervalue", "firstoffivearguments", "firstoffourarguments", "firstofoneargument", "firstofoneunexpanded", "firstofsixarguments", "firstofthreearguments", "firstofthreeunexpanded", "firstoftwoarguments", "firstoftwounexpanded", "firstrealpage", "firstrealpagenumber", "firstsubcountervalue", "firstsubpage", "firstsubpagenumber", "firstuserpage", "firstuserpagenumber", "fitfield", "fitfieldframed", "fittopbaselinegrid", "fiveeighths", "fivesixths", "fixedspace", "fixedspaces", "flag", "flat", "flligature", "floatuserdataparameter", "flushbox", "flushboxregister", "flushcollector", "flushedrightlastline", "flushlayer", "flushlocalfloats", "flushnextbox", "flushnotes", "flushoutputstream", "flushshapebox", "flushtextflow", "flushtokens", "flushtoks", "fontalternative", "fontbody", "fontchar", "fontcharbyindex", "fontclass", "fontclassname", "fontface", "fontfeaturelist", "fontsize", "fontstyle", "footnote", "footnotetext", "forall", "forcecharacterstripping", "forcelocalfloats", "forgeteverypar", "forgetparameters", "forgetragged", "formula", "formulanumber", "foundbox", "fourfifths", "fourperemspace", "fourthoffivearguments", "fourthoffourarguments", "fourthofsixarguments", "frac", "framed", "frameddimension", "framedparameter", "framedtext", "freezedimenmacro", "freezemeasure", "frenchspacing", "from", "fromlinenote", "frown", "frozenhbox", "frule", "gacute", "gamma", "gbreve", "gcaron", "gcircumflex", "gcommaaccent", "gdefconvertedargument", "gdefconvertedcommand", "gdotaccent", "ge", "geq", "geqq", "geqslant", "getMPdrawing", "getMPlayer", "getboxfromcache", "getboxllx", "getboxlly", "getbuffer", "getbufferdata", "getcommacommandsize", "getcommalistsize", "getdayoftheweek", "getdayspermonth", "getdefinedbuffer", "getdocumentargument", "getdocumentargumentdefault", "getdocumentfilename", "getdummyparameters", "getemptyparameters", "geteparameters", "getexpandedparameters", "getfiguredimensions", "getfirstcharacter", "getfirsttwopassdata", "getfromcommacommand", "getfromcommalist", "getfromtwopassdata", "getglyphdirect", "getglyphstyled", "getgparameters", "getlasttwopassdata", "getlocalfloat", "getlocalfloats", "getmarking", "getmessage", "getnamedglyphdirect", "getnamedglyphstyled", "getnamedtwopassdatalist", "getnaturaldimensions", "getnoflines", "getobject", "getobjectdimensions", "getpaletsize", "getparameters", "getprivatechar", "getprivateslot", "getrandomcount", "getrandomdimen", "getrandomfloat", "getrandomnumber", "getrandomseed", "getraweparameters", "getrawgparameters", "getrawnoflines", "getrawparameters", "getrawxparameters", "getreference", "getreferenceentry", "getroundednoflines", "gets", "getsubstring", "gettwopassdata", "gettwopassdatalist", "getuvalue", "getvalue", "getvariable", "getvariabledefault", "getxparameters", "gg", "ggg", "gggtr", "gimel", "globaldisablemode", "globalenablemode", "globalletempty", "globalpopbox", "globalpopmacro", "globalpreventmode", "globalprocesscommalist", "globalpushbox", "globalpushmacro", "globalswapcounts", "globalswapdimens", "globalswapmacros", "globalundefine", "glyphfontfile", "gnapprox", "gneqq", "gnsim", "gobbledoubleempty", "gobbleeightarguments", "gobblefivearguments", "gobblefiveoptionals", "gobblefourarguments", "gobblefouroptionals", "gobbleninearguments", "gobbleoneargument", "gobbleoneoptional", "gobblesevenarguments", "gobblesingleempty", "gobblesixarguments", "gobblespacetokens", "gobbletenarguments", "gobblethreearguments", "gobblethreeoptionals", "gobbletwoarguments", "gobbletwooptionals", "gobbleuntil", "gobbleuntilrelax", "godown", "goto", "gotobox", "gotopage", "grabbufferdata", "grabbufferdatadirect", "grabuntil", "grave", "graycolor", "grayvalue", "greedysplitstring", "greekAlpha", "greekAlphadasia", "greekAlphadasiaperispomeni", "greekAlphadasiatonos", "greekAlphadasiavaria", "greekAlphaiotasub", "greekAlphaiotasubdasia", "greekAlphaiotasubdasiaperispomeni", "greekAlphaiotasubdasiatonos", "greekAlphaiotasubdasiavaria", "greekAlphaiotasubpsili", "greekAlphaiotasubpsiliperispomeni", "greekAlphaiotasubpsilitonos", "greekAlphaiotasubpsilivaria", "greekAlphamacron", "greekAlphapsili", "greekAlphapsiliperispomeni", "greekAlphapsilitonos", "greekAlphapsilivaria", "greekAlphatonos", "greekAlphavaria", "greekAlphavrachy", "greekBeta", "greekChi", "greekCoronis", "greekDelta", "greekEpsilon", "greekEpsilondasia", "greekEpsilondasiatonos", "greekEpsilondasiavaria", "greekEpsilonpsili", "greekEpsilonpsilitonos", "greekEpsilonpsilivaria", "greekEpsilontonos", "greekEpsilonvaria", "greekEta", "greekEtadasia", "greekEtadasiaperispomeni", "greekEtadasiatonos", "greekEtadasiavaria", "greekEtaiotasub", "greekEtaiotasubdasia", "greekEtaiotasubdasiaperispomeni", "greekEtaiotasubdasiatonos", "greekEtaiotasubdasiavaria", "greekEtaiotasubpsili", "greekEtaiotasubpsiliperispomeni", "greekEtaiotasubpsilitonos", "greekEtaiotasubpsilivaria", "greekEtapsili", "greekEtapsiliperispomeni", "greekEtapsilitonos", "greekEtapsilivaria", "greekEtatonos", "greekEtavaria", "greekGamma", "greekIota", "greekIotadasia", "greekIotadasiaperispomeni", "greekIotadasiatonos", "greekIotadasiavaria", "greekIotadialytika", "greekIotamacron", "greekIotapsili", "greekIotapsiliperispomeni", "greekIotapsilitonos", "greekIotapsilivaria", "greekIotatonos", "greekIotavaria", "greekIotavrachy", "greekKappa", "greekLambda", "greekMu", "greekNu", "greekOmega", "greekOmegadasia", "greekOmegadasiaperispomeni", "greekOmegadasiatonos", "greekOmegadasiavaria", "greekOmegaiotasub", "greekOmegaiotasubdasia", "greekOmegaiotasubdasiaperispomeni", "greekOmegaiotasubdasiatonos", "greekOmegaiotasubdasiavaria", "greekOmegaiotasubpsili", "greekOmegaiotasubpsiliperispomeni", "greekOmegaiotasubpsilitonos", "greekOmegaiotasubpsilivaria", "greekOmegapsili", "greekOmegapsiliperispomeni", "greekOmegapsilitonos", "greekOmegapsilivaria", "greekOmegatonos", "greekOmegavaria", "greekOmicron", "greekOmicrondasia", "greekOmicrondasiatonos", "greekOmicrondasiavaria", "greekOmicronpsili", "greekOmicronpsilitonos", "greekOmicronpsilivaria", "greekOmicrontonos", "greekOmicronvaria", "greekPhi", "greekPi", "greekPsi", "greekRho", "greekRhodasia", "greekSigma", "greekSigmalunate", "greekTau", "greekTheta", "greekUpsilon", "greekUpsilondasia", "greekUpsilondasiaperispomeni", "greekUpsilondasiatonos", "greekUpsilondasiavaria", "greekUpsilondialytika", "greekUpsilonmacron", "greekUpsilontonos", "greekUpsilonvaria", "greekUpsilonvrachy", "greekXi", "greekZeta", "greekalpha", "greekalphadasia", "greekalphadasiaperispomeni", "greekalphadasiatonos", "greekalphadasiavaria", "greekalphaiotasub", "greekalphaiotasubdasia", "greekalphaiotasubdasiaperispomeni", "greekalphaiotasubdasiatonos", "greekalphaiotasubdasiavaria", "greekalphaiotasubperispomeni", "greekalphaiotasubpsili", "greekalphaiotasubpsiliperispomeni", "greekalphaiotasubpsilitonos", "greekalphaiotasubpsilivaria", "greekalphaiotasubtonos", "greekalphaiotasubvaria", "greekalphamacron", "greekalphaoxia", "greekalphaperispomeni", "greekalphapsili", "greekalphapsiliperispomeni", "greekalphapsilitonos", "greekalphapsilivaria", "greekalphatonos", "greekalphavaria", "greekalphavrachy", "greekbeta", "greekchi", "greekdasia", "greekdasiaperispomeni", "greekdasiatonos", "greekdasiavaria", "greekdelta", "greekdialytikaperispomeni", "greekdialytikatonos", "greekdialytikavaria", "greekdigamma", "greekepsilon", "greekepsilonalt", "greekepsilondasia", "greekepsilondasiatonos", "greekepsilondasiavaria", "greekepsilonoxia", "greekepsilonpsili", "greekepsilonpsilitonos", "greekepsilonpsilivaria", "greekepsilontonos", "greekepsilonvaria", "greeketa", "greeketadasia", "greeketadasiaperispomeni", "greeketadasiatonos", "greeketadasiavaria", "greeketaiotasub", "greeketaiotasubdasia", "greeketaiotasubdasiaperispomeni", "greeketaiotasubdasiatonos", "greeketaiotasubdasiavaria", "greeketaiotasubperispomeni", "greeketaiotasubpsili", "greeketaiotasubpsiliperispomeni", "greeketaiotasubpsilitonos", "greeketaiotasubpsilivaria", "greeketaiotasubtonos", "greeketaiotasubvaria", "greeketaoxia", "greeketaperispomeni", "greeketapsili", "greeketapsiliperispomeni", "greeketapsilitonos", "greeketapsilivaria", "greeketatonos", "greeketavaria", "greekfinalsigma", "greekgamma", "greekiota", "greekiotadasia", "greekiotadasiaperispomeni", "greekiotadasiatonos", "greekiotadasiavaria", "greekiotadialytika", "greekiotadialytikaperispomeni", "greekiotadialytikatonos", "greekiotadialytikavaria", "greekiotamacron", "greekiotaoxia", "greekiotaperispomeni", "greekiotapsili", "greekiotapsiliperispomeni", "greekiotapsilitonos", "greekiotapsilivaria", "greekiotatonos", "greekiotavaria", "greekiotavrachy", "greekkappa", "greekkoppa", "greeklambda", "greekmu", "greeknu", "greeknumerals", "greeknumkoppa", "greekomega", "greekomegadasia", "greekomegadasiaperispomeni", "greekomegadasiatonos", "greekomegadasiavaria", "greekomegaiotasub", "greekomegaiotasubdasia", "greekomegaiotasubdasiaperispomeni", "greekomegaiotasubdasiatonos", "greekomegaiotasubdasiavaria", "greekomegaiotasubperispomeni", "greekomegaiotasubpsili", "greekomegaiotasubpsiliperispomeni", "greekomegaiotasubpsilitonos", "greekomegaiotasubpsilivaria", "greekomegaiotasubtonos", "greekomegaiotasubvaria", "greekomegaoxia", "greekomegaperispomeni", "greekomegapsili", "greekomegapsiliperispomeni", "greekomegapsilitonos", "greekomegapsilivaria", "greekomegatonos", "greekomegavaria", "greekomicron", "greekomicrondasia", "greekomicrondasiatonos", "greekomicrondasiavaria", "greekomicronoxia", "greekomicronpsili", "greekomicronpsilitonos", "greekomicronpsilivaria", "greekomicrontonos", "greekomicronvaria", "greekoxia", "greekperispomeni", "greekphi", "greekphialt", "greekpi", "greekpialt", "greekprosgegrammeni", "greekpsi", "greekpsili", "greekpsiliperispomeni", "greekpsilitonos", "greekpsilivaria", "greekrho", "greekrhoalt", "greekrhodasia", "greekrhopsili", "greeksampi", "greeksigma", "greeksigmalunate", "greekstigma", "greektau", "greektheta", "greekthetaalt", "greektonos", "greekupsilon", "greekupsilondasia", "greekupsilondasiaperispomeni", "greekupsilondasiatonos", "greekupsilondasiavaria", "greekupsilondiaeresis", "greekupsilondialytikaperispomeni", "greekupsilondialytikatonos", "greekupsilondialytikavaria", "greekupsilonmacron", "greekupsilonoxia", "greekupsilonperispomeni", "greekupsilonpsili", "greekupsilonpsiliperispomeni", "greekupsilonpsilitonos", "greekupsilonpsilivaria", "greekupsilontonos", "greekupsilonvaria", "greekupsilonvrachy", "greekvaria", "greekxi", "greekzeta", "grid", "groupedcommand", "gsetboxllx", "gsetboxlly", "gstroke", "gt", "gtrapprox", "gtrdot", "gtreqless", "gtreqqless", "gtrless", "gtrsim", "guilsingleleft", "guilsingleright", "gujaratinumerals", "gurmurkhinumerals", "hairline", "hairspace", "halflinestrut", "halfstrut", "halfwaybox", "handletokens", "handwritten", "hangul", "hanzi", "hash", "hat", "hbar", "hboxofvbox", "hboxreference", "hcaron", "hcircumflex", "hdofstring", "headhbox", "headlanguage", "headnumber", "headnumbercontent", "headnumberdistance", "headnumberwidth", "headreferenceattributes", "headsetupspacing", "headtext", "headtextcontent", "headtextdistance", "headtexts", "headtextwidth", "headvbox", "headwidth", "heartsuit", "hebrewAlef", "hebrewAyin", "hebrewBet", "hebrewDalet", "hebrewGimel", "hebrewHe", "hebrewHet", "hebrewKaf", "hebrewKaffinal", "hebrewLamed", "hebrewMem", "hebrewMemfinal", "hebrewNun", "hebrewNunfinal", "hebrewPe", "hebrewPefinal", "hebrewQof", "hebrewResh", "hebrewSamekh", "hebrewShin", "hebrewTav", "hebrewTet", "hebrewTsadi", "hebrewTsadifinal", "hebrewVav", "hebrewYod", "hebrewZayin", "heightanddepthofstring", "heightofstring", "heightspanningtext", "helptext", "hglue", "hiddenbar", "hiddencitation", "hiddencite", "hideblocks", "high", "highlight", "highordinalstr", "hilo", "himilo", "hl", "hookleftarrow", "hookrightarrow", "horizontalgrowingbar", "horizontalpositionbar", "hphantom", "hpos", "hsizefraction", "hslash", "hsmash", "hsmashbox", "hsmashed", "hspace", "hstroke", "htdpofstring", "htofstring", "hyphen", "hyphenatedcoloredword", "hyphenatedfile", "hyphenatedfilename", "hyphenatedhbox", "hyphenatedpar", "hyphenatedurl", "hyphenatedword", "iacute", "ibox", "ibreve", "icaron", "icircumflex", "ideographichalffillspace", "ideographicspace", "idiaeresis", "idotaccent", "idotbelow", "idoublegrave", "ifassignment", "iff", "ifinobject", "ifinoutputstream", "ifparameters", "iftrialtypesetting", "ignoreimplicitspaces", "ignorevalue", "igrave", "ihook", "iiiint", "iiiintop", "iiint", "iiintop", "iint", "iintop", "iinvertedbreve", "ijligature", "imacron", "imaginaryi", "imaginaryj", "imath", "immediatesavetwopassdata", "impliedby", "implies", "imply", "in", "includemenu", "includeversioninfo", "increment", "incrementcounter", "incrementedcounter", "incrementpagenumber", "incrementsubpagenumber", "incrementvalue", "indentation", "index", "infofont", "infofontbold", "inframed", "infty", "infull", "inheritparameter", "inhibitblank", "ininner", "ininneredge", "ininnermargin", "initializeboxstack", "inleft", "inleftedge", "inleftmargin", "inline", "inlinebuffer", "inlinedbox", "inlinemath", "inlinemathematics", "inlinemessage", "inlineordisplaymath", "inlineprettyprintbuffer", "inlinerange", "inmargin", "inmframed", "innerflushshapebox", "inother", "inouter", "inouteredge", "inoutermargin", "input", "inputfilebarename", "inputfilename", "inputfilerealsuffix", "inputfilesuffix", "inputgivenfile", "inright", "inrightedge", "inrightmargin", "insertpages", "installactionhandler", "installactivecharacter", "installanddefineactivecharacter", "installattributestack", "installautocommandhandler", "installautosetuphandler", "installbasicautosetuphandler", "installbasicparameterhandler", "installbottomframerenderer", "installcommandhandler", "installcorenamespace", "installdefinehandler", "installdefinitionset", "installdefinitionsetmember", "installdirectcommandhandler", "installdirectparameterhandler", "installdirectparametersethandler", "installdirectsetuphandler", "installdirectstyleandcolorhandler", "installframedautocommandhandler", "installframedcommandhandler", "installlanguage", "installleftframerenderer", "installnamespace", "installoutputroutine", "installpagearrangement", "installparameterhandler", "installparameterhashhandler", "installparametersethandler", "installparentinjector", "installrightframerenderer", "installrootparameterhandler", "installsetuphandler", "installsetuponlycommandhandler", "installshipoutmethod", "installsimplecommandhandler", "installsimpleframedcommandhandler", "installstyleandcolorhandler", "installswitchcommandhandler", "installswitchsetuphandler", "installtexdirective", "installtextracker", "installtopframerenderer", "installunitsseparator", "installunitsspace", "installversioninfo", "int", "intclockwise", "integerrounding", "integers", "interactionbar", "interactionbuttons", "interactionmenu", "intercal", "intertext", "intop", "invisibletimes", "invokepageheandler", "iogonek", "iota", "istltdir", "istrtdir", "italic", "italicbold", "italiccorrection", "italicface", "item", "items", "itemtag", "itilde", "jcaron", "jcircumflex", "jmath", "jobfilename", "jobfilesuffix", "kap", "kappa", "kcaron", "kcommaaccent", "keepblocks", "keeplinestogether", "keepunwantedspaces", "kerncharacters", "khook", "kkra", "koreancirclenumerals", "koreannumerals", "koreannumeralsc", "koreannumeralsp", "koreanparentnumerals", "lVert", "labellanguage", "labeltext", "labeltexts", "lacute", "lambda", "lambdabar", "land", "langle", "language", "languageCharacters", "languagecharacters", "languagecharwidth", "lastcounter", "lastcountervalue", "lastdigit", "lastlinewidth", "lastnaturalboxdp", "lastnaturalboxht", "lastnaturalboxwd", "lastpredefinedsymbol", "lastrealpage", "lastrealpagenumber", "lastsubcountervalue", "lastsubpage", "lastsubpagenumber", "lasttwodigits", "lastuserpage", "lastuserpagenumber", "lateluacode", "latin", "layeredtext", "layerheight", "layerwidth", "lazysavetaggedtwopassdata", "lazysavetwopassdata", "lbar", "lbox", "lbrace", "lbracket", "lcaron", "lceil", "lcommaaccent", "lcurl", "ldotmiddle", "ldotp", "ldots", "le", "leadsto", "left", "leftaligned", "leftarrow", "leftarrowtail", "leftarrowtriangle", "leftbottombox", "leftbox", "leftdasharrow", "leftguillemot", "leftharpoondown", "leftharpoonup", "lefthbox", "leftheadtext", "leftlabeltext", "leftleftarrows", "leftline", "leftmathlabeltext", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "leftrightarrow", "leftrightarrows", "leftrightarrowtriangle", "leftrightharpoons", "leftrightsquigarrow", "leftskipadaption", "leftsquigarrow", "leftsubguillemot", "leftthreetimes", "lefttopbox", "lefttoright", "lefttorighthbox", "lefttorightvbox", "lefttorightvtop", "leftwavearrow", "leftwhitearrow", "leq", "leqq", "leqslant", "lessapprox", "lessdot", "lesseqgtr", "lesseqqgtr", "lessgtr", "lesssim", "letbeundefined", "letcatcodecommand", "letcscsname", "letcsnamecs", "letcsnamecsname", "letdummyparameter", "letempty", "letgvalue", "letgvalueempty", "letgvalurelax", "letterampersand", "letterat", "letterbackslash", "letterbar", "letterbgroup", "letterclosebrace", "lettercolon", "letterdollar", "letterdoublequote", "letteregroup", "letterescape", "letterexclamationmark", "letterhash", "letterhat", "letterleftbrace", "letterleftbracket", "letterleftparenthesis", "letterless", "lettermore", "letteropenbrace", "letterpercent", "letterquestionmark", "letterrightbrace", "letterrightbracket", "letterrightparenthesis", "lettersinglequote", "letterslash", "letterspacing", "lettertilde", "letterunderscore", "letvalue", "letvalueempty", "letvaluerelax", "lfence", "lfloor", "lgroup", "lhbox", "lhooknwarrow", "lhooksearrow", "limitatefirstline", "limitatelines", "limitatetext", "line", "linefeed", "linenote", "linespanningtext", "linethickness", "linterval", "listcitation", "listcite", "listlength", "listnamespaces", "ljligature", "ll", "llangle", "llap", "llbracket", "llcorner", "lll", "llless", "lmoustache", "lnapprox", "lneq", "lneqq", "lnot", "lnsim", "loadanyfile", "loadanyfileonce", "loadbtxdefinitionfile", "loadbtxreplacementfile", "loadcldfile", "loadcldfileonce", "loadfontgoodies", "loadluafile", "loadluafileonce", "loadspellchecklist", "loadtexfile", "loadtexfileonce", "loadtypescriptfile", "localframed", "localframedwithsettings", "localhsize", "localpopbox", "localpopmacro", "localpushbox", "localpushmacro", "localundefine", "locatedfilepath", "locatefilepath", "locfilename", "logo", "lohi", "lointerval", "lomihi", "longleftarrow", "longleftrightarrow", "longmapsfrom", "longmapsto", "longrightarrow", "longrightsquigarrow", "looparrowleft", "looparrowright", "lor", "low", "lowerbox", "lowercased", "lowercasestring", "lowerleftdoubleninequote", "lowerleftsingleninequote", "lowerrightdoubleninequote", "lowerrightsingleninequote", "lozenge", "lparent", "lrcorner", "lrointerval", "lrtbbox", "lstroke", "lt", "ltimes", "ltop", "luaTeX", "luacode", "luaconditional", "luaenvironment", "luaexpanded", "luaexpr", "luafunction", "luajitTeX", "luamajorversion", "luaminorversion", "luaparameterset", "luasetup", "luaversion", "lvert", "m", "mLeftarrow", "mLeftrightarrow", "mRightarrow", "mainlanguage", "makecharacteractive", "makerawcommalist", "makestrutofbox", "maltese", "mapfontsize", "mapsdown", "mapsfrom", "mapsto", "mapsup", "margindata", "margintext", "markcontent", "marking", "markinjector", "markpage", "mat", "math", "mathampersand", "mathbf", "mathbi", "mathblackboard", "mathbs", "mathdefault", "mathdollar", "mathdouble", "mathematics", "mathfraktur", "mathfunction", "mathhash", "mathhyphen", "mathit", "mathitalic", "mathlabellanguage", "mathlabeltext", "mathlabeltexts", "mathop", "mathover", "mathpercent", "mathrm", "mathscript", "mathsl", "mathss", "mathtext", "mathtextbf", "mathtextbi", "mathtextbs", "mathtextit", "mathtextsl", "mathtexttf", "mathtf", "mathtriplet", "mathtt", "mathunder", "mathupright", "mathword", "mathwordbf", "mathwordbi", "mathwordbs", "mathwordit", "mathwordsl", "mathwordtf", "maxaligned", "mbox", "mcframed", "measure", "measured", "measuredangle", "measuredeq", "medskip", "medspace", "menubutton", "mequal", "message", "metaTeX", "mfence", "mframed", "mfunction", "mfunctionlabeltext", "mhbox", "mho", "mhookleftarrow", "mhookrightarrow", "mid", "midaligned", "middle", "middlealigned", "middlebox", "midhbox", "minimalhbox", "minus", "minuscolon", "mirror", "mixedcaps", "mkvibuffer", "mleftarrow", "mleftharpoondown", "mleftharpoonup", "mleftrightarrow", "mleftrightharpoons", "mmapsto", "models", "moduleparameter", "molecule", "mono", "monobold", "mononormal", "month", "monthlong", "monthshort", "mp", "mprandomnumber", "mrel", "mrightarrow", "mrightharpoondown", "mrightharpoonup", "mrightleftharpoons", "mrightoverleftarrow", "mtext", "mtriplerel", "mtwoheadleftarrow", "mtwoheadrightarrow", "mu", "multimap", "nHdownarrow", "nHuparrow", "nLeftarrow", "nLeftrightarrow", "nRightarrow", "nVDash", "nVdash", "nVleftarrow", "nVleftrightarrow", "nVrightarrow", "nabla", "nacute", "namedheadnumber", "namedstructureheadlocation", "namedstructureuservariable", "namedstructurevariable", "namedtaggedlabeltexts", "napostrophe", "napprox", "napproxEq", "narrownobreakspace", "nasymp", "natural", "naturalhbox", "naturalhpack", "naturalnumbers", "naturalvbox", "naturalvcenter", "naturalvpack", "naturalvtop", "naturalwd", "ncaron", "ncommaaccent", "ncong", "ncurl", "ndivides", "ne", "nearrow", "neg", "negatecolorbox", "negated", "negativesign", "negthinspace", "neng", "neq", "nequiv", "neswarrow", "newattribute", "newcatcodetable", "newcounter", "newevery", "newfrenchspacing", "newmode", "newsignal", "newsystemmode", "nexists", "nextbox", "nextboxdp", "nextboxht", "nextboxhtdp", "nextboxwd", "nextcounter", "nextcountervalue", "nextdepth", "nextparagraphs", "nextrealpage", "nextrealpagenumber", "nextsubcountervalue", "nextsubpage", "nextsubpagenumber", "nextuserpage", "nextuserpagenumber", "ngeq", "ngrave", "ngtr", "ngtrless", "ngtrsim", "ni", "nihongo", "nin", "njligature", "nleftarrow", "nleftrightarrow", "nleq", "nless", "nlessgtr", "nlesssim", "nmid", "nni", "nobar", "nobreakspace", "nocap", "nocitation", "nocite", "nodetostring", "noffigurepages", "noflines", "noflocalfloats", "noheaderandfooterlines", "noheightstrut", "noindentation", "noitem", "nonfrenchspacing", "nonmathematics", "normal", "normalboldface", "normalframedwithsettings", "normalitalicface", "normalizebodyfontsize", "normalizedfontsize", "normalizefontdepth", "normalizefontheight", "normalizefontline", "normalizefontwidth", "normalizetextdepth", "normalizetextheight", "normalizetextline", "normalizetextwidth", "normalslantedface", "normaltypeface", "nospace", "not", "note", "notesymbol", "notin", "notopandbottomlines", "notragged", "nowns", "nparallel", "nprec", "npreccurlyeq", "nrightarrow", "nsim", "nsimeq", "nsqsubseteq", "nsqsupseteq", "nsubset", "nsubseteq", "nsucc", "nsucccurlyeq", "nsupset", "nsupseteq", "ntilde", "ntimes", "ntriangleleft", "ntrianglelefteq", "ntriangleright", "ntrianglerighteq", "nu", "numberofpoints", "numbers", "nvDash", "nvdash", "nvleftarrow", "nvleftrightarrow", "nvrightarrow", "nwarrow", "nwsearrow", "oacute", "obeydepth", "objectdepth", "objectheight", "objectmargin", "objectwidth", "obox", "obreve", "ocaron", "ocircumflex", "ocircumflexacute", "ocircumflexdotbelow", "ocircumflexgrave", "ocircumflexhook", "ocircumflextilde", "odiaeresis", "odiaeresismacron", "odot", "odotaccent", "odotaccentmacron", "odotbelow", "odoublegrave", "oeligature", "offset", "offsetbox", "ograve", "ohm", "ohook", "ohorn", "ohornacute", "ohorndotbelow", "ohorngrave", "ohornhook", "ohorntilde", "ohungarumlaut", "oiiint", "oiint", "oint", "ointclockwise", "ointctrclockwise", "oinvertedbreve", "omacron", "omega", "omicron", "ominus", "onedigitrounding", "oneeighth", "onefifth", "onehalf", "onequarter", "onesixth", "onesuperior", "onethird", "oogonek", "oogonekmacron", "operatorlanguage", "operatortext", "oplus", "ordfeminine", "ordinaldaynumber", "ordinalstr", "ordmasculine", "ornamenttext", "oslash", "ostroke", "ostrokeacute", "otilde", "otildemacron", "otimes", "outputfilename", "outputstreambox", "outputstreamcopy", "outputstreamunvbox", "outputstreamunvcopy", "over", "overbar", "overbars", "overbarunderbar", "overbrace", "overbraceunderbrace", "overbracket", "overbracketunderbracket", "overlaybutton", "overlaycolor", "overlaydepth", "overlayfigure", "overlayheight", "overlaylinecolor", "overlaylinewidth", "overlayoffset", "overlayrollbutton", "overlaywidth", "overleftarrow", "overloaderror", "overparent", "overparentunderparent", "overrightarrow", "overset", "overstrike", "overstrikes", "owns", "page", "pagearea", "pagebreak", "pagefigure", "pagegridspanwidth", "pageinjection", "pagenumber", "pagereference", "pagestaterealpage", "paletsize", "paragraphmark", "parallel", "part", "partial", "pdfTeX", "pdfactualtext", "pdfbackendactualtext", "pdfbackendcurrentresources", "pdfbackendsetcatalog", "pdfbackendsetcolorspace", "pdfbackendsetextgstate", "pdfbackendsetinfo", "pdfbackendsetname", "pdfbackendsetpageattribute", "pdfbackendsetpageresource", "pdfbackendsetpagesattribute", "pdfbackendsetpattern", "pdfbackendsetshade", "pdfcolor", "pdfeTeX", "percent", "percentdimen", "periodcentered", "periods", "permitcaretescape", "permitcircumflexescape", "permitspacesbetweengroups", "perp", "persiandecimals", "persiannumerals", "perthousand", "phantom", "phantombox", "phi", "phook", "pi", "pickupgroupedcommand", "pitchfork", "placeattachments", "placebookmarks", "placebtxrendering", "placechemical", "placecitation", "placecombinedlist", "placecomments", "placecontent", "placecurrentformulanumber", "placedbox", "placefigure", "placefloat", "placefloatwithsetups", "placefootnotes", "placeformula", "placeframed", "placegraphic", "placeheadnumber", "placeheadtext", "placehelp", "placeindex", "placeinitial", "placeintermezzo", "placelayer", "placelayeredtext", "placelegend", "placelist", "placelistofabbreviations", "placelistofchemicals", "placelistoffigures", "placelistofgraphics", "placelistofintermezzi", "placelistoflogos", "placelistofpublications", "placelistofsorts", "placelistofsynonyms", "placelistoftables", "placelocalfootnotes", "placelocalnotes", "placement", "placenamedfloat", "placenamedformula", "placenotes", "placeongrid", "placeontopofeachother", "placepagenumber", "placepairedbox", "placeparallel", "placerawlist", "placeregister", "placerenderingwindow", "placesidebyside", "placesubformula", "placetable", "pm", "popattribute", "popmacro", "popmode", "popsystemmode", "position", "positionoverlay", "positionregionoverlay", "positivesign", "postponenotes", "prec", "precapprox", "preccurlyeq", "preceq", "preceqq", "precnapprox", "precneq", "precneqq", "precnsim", "precsim", "predefinedfont", "predefinefont", "predefinesymbol", "prefixedpagenumber", "prefixlanguage", "prefixtext", "prependetoks", "prependgvalue", "prependtocommalist", "prependtoks", "prependtoksonce", "prependvalue", "presetbtxlabeltext", "presetdocument", "presetfieldsymbols", "presetheadtext", "presetlabeltext", "presetmathlabeltext", "presetoperatortext", "presetprefixtext", "presetsuffixtext", "presettaglabeltext", "presetunittext", "pretocommalist", "prettyprintbuffer", "prevcounter", "prevcountervalue", "preventmode", "prevrealpage", "prevrealpagenumber", "prevsubcountervalue", "prevsubpage", "prevsubpagenumber", "prevuserpage", "prevuserpagenumber", "prime", "primes", "procent", "processMPbuffer", "processMPfigurefile", "processaction", "processallactionsinset", "processassignlist", "processassignmentcommand", "processassignmentlist", "processbetween", "processblocks", "processbodyfontenvironmentlist", "processcolorcomponents", "processcommacommand", "processcommalist", "processcommalistwithparameters", "processcontent", "processfile", "processfilemany", "processfilenone", "processfileonce", "processfirstactioninset", "processisolatedchars", "processisolatedwords", "processlinetablebuffer", "processlinetablefile", "processlist", "processmonth", "processranges", "processseparatedlist", "processtexbuffer", "processtokens", "processuntil", "processxtablebuffer", "processyear", "prod", "product", "profiledbox", "profilegivenbox", "program", "project", "propto", "pseudoMixedCapped", "pseudoSmallCapped", "pseudoSmallcapped", "pseudosmallcapped", "psi", "punctuationspace", "purenumber", "pushattribute", "pushbutton", "pushmacro", "pushmode", "pushoutputstream", "pushsystemmode", "putboxincache", "putnextboxincache", "qquad", "quad", "quadrupleprime", "quads", "quarterstrut", "questiondown", "questionedeq", "quitcommalist", "quitprevcommalist", "quittypescriptscanning", "quotation", "quote", "quotedbl", "quotedblbase", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "quotesingle", "quotesinglebase", "rVert", "racute", "raggedbottom", "raggedcenter", "raggedleft", "raggedright", "raggedwidecenter", "raisebox", "randomizetext", "randomnumber", "rangle", "rationals", "rawcounter", "rawcountervalue", "rawdate", "rawdoifelseinset", "rawdoifinset", "rawdoifinsetelse", "rawgetparameters", "rawprocessaction", "rawprocesscommacommand", "rawprocesscommalist", "rawstructurelistuservariable", "rawsubcountervalue", "rbox", "rbrace", "rbracket", "rcaron", "rceil", "rcommaaccent", "rdoublegrave", "readfile", "readfixfile", "readjobfile", "readlocfile", "readsetfile", "readsysfile", "readtexfile", "readxmlfile", "realSmallCapped", "realSmallcapped", "realpagenumber", "reals", "realsmallcapped", "recursedepth", "recurselevel", "recursestring", "redoconvertfont", "ref", "reference", "referenceprefix", "referring", "registerattachment", "registerctxluafile", "registered", "registerexternalfigure", "registerfontclass", "registerhyphenationexception", "registerhyphenationpattern", "registermenubuttons", "registersort", "registersynonym", "registerunit", "regular", "relatemarking", "relateparameterhandlers", "relaxvalueifundefined", "relbar", "remainingcharacters", "remark", "removebottomthings", "removedepth", "removefromcommalist", "removelastskip", "removelastspace", "removemarkedcontent", "removepunctuation", "removesubstring", "removetoks", "removeunwantedspaces", "replacefeature", "replaceincommalist", "replaceword", "rescan", "rescanwithsetup", "resetMPdrawing", "resetMPenvironment", "resetMPinstance", "resetallattributes", "resetandaddfeature", "resetbar", "resetboxesincache", "resetbreakpoints", "resetbuffer", "resetcharacteralign", "resetcharacterkerning", "resetcharacterspacing", "resetcharacterstripping", "resetcollector", "resetcounter", "resetdigitsmanipulation", "resetdirection", "resetfeature", "resetflag", "resetfontcolorsheme", "resetfontfallback", "resetfontsolution", "resethyphenationfeatures", "resetinjector", "resetinteractionmenu", "resetitaliccorrection", "resetlayer", "resetlocalfloats", "resetmarker", "resetmarking", "resetmode", "resetpagenumber", "resetparallel", "resetpath", "resetpenalties", "resetprofile", "resetrecurselevel", "resetreference", "resetreplacement", "resetscript", "resetsetups", "resetshownsynonyms", "resetsubpagenumber", "resetsymbolset", "resetsystemmode", "resettimer", "resettrackers", "resettrialtypesetting", "resetusedsortings", "resetusedsynonyms", "resetuserpagenumber", "resetvalue", "resetvisualizers", "reshapebox", "resolvedglyphdirect", "resolvedglyphstyled", "restartcounter", "restorebox", "restorecatcodes", "restorecounter", "restorecurrentattributes", "restoreendofline", "restoreglobalbodyfont", "restriction", "reusableMPgraphic", "reuseMPgraphic", "reuserandomseed", "reverseddoubleprime", "reversedprime", "reversedtripleprime", "revivefeature", "rfence", "rfloor", "rgroup", "rhbox", "rho", "rhooknearrow", "rhookswarrow", "right", "rightaligned", "rightangle", "rightarrow", "rightarrowbar", "rightarrowtail", "rightarrowtriangle", "rightbottombox", "rightbox", "rightdasharrow", "rightguillemot", "rightharpoondown", "rightharpoonup", "righthbox", "rightheadtext", "rightlabeltext", "rightleftarrows", "rightleftharpoons", "rightline", "rightmathlabeltext", "rightorleftpageaction", "rightrightarrows", "rightskipadaption", "rightsquigarrow", "rightsubguillemot", "rightthreearrows", "rightthreetimes", "righttoleft", "righttolefthbox", "righttoleftvbox", "righttoleftvtop", "righttopbox", "rightwavearrow", "rightwhitearrow", "ring", "rinterval", "rinvertedbreve", "risingdotseq", "rlap", "rlointerval", "rmoustache", "rneq", "robustaddtocommalist", "robustdoifelseinset", "robustdoifinsetelse", "robustpretocommalist", "rointerval", "rollbutton", "roman", "romanC", "romanD", "romanI", "romanII", "romanIII", "romanIV", "romanIX", "romanL", "romanM", "romanV", "romanVI", "romanVII", "romanVIII", "romanX", "romanXI", "romanXII", "romanc", "romand", "romani", "romanii", "romaniii", "romaniv", "romanix", "romanl", "romanm", "romannumerals", "romanv", "romanvi", "romanvii", "romanviii", "romanx", "romanxi", "romanxii", "rootradical", "rotate", "rparent", "rrangle", "rrbracket", "rrointerval", "rtimes", "rtop", "ruledhbox", "ruledhpack", "ruledmbox", "ruledtopv", "ruledtpack", "ruledvbox", "ruledvpack", "ruledvtop", "runMPbuffer", "runninghbox", "rvert", "sacute", "safechar", "samplefile", "sans", "sansbold", "sansnormal", "sansserif", "savebox", "savebtxdataset", "savebuffer", "savecounter", "savecurrentattributes", "savenormalmeaning", "savetaggedtwopassdata", "savetwopassdata", "sbox", "scale", "scaron", "scedilla", "schwa", "schwahook", "scircumflex", "scommaaccent", "screen", "searrow", "secondoffivearguments", "secondoffourarguments", "secondofsixarguments", "secondofthreearguments", "secondofthreeunexpanded", "secondoftwoarguments", "secondoftwounexpanded", "section", "sectionmark", "seeindex", "select", "selectblocks", "serializecommalist", "serializedcommalist", "serif", "serifbold", "serifnormal", "setJSpreamble", "setMPlayer", "setMPpositiongraphic", "setMPpositiongraphicrange", "setMPtext", "setMPvariable", "setMPvariables", "setbar", "setbigbodyfont", "setboxllx", "setboxlly", "setbreakpoints", "setcapstrut", "setcatcodetable", "setcharacteralign", "setcharactercasing", "setcharactercleaning", "setcharacterkerning", "setcharacterspacing", "setcharacterstripping", "setcharstrut", "setcollector", "setcolormodell", "setcounter", "setcounterown", "setcurrentfontclass", "setdataset", "setdefaultpenalties", "setdigitsmanipulation", "setdirection", "setdocumentargument", "setdocumentargumentdefault", "setdocumentfilename", "setdummyparameter", "setelementexporttag", "setemeasure", "setevalue", "setevariable", "setevariables", "setfirstline", "setflag", "setfont", "setfontcolorsheme", "setfontfeature", "setfontsolution", "setfontstrut", "setgmeasure", "setgvalue", "setgvariable", "setgvariables", "sethboxregister", "sethyphenatedurlafter", "sethyphenatedurlbefore", "sethyphenatedurlnormal", "sethyphenationfeatures", "setinitial", "setinjector", "setinteraction", "setinterfacecommand", "setinterfaceconstant", "setinterfaceelement", "setinterfacemessage", "setinterfacevariable", "setinternalrendering", "setitaliccorrection", "setlayer", "setlayerframed", "setlayertext", "setlinefiller", "setlocalhsize", "setmainbodyfont", "setmainparbuilder", "setmarker", "setmarking", "setmathstyle", "setmeasure", "setmessagetext", "setminus", "setmode", "setnostrut", "setnote", "setnotetext", "setobject", "setoldstyle", "setpagegrid", "setpagereference", "setpagestate", "setpagestaterealpageno", "setpenalties", "setpercentdimen", "setposition", "setpositionbox", "setpositiondata", "setpositiondataplus", "setpositiononly", "setpositionplus", "setpositionstrut", "setprofile", "setrandomseed", "setreference", "setreferencedobject", "setregisterentry", "setreplacement", "setrigidcolumnbalance", "setrigidcolumnhsize", "setscript", "setsectionblock", "setsimplecolumnhsize", "setsmallbodyfont", "setsmallcaps", "setstackbox", "setstructurepageregister", "setstrut", "setsuperiors", "setsystemmode", "settabular", "settaggedmetadata", "settextcontent", "settightobject", "settightreferencedobject", "settightunreferencedobject", "settrialtypesetting", "setuevalue", "setugvalue", "setunreferencedobject", "setup", "setupMPgraphics", "setupMPinstance", "setupMPpage", "setupMPvariables", "setupTABLE", "setupTEXpage", "setupalign", "setupalternativestyles", "setuparranging", "setupattachment", "setupattachments", "setupbackend", "setupbackground", "setupbackgrounds", "setupbar", "setupbars", "setupblackrules", "setupblank", "setupbleeding", "setupblock", "setupbodyfont", "setupbookmark", "setupbottom", "setupbottomtexts", "setupbtx", "setupbtxdataset", "setupbtxlabeltext", "setupbtxlist", "setupbtxregister", "setupbtxrendering", "setupbuffer", "setupbutton", "setupcapitals", "setupcaption", "setupcaptions", "setupcharacterkerning", "setupcharacterspacing", "setupchemical", "setupchemicalframed", "setupclipping", "setupcollector", "setupcolor", "setupcolors", "setupcolumns", "setupcolumnspan", "setupcombination", "setupcombinedlist", "setupcomment", "setupcontent", "setupcounter", "setupdataset", "setupdelimitedtext", "setupdescription", "setupdirections", "setupdocument", "setupeffect", "setupenumeration", "setupenumerations", "setupenv", "setupexport", "setupexternalfigure", "setupexternalsoundtracks", "setupfield", "setupfieldbody", "setupfieldcategory", "setupfieldcontentframed", "setupfieldlabelframed", "setupfields", "setupfieldtotalframed", "setupfiller", "setupfillinlines", "setupfillinrules", "setupfirstline", "setupfittingpage", "setupfloat", "setupfloatcaption", "setupfloats", "setupfloatsplitting", "setupfontexpansion", "setupfontprotrusion", "setupfonts", "setupfontsolution", "setupfooter", "setupfootertexts", "setupforms", "setupformula", "setupformulae", "setupformulaframed", "setupframed", "setupframedcontent", "setupframedtable", "setupframedtablecolumn", "setupframedtablerow", "setupframedtext", "setupframedtexts", "setupglobalreferenceprefix", "setuphead", "setupheadalternative", "setupheader", "setupheadertexts", "setupheadnumber", "setupheads", "setupheadtext", "setuphelp", "setuphigh", "setuphighlight", "setuphyphenation", "setuphyphenmark", "setupindentedtext", "setupindenting", "setupindex", "setupinitial", "setupinsertion", "setupinteraction", "setupinteractionbar", "setupinteractionmenu", "setupinteractionscreen", "setupinterlinespace", "setupitaliccorrection", "setupitemgroup", "setupitemizations", "setupitemize", "setupitems", "setuplabel", "setuplabeltext", "setuplanguage", "setuplayer", "setuplayeredtext", "setuplayout", "setuplayouttext", "setuplegend", "setuplinefiller", "setuplinefillers", "setuplinenote", "setuplinenumbering", "setuplines", "setuplinetable", "setuplinewidth", "setuplist", "setuplistalternative", "setuplistextra", "setuplocalfloats", "setuplocalinterlinespace", "setuplow", "setuplowhigh", "setuplowmidhigh", "setupmakeup", "setupmarginblock", "setupmargindata", "setupmarginframed", "setupmarginrule", "setupmarginrules", "setupmarking", "setupmathalignment", "setupmathcases", "setupmathematics", "setupmathfence", "setupmathfraction", "setupmathfractions", "setupmathframed", "setupmathlabeltext", "setupmathmatrix", "setupmathornament", "setupmathradical", "setupmathstackers", "setupmathstyle", "setupmixedcolumns", "setupmodule", "setupnarrower", "setupnotation", "setupnotations", "setupnote", "setupnotes", "setupoffset", "setupoffsetbox", "setupoperatortext", "setupoppositeplacing", "setupoutputroutine", "setuppagechecker", "setuppagecomment", "setuppagegrid", "setuppagegridarea", "setuppagegridareatext", "setuppagegridlines", "setuppagegridspan", "setuppagegridstart", "setuppageinjection", "setuppageinjectionalternative", "setuppagenumber", "setuppagenumbering", "setuppageshift", "setuppagestate", "setuppagetransitions", "setuppairedbox", "setuppalet", "setuppaper", "setuppapersize", "setupparagraph", "setupparagraphintro", "setupparagraphnumbering", "setupparagraphs", "setupparallel", "setupperiods", "setupplacement", "setuppositionbar", "setuppositioning", "setupprefixtext", "setupprocessor", "setupprofile", "setupprograms", "setupquotation", "setupquote", "setuprealpagenumber", "setupreferenceformat", "setupreferenceprefix", "setupreferencestructureprefix", "setupreferencing", "setupregister", "setupregisters", "setuprenderingwindow", "setuprotate", "setups", "setupscale", "setupscript", "setupscripts", "setupsectionblock", "setupselector", "setupshift", "setupsidebar", "setupsorting", "setupspacing", "setupspellchecking", "setupstartstop", "setupstretched", "setupstruts", "setupstyle", "setupsubformula", "setupsubformulas", "setupsubpagenumber", "setupsuffixtext", "setupsymbolset", "setupsynctex", "setupsynonyms", "setuptables", "setuptabulate", "setuptabulation", "setuptagging", "setuptaglabeltext", "setuptext", "setuptextbackground", "setuptextflow", "setuptextrules", "setuptexttexts", "setupthinrules", "setuptolerance", "setuptooltip", "setuptop", "setuptoptexts", "setuptype", "setuptyping", "setupunit", "setupunittext", "setupurl", "setupuserpagenumber", "setupversion", "setupviewerlayer", "setupvspacing", "setupwhitespace", "setupwithargument", "setupwithargumentswapped", "setupxml", "setupxtable", "setuvalue", "setuxvalue", "setvalue", "setvariable", "setvariables", "setvboxregister", "setvisualizerfont", "setvtopregister", "setwidthof", "setxmeasure", "setxvalue", "setxvariable", "setxvariables", "seveneighths", "sfrac", "shapedhbox", "sharp", "shiftdown", "shiftup", "showallmakeup", "showattributes", "showbodyfont", "showbodyfontenvironment", "showboxes", "showbtxdatasetauthors", "showbtxdatasetcompleteness", "showbtxdatasetfields", "showbtxfields", "showbtxhashedauthors", "showbtxtables", "showchardata", "showcharratio", "showcolor", "showcolorbar", "showcolorcomponents", "showcolorgroup", "showcolorset", "showcolorstruts", "showcounter", "showdirectives", "showdirsinmargin", "showedebuginfo", "showexperiments", "showfont", "showfontdata", "showfontitalics", "showfontkerns", "showfontparameters", "showfontstrip", "showfontstyle", "showframe", "showglyphs", "showgrid", "showgridsnapping", "showhelp", "showhyphenationtrace", "showhyphens", "showinjector", "showjustification", "showkerning", "showlayout", "showlayoutcomponents", "showligature", "showligatures", "showlogcategories", "showmakeup", "showmargins", "showmessage", "showminimalbaseline", "shownextbox", "showotfcomposition", "showpalet", "showparentchain", "showprint", "showsetups", "showsetupsdefinition", "showstruts", "showsymbolset", "showtimer", "showtokens", "showtrackers", "showvalue", "showvariable", "showwarning", "sigma", "sim", "simeq", "simplealignedbox", "simplealignedboxplus", "simplealignedspreadbox", "simplegroupedcommand", "simplereversealignedbox", "simplereversealignedboxplus", "singalcharacteralign", "singlebond", "singleverticalbar", "sixperemspace", "sixthofsixarguments", "slanted", "slantedbold", "slantedface", "slash", "slicepages", "slong", "slovenianNumerals", "sloveniannumerals", "small", "smallbodyfont", "smallbold", "smallbolditalic", "smallboldslanted", "smallcappedcharacters", "smallcappedromannumerals", "smaller", "smallitalicbold", "smallnormal", "smallskip", "smallslanted", "smallslantedbold", "smalltype", "smash", "smashbox", "smashboxed", "smashedhbox", "smashedvbox", "smile", "snaptogrid", "softhyphen", "solidus", "someheadnumber", "somekindoftab", "someline", "somelocalfloat", "somenamedheadnumber", "someplace", "somewhere", "space", "spadesuit", "spanishNumerals", "spanishnumerals", "speech", "sphericalangle", "splitatasterisk", "splitatcolon", "splitatcolons", "splitatcomma", "splitatperiod", "splitdfrac", "splitfilename", "splitfloat", "splitfrac", "splitoffbase", "splitofffull", "splitoffkind", "splitoffname", "splitoffpath", "splitoffroot", "splitofftokens", "splitofftype", "splitstring", "spreadhbox", "sqcap", "sqcup", "sqrt", "sqsubset", "sqsubseteq", "sqsubsetneq", "sqsupset", "sqsupseteq", "sqsupsetneq", "square", "squaredots", "ssharp", "stackrel", "star", "stareq", "startJScode", "startJSpreamble", "startLUA", "startMP", "startMPclip", "startMPcode", "startMPdefinitions", "startMPdrawing", "startMPenvironment", "startMPextensions", "startMPinclusions", "startMPinitializations", "startMPpage", "startMPpositiongraphic", "startMPpositionmethod", "startMPrun", "startPARSEDXML", "startTABLE", "startTABLEbody", "startTABLEfoot", "startTABLEhead", "startTABLEnext", "startTC", "startTD", "startTDs", "startTEX", "startTEXpage", "startTH", "startTN", "startTR", "startTRs", "startTX", "startTY", "startXML", "startalign", "startalignment", "startallmodes", "startappendices", "startarrangedpages", "startaside", "startattachment", "startbackground", "startbackmatter", "startbar", "startbbordermatrix", "startbitmapimage", "startblockquote", "startbodymatter", "startbordermatrix", "startboxedcolumns", "startbtxlabeltext", "startbtxrenderingdefinitions", "startbuffer", "startcases", "startcatcodetable", "startcenteraligned", "startchapter", "startcharacteralign", "startcheckedfences", "startchemical", "startchemicaltext", "startcollect", "startcollecting", "startcolor", "startcolorintent", "startcoloronly", "startcolorset", "startcolumns", "startcolumnspan", "startcombination", "startcomment", "startcomponent", "startcontextcode", "startcontextdefinitioncode", "startctxfunction", "startctxfunctiondefinition", "startcurrentcolor", "startcurrentlistentrywrapper", "startdelimited", "startdelimitedtext", "startdisplaymath", "startdmath", "startdocument", "starteffect", "startelement", "startembeddedxtable", "startendnote", "startendofline", "startenvironment", "startexceptions", "startexpanded", "startexpandedcollect", "startextendedcatcodetable", "startexternalfigurecollection", "startfact", "startfigure", "startfiguretext", "startfittingpage", "startfixed", "startfloatcombination", "startfont", "startfontclass", "startfontsolution", "startfootnote", "startformula", "startformulas", "startframed", "startframedcell", "startframedcontent", "startframedrow", "startframedtable", "startframedtext", "startfrontmatter", "startgoto", "startgraphictext", "startgridsnapping", "starthanging", "starthbox", "starthboxestohbox", "starthboxregister", "starthead", "startheadtext", "starthelptext", "starthiding", "starthighlight", "starthyphenation", "startimath", "startindentation", "startindentedtext", "startinteraction", "startinteractionmenu", "startinterface", "startintermezzotext", "startintertext", "startitem", "startitemgroup", "startitemgroupcolumns", "startitemize", "startknockout", "startlabeltext", "startlayout", "startleftaligned", "startlegend", "startline", "startlinealignment", "startlinecorrection", "startlinefiller", "startlinenote", "startlinenumbering", "startlines", "startlinetable", "startlinetablebody", "startlinetablecell", "startlinetablehead", "startlocalfootnotes", "startlocalheadsetup", "startlocallinecorrection", "startlocalnotes", "startlocalsetups", "startlua", "startluacode", "startluaparameterset", "startluasetups", "startmakeup", "startmarginblock", "startmarginrule", "startmarkedcontent", "startmathalignment", "startmathcases", "startmathlabeltext", "startmathmatrix", "startmathmode", "startmathstyle", "startmatrices", "startmatrix", "startmaxaligned", "startmdformula", "startmidaligned", "startmiddlealigned", "startmiddlemakeup", "startmixedcolumns", "startmode", "startmodeset", "startmodule", "startmoduletestsection", "startmpformula", "startnamedsection", "startnamedsubformulas", "startnarrow", "startnarrower", "startnegative", "startnicelyfilledbox", "startnointerference", "startnotallmodes", "startnotext", "startnotmode", "startoperatortext", "startopposite", "startoutputstream", "startoverlay", "startoverprint", "startpacked", "startpagecomment", "startpagefigure", "startpagegrid", "startpagegridspan", "startpagelayout", "startpagemakeup", "startpar", "startparagraph", "startparagraphs", "startparagraphscell", "startparbuilder", "startpart", "startpath", "startplacechemical", "startplacefigure", "startplacefloat", "startplaceformula", "startplacegraphic", "startplaceintermezzo", "startplacelegend", "startplacepairedbox", "startplacetable", "startpositioning", "startpositionoverlay", "startpositive", "startpostponing", "startprefixtext", "startprocessassignmentcommand", "startprocessassignmentlist", "startprocesscommacommand", "startprocesscommalist", "startproduct", "startproject", "startprotect", "startprotectedcolors", "startpublication", "startpunctuation", "startquotation", "startquote", "startrandomized", "startrandomseed", "startrawsetups", "startreadingfile", "startreferenceprefix", "startregime", "startregister", "startreusableMPgraphic", "startrightaligned", "startscript", "startsdformula", "startsection", "startsectionblock", "startsectionblockenvironment", "startsectionlevel", "startsetups", "startshapebox", "startshift", "startsidebar", "startsimplecolumns", "startspecialitem", "startspeech", "startspformula", "startspread", "startstandardmakeup", "startstartstop", "startstaticMPfigure", "startstaticMPgraphic", "startstrictinspectnextcharacter", "startstructurepageregister", "startstrut", "startstyle", "startsubformulas", "startsubject", "startsubjectlevel", "startsubsection", "startsubsentence", "startsubstack", "startsubsubject", "startsubsubsection", "startsubsubsubject", "startsubsubsubsection", "startsubsubsubsubject", "startsubsubsubsubsection", "startsubsubsubsubsubject", "startsuffixtext", "startsymbolset", "starttable", "starttablehead", "starttables", "starttabletail", "starttabletext", "starttabulate", "starttabulatehead", "starttabulatetail", "starttagged", "starttaglabeltext", "starttexcode", "starttexdefinition", "starttext", "starttextbackground", "starttextbackgroundmanual", "starttextcolor", "starttextcolorintent", "starttextflow", "starttextmakeup", "starttextrule", "starttitle", "starttokens", "starttransparent", "starttypescript", "starttypescriptcollection", "starttyping", "startuniqueMPgraphic", "startuniqueMPpagegraphic", "startunittext", "startunpacked", "startusableMPgraphic", "startuseMPgraphic", "startusemathstyleparameter", "startusingbtxspecification", "startvbox", "startvboxregister", "startvboxtohbox", "startvboxtohboxseparator", "startviewerlayer", "startvtop", "startvtopregister", "startxcell", "startxcellgroup", "startxgroup", "startxmldisplayverbatim", "startxmlinlineverbatim", "startxmlraw", "startxmlsetups", "startxrow", "startxrowgroup", "startxtable", "startxtablebody", "startxtablefoot", "startxtablehead", "startxtablenext", "stligature", "stopJScode", "stopJSpreamble", "stopLUA", "stopMP", "stopMPclip", "stopMPcode", "stopMPdefinitions", "stopMPdrawing", "stopMPenvironment", "stopMPextensions", "stopMPinclusions", "stopMPinitializations", "stopMPpage", "stopMPpositiongraphic", "stopMPpositionmethod", "stopMPrun", "stopPARSEDXML", "stopTABLE", "stopTABLEbody", "stopTABLEfoot", "stopTABLEhead", "stopTABLEnext", "stopTC", "stopTD", "stopTDs", "stopTEX", "stopTEXpage", "stopTH", "stopTN", "stopTR", "stopTRs", "stopTX", "stopTY", "stopXML", "stopalign", "stopalignment", "stopallmodes", "stopappendices", "stoparrangedpages", "stopaside", "stopattachment", "stopbackground", "stopbackmatter", "stopbar", "stopbbordermatrix", "stopbitmapimage", "stopblockquote", "stopbodymatter", "stopbordermatrix", "stopboxedcolumns", "stopbtxlabeltext", "stopbtxrenderingdefinitions", "stopbuffer", "stopcases", "stopcatcodetable", "stopcenteraligned", "stopchapter", "stopcharacteralign", "stopcheckedfences", "stopchemical", "stopchemicaltext", "stopcollect", "stopcollecting", "stopcolor", "stopcolorintent", "stopcoloronly", "stopcolorset", "stopcolumns", "stopcolumnspan", "stopcombination", "stopcomment", "stopcomponent", "stopcontextcode", "stopcontextdefinitioncode", "stopctxfunction", "stopctxfunctiondefinition", "stopcurrentcolor", "stopcurrentlistentrywrapper", "stopdelimited", "stopdelimitedtext", "stopdisplaymath", "stopdmath", "stopdocument", "stopeffect", "stopelement", "stopembeddedxtable", "stopendnote", "stopendofline", "stopenvironment", "stopexceptions", "stopexpanded", "stopexpandedcollect", "stopextendedcatcodetable", "stopexternalfigurecollection", "stopfact", "stopfigure", "stopfiguretext", "stopfittingpage", "stopfixed", "stopfloatcombination", "stopfont", "stopfontclass", "stopfontsolution", "stopfootnote", "stopformula", "stopformulas", "stopframed", "stopframedcell", "stopframedcontent", "stopframedrow", "stopframedtable", "stopframedtext", "stopfrontmatter", "stopgoto", "stopgraphictext", "stopgridsnapping", "stophanging", "stophbox", "stophboxestohbox", "stophboxregister", "stophead", "stopheadtext", "stophelptext", "stophiding", "stophighlight", "stophyphenation", "stopimath", "stopindentation", "stopindentedtext", "stopinteraction", "stopinteractionmenu", "stopinterface", "stopintermezzotext", "stopintertext", "stopitem", "stopitemgroup", "stopitemgroupcolumns", "stopitemize", "stopknockout", "stoplabeltext", "stoplayout", "stopleftaligned", "stoplegend", "stopline", "stoplinealignment", "stoplinecorrection", "stoplinefiller", "stoplinenote", "stoplinenumbering", "stoplines", "stoplinetable", "stoplinetablebody", "stoplinetablecell", "stoplinetablehead", "stoplocalfootnotes", "stoplocalheadsetup", "stoplocallinecorrection", "stoplocalnotes", "stoplocalsetups", "stoplua", "stopluacode", "stopluaparameterset", "stopluasetups", "stopmakeup", "stopmarginblock", "stopmarginrule", "stopmarkedcontent", "stopmathalignment", "stopmathcases", "stopmathlabeltext", "stopmathmatrix", "stopmathmode", "stopmathstyle", "stopmatrices", "stopmatrix", "stopmaxaligned", "stopmdformula", "stopmidaligned", "stopmiddlealigned", "stopmiddlemakeup", "stopmixedcolumns", "stopmode", "stopmodeset", "stopmodule", "stopmoduletestsection", "stopmpformula", "stopnamedsection", "stopnamedsubformulas", "stopnarrow", "stopnarrower", "stopnegative", "stopnicelyfilledbox", "stopnointerference", "stopnotallmodes", "stopnotext", "stopnotmode", "stopoperatortext", "stopopposite", "stopoutputstream", "stopoverlay", "stopoverprint", "stoppacked", "stoppagecomment", "stoppagefigure", "stoppagegrid", "stoppagegridspan", "stoppagelayout", "stoppagemakeup", "stoppar", "stopparagraph", "stopparagraphs", "stopparagraphscell", "stopparbuilder", "stoppart", "stoppath", "stopplacechemical", "stopplacefigure", "stopplacefloat", "stopplaceformula", "stopplacegraphic", "stopplaceintermezzo", "stopplacelegend", "stopplacepairedbox", "stopplacetable", "stoppositioning", "stoppositionoverlay", "stoppositive", "stoppostponing", "stopprefixtext", "stopprocessassignmentcommand", "stopprocessassignmentlist", "stopprocesscommacommand", "stopprocesscommalist", "stopproduct", "stopproject", "stopprotect", "stopprotectedcolors", "stoppublication", "stoppunctuation", "stopquotation", "stopquote", "stoprandomized", "stoprandomseed", "stoprawsetups", "stopreadingfile", "stopreferenceprefix", "stopregime", "stopregister", "stopreusableMPgraphic", "stoprightaligned", "stopscript", "stopsdformula", "stopsection", "stopsectionblock", "stopsectionblockenvironment", "stopsectionlevel", "stopsetups", "stopshapebox", "stopshift", "stopsidebar", "stopsimplecolumns", "stopspecialitem", "stopspeech", "stopspformula", "stopspread", "stopstandardmakeup", "stopstartstop", "stopstaticMPfigure", "stopstaticMPgraphic", "stopstrictinspectnextcharacter", "stopstructurepageregister", "stopstrut", "stopstyle", "stopsubformulas", "stopsubject", "stopsubjectlevel", "stopsubsection", "stopsubsentence", "stopsubstack", "stopsubsubject", "stopsubsubsection", "stopsubsubsubject", "stopsubsubsubsection", "stopsubsubsubsubject", "stopsubsubsubsubsection", "stopsubsubsubsubsubject", "stopsuffixtext", "stopsymbolset", "stoptable", "stoptablehead", "stoptables", "stoptabletail", "stoptabletext", "stoptabulate", "stoptabulatehead", "stoptabulatetail", "stoptagged", "stoptaglabeltext", "stoptexcode", "stoptexdefinition", "stoptext", "stoptextbackground", "stoptextbackgroundmanual", "stoptextcolor", "stoptextcolorintent", "stoptextflow", "stoptextmakeup", "stoptextrule", "stoptitle", "stoptokens", "stoptransparent", "stoptypescript", "stoptypescriptcollection", "stoptyping", "stopuniqueMPgraphic", "stopuniqueMPpagegraphic", "stopunittext", "stopunpacked", "stopusableMPgraphic", "stopuseMPgraphic", "stopusemathstyleparameter", "stopusingbtxspecification", "stopvbox", "stopvboxregister", "stopvboxtohbox", "stopvboxtohboxseparator", "stopviewerlayer", "stopvtop", "stopvtopregister", "stopxcell", "stopxcellgroup", "stopxgroup", "stopxmldisplayverbatim", "stopxmlinlineverbatim", "stopxmlraw", "stopxmlsetups", "stopxrow", "stopxrowgroup", "stopxtable", "stopxtablebody", "stopxtablefoot", "stopxtablehead", "stopxtablenext", "stretched", "strictdoifelsenextoptional", "strictdoifnextoptionalelse", "stripcharacter", "strippedcsname", "stripspaces", "structurelistuservariable", "structurenumber", "structuretitle", "structureuservariable", "structurevariable", "strut", "strutdp", "strutht", "struthtdp", "struttedbox", "strutwd", "style", "styleinstance", "subject", "subpagenumber", "subsection", "subsentence", "subset", "subseteq", "subseteqq", "subsetneq", "subsetneqq", "substituteincommalist", "subsubject", "subsubsection", "subsubsubject", "subsubsubsection", "subsubsubsubject", "subsubsubsubsection", "subsubsubsubsubject", "subtractfeature", "succ", "succapprox", "succcurlyeq", "succeq", "succeqq", "succnapprox", "succneq", "succneqq", "succnsim", "succsim", "suffixlanguage", "suffixtext", "sum", "supset", "supseteq", "supseteqq", "supsetneq", "supsetneqq", "surd", "surdradical", "swapcounts", "swapdimens", "swapface", "swapmacros", "swaptypeface", "swarrow", "switchstyleonly", "switchtobodyfont", "switchtocolor", "switchtointerlinespace", "symbol", "symbolreference", "synchronizeblank", "synchronizeindenting", "synchronizemarking", "synchronizeoutputstreams", "synchronizestrut", "synchronizewhitespace", "synctexblockfilename", "synctexresetfilename", "synctexsetfilename", "systemlog", "systemlogfirst", "systemloglast", "systemsetups", "tLeftarrow", "tLeftrightarrow", "tRightarrow", "tabulateautoline", "tabulateautorule", "tabulateline", "tabulaterule", "taggedctxcommand", "taggedlabeltexts", "taglabellanguage", "taglabeltext", "tau", "tbinom", "tbox", "tcaron", "tcedilla", "tcommaaccent", "tcurl", "tequal", "test", "testandsplitstring", "testcolumn", "testfeature", "testfeatureonce", "testpage", "testpageonly", "testpagesync", "testtokens", "tex", "texdefinition", "texsetup", "textAngstrom", "textacute", "textampersand", "textasciicircum", "textasciitilde", "textat", "textbackslash", "textbar", "textbottomcomma", "textbottomdot", "textbraceleft", "textbraceright", "textbreve", "textbrokenbar", "textbullet", "textcaron", "textcedilla", "textcelsius", "textcent", "textcircledP", "textcircumflex", "textcitation", "textcite", "textcomma", "textcontrolspace", "textcurrency", "textdag", "textddag", "textdegree", "textdiaeresis", "textdiv", "textdollar", "textdong", "textdotaccent", "textellipsis", "texteuro", "textflowcollector", "textfraction", "textgrave", "texthash", "texthorizontalbar", "texthungarumlaut", "texthyphen", "textkelvin", "textlognot", "textmacron", "textmath", "textmho", "textminus", "textmu", "textmultiply", "textnumero", "textogonek", "textohm", "textormathchar", "textounce", "textpercent", "textperiod", "textplus", "textpm", "textreference", "textring", "textrule", "textslash", "textsterling", "texttilde", "textunderscore", "textvisiblespace", "textyen", "thai", "thainumerals", "thefirstcharacter", "thenormalizedbodyfontsize", "therefore", "theremainingcharacters", "theta", "thickspace", "thinrule", "thinrules", "thinspace", "thirdoffivearguments", "thirdoffourarguments", "thirdofsixarguments", "thirdofthreearguments", "thirdofthreeunexpanded", "thook", "thookleftarrow", "thookrightarrow", "thorn", "threedigitrounding", "threeeighths", "threefifths", "threeperemspace", "threequarter", "threesuperior", "tibetannumerals", "tightlayer", "tilde", "times", "tinyfont", "title", "tlap", "tleftarrow", "tleftharpoondown", "tleftharpoonup", "tleftrightarrow", "tleftrightharpoons", "tmapsto", "to", "tochar", "tolinenote", "tooltip", "top", "topbox", "topleftbox", "toplinebox", "toprightbox", "topskippedbox", "tracecatcodetables", "tracedfontname", "traceoutputroutines", "tracepositions", "trademark", "translate", "transparencycomponents", "transparent", "trel", "triangle", "triangledown", "triangleleft", "triangleq", "triangleright", "trightarrow", "trightharpoondown", "trightharpoonup", "trightleftharpoons", "trightoverleftarrow", "triplebond", "tripleprime", "tripleverticalbar", "truefilename", "truefontname", "tstroke", "ttraggedright", "ttriplerel", "ttwoheadleftarrow", "ttwoheadrightarrow", "turnediota", "twodigitrounding", "twofifths", "twoheaddownarrow", "twoheadleftarrow", "twoheadrightarrow", "twoheadrightarrowtail", "twoheaduparrow", "twosuperior", "twothirds", "tx", "txx", "typ", "type", "typebuffer", "typedefinedbuffer", "typeface", "typefile", "typeinlinebuffer", "typescriptone", "typescriptprefix", "typescriptthree", "typescripttwo", "typesetbuffer", "typesetfile", "uacute", "ubreve", "ucaron", "ucircumflex", "uconvertnumber", "udiaeresis", "udiaeresisacute", "udiaeresiscaron", "udiaeresisgrave", "udiaeresismacron", "udotbelow", "udots", "udoublegrave", "uedcatcodecommand", "ugrave", "uhook", "uhorn", "uhornacute", "uhorndotbelow", "uhorngrave", "uhornhook", "uhorntilde", "uhungarumlaut", "uinvertedbreve", "ulcorner", "umacron", "undefinevalue", "undepthed", "underbar", "underbars", "underbrace", "underbracket", "underdash", "underdashes", "underdot", "underdots", "underleftarrow", "underparent", "underrandom", "underrandoms", "underrightarrow", "underset", "understrike", "understrikes", "undoassign", "unexpandeddocumentvariable", "unframed", "unhhbox", "unihex", "uniqueMPgraphic", "uniqueMPpagegraphic", "unit", "unitlanguage", "unitshigh", "unitslow", "unittext", "unknown", "unprotected", "unregisterhyphenationpattern", "unspaceafter", "unspaceargument", "unspaced", "unspacestring", "untexargument", "untexcommand", "uogonek", "upand", "uparrow", "updasharrow", "updownarrow", "updownarrowbar", "updownarrows", "upharpoonleft", "upharpoonright", "uplus", "uppercased", "uppercasestring", "upperleftdoubleninequote", "upperleftdoublesixquote", "upperleftsingleninequote", "upperleftsinglesixquote", "upperrightdoubleninequote", "upperrightdoublesixquote", "upperrightsingleninequote", "upperrightsinglesixquote", "upsilon", "upuparrows", "upwhitearrow", "urcorner", "uring", "url", "useJSscripts", "useMPenvironmentbuffer", "useMPgraphic", "useMPlibrary", "useMPrun", "useMPvariables", "useURL", "usealignparameter", "useblankparameter", "useblocks", "usebodyfont", "usebodyfontparameter", "usebtxdataset", "usebtxdefinitions", "usecitation", "usecolors", "usecomponent", "usedirectory", "usedummycolorparameter", "usedummystyleandcolor", "usedummystyleparameter", "useenvironment", "useexternaldocument", "useexternalfigure", "useexternalrendering", "useexternalsoundtrack", "usefigurebase", "usefile", "usegridparameter", "useindentingparameter", "useindentnextparameter", "useinterlinespaceparameter", "uselanguageparameter", "useluamodule", "usemathstyleparameter", "usemodule", "useproduct", "useprofileparameter", "useproject", "usereferenceparameter", "userpagenumber", "usesetupsparameter", "usestaticMPfigure", "usesubpath", "usesymbols", "usetexmodule", "usetypescript", "usetypescriptfile", "useurl", "usezipfile", "utfchar", "utflower", "utfupper", "utilde", "utilityregisterlength", "vDash", "varTheta", "varepsilon", "varkappa", "varnothing", "varphi", "varpi", "varrho", "varsigma", "vartheta", "vboxreference", "vdash", "vdots", "vec", "vee", "veebar", "veeeq", "verbatim", "verbatimstring", "verbosenumber", "version", "vert", "verticalgrowingbar", "verticalpositionbar", "veryraggedcenter", "veryraggedleft", "veryraggedright", "vglue", "viewerlayer", "vl", "vphantom", "vpos", "vsmash", "vsmashbox", "vsmashed", "vspace", "vspacing", "wcircumflex", "wdofstring", "wedge", "wedgeeq", "weekday", "whitearrowupfrombar", "widehat", "widetilde", "widthofstring", "widthspanningtext", "withoutpt", "word", "wordright", "words", "wordtonumber", "wp", "wr", "writebetweenlist", "writedatatolist", "writestatus", "writetolist", "xLeftarrow", "xLeftrightarrow", "xRightarrow", "xdefconvertedargument", "xequal", "xfrac", "xhookleftarrow", "xhookrightarrow", "xi", "xleftarrow", "xleftharpoondown", "xleftharpoonup", "xleftrightarrow", "xleftrightharpoons", "xmapsto", "xmladdindex", "xmlafterdocumentsetup", "xmlaftersetup", "xmlall", "xmlappenddocumentsetup", "xmlappendsetup", "xmlapplyselectors", "xmlatt", "xmlattdef", "xmlattribute", "xmlattributedef", "xmlbadinclusions", "xmlbeforedocumentsetup", "xmlbeforesetup", "xmlchainatt", "xmlchainattdef", "xmlchecknamespace", "xmlcommand", "xmlconcat", "xmlconcatrange", "xmlcontext", "xmlcount", "xmldefaulttotext", "xmldirectives", "xmldirectivesafter", "xmldirectivesbefore", "xmldisplayverbatim", "xmldoif", "xmldoifelse", "xmldoifelseempty", "xmldoifelseselfempty", "xmldoifelsetext", "xmldoifelsevalue", "xmldoifnot", "xmldoifnotselfempty", "xmldoifnottext", "xmldoifselfempty", "xmldoiftext", "xmlelement", "xmlfilter", "xmlfirst", "xmlflush", "xmlflushcontext", "xmlflushdocumentsetups", "xmlflushlinewise", "xmlflushpure", "xmlflushspacewise", "xmlflushtext", "xmlinclude", "xmlinclusion", "xmlinclusions", "xmlinfo", "xmlinjector", "xmlinlineprettyprint", "xmlinlineprettyprinttext", "xmlinlineverbatim", "xmlinstalldirective", "xmllast", "xmllastatt", "xmllastmatch", "xmlloadbuffer", "xmlloaddata", "xmlloaddirectives", "xmlloadfile", "xmlloadonly", "xmlmain", "xmlmapvalue", "xmlname", "xmlnamespace", "xmlnonspace", "xmlpath", "xmlpos", "xmlposition", "xmlprependdocumentsetup", "xmlprependsetup", "xmlprettyprint", "xmlprettyprinttext", "xmlprocessbuffer", "xmlprocessdata", "xmlprocessfile", "xmlpure", "xmlraw", "xmlrefatt", "xmlregistereddocumentsetups", "xmlregisteredsetups", "xmlregisterns", "xmlremapname", "xmlremapnamespace", "xmlremovedocumentsetup", "xmlremovesetup", "xmlresetdocumentsetups", "xmlresetinjectors", "xmlresetsetups", "xmlsave", "xmlsetentity", "xmlsetfunction", "xmlsetinjectors", "xmlsetsetup", "xmlsetup", "xmlshow", "xmlsnippet", "xmlstrip", "xmlstripnolines", "xmlstripped", "xmlstrippednolines", "xmltag", "xmltexentity", "xmltext", "xmltobuffer", "xmltobufferverbose", "xmltofile", "xmlvalue", "xmlverbatim", "xrel", "xrightarrow", "xrightharpoondown", "xrightharpoonup", "xrightleftharpoons", "xrightoverleftarrow", "xsplitstring", "xtriplerel", "xtwoheadleftarrow", "xtwoheadrightarrow", "xxfrac", "xypos", "yacute", "ycircumflex", "ydiaeresis", "ydotbelow", "yen", "ygrave", "yhook", "ymacron", "ytilde", "zacute", "zcaron", "zdotaccent", "zerowidthnobreakspace", "zerowidthspace", "zeta", "zhook", "zstroke", "zwj", "zwnj" },
+ ["common"]={ "AEacute", "AEligature", "AEmacron", "AMSTEX", "Aacute", "Abreve", "Abreveacute", "Abrevedotbelow", "Abrevegrave", "Abrevehook", "Abrevetilde", "Acaron", "Acircumflex", "Acircumflexacute", "Acircumflexdotbelow", "Acircumflexgrave", "Acircumflexhook", "Acircumflextilde", "Adiaeresis", "Adiaeresismacron", "Adotaccent", "Adotaccentmacron", "Adotbelow", "Adoublegrave", "AfterPar", "Agrave", "Ahook", "Ainvertedbreve", "Alpha", "Alphabeticnumerals", "AmSTeX", "Amacron", "And", "Angstrom", "Aogonek", "Aring", "Aringacute", "Arrowvert", "Astroke", "Atilde", "BeforePar", "Beta", "Bhook", "Big", "Bigg", "Biggl", "Biggm", "Biggr", "Bigl", "Bigm", "Bigr", "Box", "Bumpeq", "CONTEXT", "Cacute", "Cap", "Caps", "Ccaron", "Ccedilla", "Ccircumflex", "Cdotaccent", "Character", "Characters", "Chi", "Chook", "ConTeXt", "Context", "ConvertConstantAfter", "ConvertToConstant", "Cstroke", "Cup", "DZcaronligature", "DZligature", "Dafrican", "Dcaron", "Ddownarrow", "Delta", "Dhook", "Doteq", "Downarrow", "Dstroke", "Dzcaronligature", "Dzligature", "ETEX", "Eacute", "Ebreve", "Ecaron", "Ecedilla", "Ecircumflex", "Ecircumflexacute", "Ecircumflexdotbelow", "Ecircumflexgrave", "Ecircumflexhook", "Ecircumflextilde", "Ediaeresis", "Edotaccent", "Edotbelow", "Edoublegrave", "Egrave", "Ehook", "Einvertedbreve", "Emacron", "Eogonek", "Epsilon", "Eta", "Eth", "Etilde", "Eulerconst", "EveryLine", "EveryPar", "Fhook", "Finv", "Gacute", "Game", "Gamma", "Gbreve", "Gcaron", "Gcircumflex", "Gcommaaccent", "Gdotaccent", "GetPar", "Ghook", "GotoPar", "Greeknumerals", "Gstroke", "Hat", "Hcaron", "Hcircumflex", "Hstroke", "IJligature", "INRSTEX", "Iacute", "Ibreve", "Icaron", "Icircumflex", "Idiaeresis", "Idotaccent", "Idotbelow", "Idoublegrave", "Igrave", "Ihook", "Iinvertedbreve", "Im", "Imacron", "Iogonek", "Iota", "Istroke", "Itilde", "Jcircumflex", "Join", "Kappa", "Kcaron", "Kcommaaccent", "Khook", "LAMSTEX", "LATEX", "LJligature", "LUAJITTEX", "LUATEX", "LaTeX", "Lacute", "LamSTeX", "Lambda", "Lbar", "Lcaron", "Lcommaaccent", "Ldotmiddle", "Ldsh", "Leftarrow", "Leftrightarrow", "Ljligature", "Lleftarrow", "Longleftarrow", "Longleftrightarrow", "Longmapsfrom", "Longmapsto", "Longrightarrow", "Lsh", "Lstroke", "Lua", "LuaTeX", "LuajitTeX", "METAFONT", "METAFUN", "METAPOST", "MKII", "MKIV", "MKIX", "MKVI", "MKXI", "MONTH", "MONTHLONG", "MONTHSHORT", "MPII", "MPIV", "MPVI", "MPanchor", "MPbetex", "MPc", "MPcode", "MPcolor", "MPcoloronly", "MPcolumn", "MPd", "MPdrawing", "MPfontsizehskip", "MPgetmultipars", "MPgetmultishape", "MPgetposboxes", "MPh", "MPinclusions", "MPleftskip", "MPll", "MPlr", "MPls", "MPmenubuttons", "MPn", "MPoptions", "MPoverlayanchor", "MPp", "MPpage", "MPpardata", "MPplus", "MPpos", "MPpositiongraphic", "MPposset", "MPr", "MPrawvar", "MPregion", "MPrest", "MPrightskip", "MPrs", "MPstring", "MPtext", "MPtransparency", "MPul", "MPur", "MPv", "MPvar", "MPvariable", "MPvv", "MPw", "MPwhd", "MPx", "MPxy", "MPxywhd", "MPy", "Mapsfrom", "Mapsto", "MetaFont", "MetaFun", "MetaPost", "Mu", "NJligature", "Nacute", "Ncaron", "Ncommaaccent", "Nearrow", "Neng", "Ngrave", "Njligature", "NormalizeFontHeight", "NormalizeFontWidth", "NormalizeTextHeight", "NormalizeTextWidth", "Ntilde", "Nu", "Numbers", "Nwarrow", "OEligature", "Oacute", "Obreve", "Ocaron", "Ocircumflex", "Ocircumflexacute", "Ocircumflexdotbelow", "Ocircumflexgrave", "Ocircumflexhook", "Ocircumflextilde", "Odiaeresis", "Odiaeresismacron", "Odotaccent", "Odotaccentmacron", "Odotbelow", "Odoublegrave", "Ograve", "Ohook", "Ohorn", "Ohornacute", "Ohorndotbelow", "Ohorngrave", "Ohornhook", "Ohorntilde", "Ohungarumlaut", "Oinvertedbreve", "Omacron", "Omega", "Omicron", "Oogonek", "Oogonekmacron", "Ostroke", "Ostrokeacute", "Otilde", "Otildemacron", "P", "PDFETEX", "PDFTEX", "PDFcolor", "PICTEX", "PPCHTEX", "PPCHTeX", "PRAGMA", "Phi", "Phook", "Pi", "PiCTeX", "Plankconst", "PointsToBigPoints", "PointsToReal", "PointsToWholeBigPoints", "PropertyLine", "Psi", "PtToCm", "Racute", "Rcaron", "Rcommaaccent", "Rdoublegrave", "Rdsh", "Re", "ReadFile", "Relbar", "Rho", "Rightarrow", "Rinvertedbreve", "Romannumerals", "Rrightarrow", "Rsh", "S", "Sacute", "ScaledPointsToBigPoints", "ScaledPointsToWholeBigPoints", "Scaron", "Scedilla", "Schwa", "Scircumflex", "Scommaaccent", "Searrow", "Sigma", "Smallcapped", "Subset", "Supset", "Swarrow", "TABLE", "TEX", "TaBlE", "Tau", "Tcaron", "Tcedilla", "Tcommaaccent", "TeX", "TheNormalizedFontSize", "Theta", "Thook", "Thorn", "TransparencyHack", "Tstroke", "Uacute", "Ubreve", "Ucaron", "Ucircumflex", "Udiaeresis", "Udiaeresisacute", "Udiaeresiscaron", "Udiaeresisgrave", "Udiaeresismacron", "Udotbelow", "Udoublegrave", "Ugrave", "Uhook", "Uhorn", "Uhornacute", "Uhorndotbelow", "Uhorngrave", "Uhornhook", "Uhorntilde", "Uhungarumlaut", "Uinvertedbreve", "Umacron", "Uogonek", "Uparrow", "Updownarrow", "Upsilon", "Uring", "Utilde", "Uuparrow", "VDash", "Vdash", "VerboseNumber", "Vert", "Vvdash", "WEEKDAY", "WORD", "WORDS", "Wcircumflex", "WidthSpanningText", "Word", "Words", "XETEX", "XeTeX", "Xi", "Yacute", "Ycircumflex", "Ydiaeresis", "Ydotbelow", "Ygrave", "Yhook", "Ymacron", "Ytilde", "Zacute", "Zcaron", "Zdotaccent", "Zeta", "Zhook", "Zstroke", "aacute", "abbreviation", "abjadnaivenumerals", "abjadnodotnumerals", "abjadnumerals", "about", "abreve", "abreveacute", "abrevedotbelow", "abrevegrave", "abrevehook", "abrevetilde", "acaron", "acircumflex", "acircumflexacute", "acircumflexdotbelow", "acircumflexgrave", "acircumflexhook", "acircumflextilde", "activatespacehandler", "actuarial", "acute", "acwopencirclearrow", "adaptcollector", "adaptfontfeature", "adaptlayout", "adaptpapersize", "addfeature", "addtoJSpreamble", "addtocommalist", "addvalue", "adiaeresis", "adiaeresismacron", "adotaccent", "adotaccentmacron", "adotbelow", "adoublegrave", "aeacute", "aeligature", "aemacron", "aftersplitstring", "aftertestandsplitstring", "agrave", "ahook", "ainvertedbreve", "aleph", "alignbottom", "aligned", "alignedbox", "alignedline", "alignhere", "alignmentcharacter", "allinputpaths", "alpha", "alphabeticnumerals", "alwayscitation", "alwayscite", "amacron", "amalg", "ampersand", "anchor", "angle", "aogonek", "appendetoks", "appendgvalue", "appendtocommalist", "appendtoks", "appendtoksonce", "appendvalue", "apply", "applyalternativestyle", "applyprocessor", "applytocharacters", "applytofirstcharacter", "applytosplitstringchar", "applytosplitstringcharspaced", "applytosplitstringline", "applytosplitstringlinespaced", "applytosplitstringword", "applytosplitstringwordspaced", "applytowords", "approx", "approxEq", "approxeq", "approxnEq", "arabicdecimals", "arabicexnumerals", "arabicnumerals", "arg", "aring", "aringacute", "arrowvert", "asciistr", "aside", "assignalfadimension", "assigndimen", "assigndimension", "assignifempty", "assigntranslation", "assignvalue", "assignwidth", "assumelongusagecs", "ast", "astype", "asymp", "at", "atilde", "atleftmargin", "atpage", "atrightmargin", "attachment", "autocap", "autodirhbox", "autodirvbox", "autodirvtop", "autoinsertnextspace", "autointegral", "automathematics", "autosetups", "availablehsize", "averagecharwidth", "backepsilon", "background", "backgroundimage", "backgroundimagefill", "backgroundline", "backprime", "backsim", "backslash", "bar", "barleftarrow", "barleftarrowrightarrowbar", "barovernorthwestarrow", "barwedge", "basegrid", "baselinebottom", "baselineleftbox", "baselinemiddlebox", "baselinerightbox", "bbordermatrix", "bbox", "because", "beforesplitstring", "beforetestandsplitstring", "beta", "beth", "between", "bhook", "big", "bigbodyfont", "bigcap", "bigcirc", "bigcircle", "bigcup", "bigdiamond", "bigg", "bigger", "biggl", "biggm", "biggr", "bigl", "bigm", "bigodot", "bigoplus", "bigotimes", "bigr", "bigskip", "bigsqcap", "bigsqcup", "bigsquare", "bigstar", "bigtimes", "bigtriangledown", "bigtriangleup", "bigudot", "biguplus", "bigvee", "bigwedge", "binom", "bitmapimage", "blacklozenge", "blackrule", "blackrules", "blacksquare", "blacktriangle", "blacktriangledown", "blacktriangleleft", "blacktriangleright", "blank", "blap", "bleed", "bleedheight", "bleedwidth", "blockligatures", "blockquote", "blocksynctexfile", "bodyfontenvironmentlist", "bodyfontsize", "bold", "boldface", "bolditalic", "boldslanted", "bookmark", "booleanmodevalue", "bordermatrix", "bot", "bottombox", "bottomleftbox", "bottomrightbox", "bowtie", "boxcursor", "boxdot", "boxmarker", "boxminus", "boxofsize", "boxplus", "boxreference", "boxtimes", "bpos", "breakablethinspace", "breakhere", "breve", "bstroke", "btxabbreviatedjournal", "btxaddjournal", "btxalwayscitation", "btxauthorfield", "btxdetail", "btxdirect", "btxdoif", "btxdoifcombiinlistelse", "btxdoifelse", "btxdoifelsecombiinlist", "btxdoifelsesameasprevious", "btxdoifelsesameaspreviouschecked", "btxdoifelseuservariable", "btxdoifnot", "btxdoifsameaspreviouscheckedelse", "btxdoifsameaspreviouselse", "btxdoifuservariableelse", "btxexpandedjournal", "btxfield", "btxfieldname", "btxfieldtype", "btxfirstofrange", "btxflush", "btxflushauthor", "btxflushauthorinverted", "btxflushauthorinvertedshort", "btxflushauthorname", "btxflushauthornormal", "btxflushauthornormalshort", "btxflushsuffix", "btxfoundname", "btxfoundtype", "btxhiddencitation", "btxhybridcite", "btxlabellanguage", "btxlabeltext", "btxlistcitation", "btxloadjournalist", "btxoneorrange", "btxremapauthor", "btxsavejournalist", "btxsetup", "btxsingularorplural", "btxsingularplural", "btxtextcitation", "buildmathaccent", "buildtextaccent", "buildtextbottomcomma", "buildtextbottomdot", "buildtextcedilla", "buildtextgrave", "buildtextmacron", "buildtextognek", "bullet", "button", "cacute", "calligraphic", "camel", "cap", "carriagereturn", "catcodetablename", "cbox", "ccaron", "ccedilla", "ccircumflex", "ccurl", "cdot", "cdotaccent", "cdotp", "cdots", "centeraligned", "centerbox", "centerdot", "centeredbox", "centeredlastline", "centerednextbox", "centerline", "cfrac", "chapter", "character", "characters", "chardescription", "charwidthlanguage", "check", "checkcharacteralign", "checkedchar", "checkedfiller", "checkedstrippedcsname", "checkinjector", "checkmark", "checknextindentation", "checknextinjector", "checkpage", "checkparameters", "checkpreviousinjector", "checksoundtrack", "checktwopassdata", "checkvariables", "chem", "chemical", "chemicalbottext", "chemicalmidtext", "chemicalsymbol", "chemicaltext", "chemicaltoptext", "chi", "chineseallnumerals", "chinesecapnumerals", "chinesenumerals", "chook", "circ", "circeq", "circlearrowleft", "circlearrowright", "circledR", "circledS", "circledast", "circledcirc", "circleddash", "circledequals", "circleonrightarrow", "citation", "cite", "clap", "classfont", "cldcommand", "cldcontext", "cldloadfile", "cldprocessfile", "cleftarrow", "clip", "clonefield", "clubsuit", "collect", "collectedtext", "collectexpanded", "colon", "coloncolonequals", "colonequals", "color", "colorbar", "colorcomponents", "colored", "coloronly", "colorvalue", "column", "columnbreak", "combinepages", "commalistelement", "commalistsentence", "commalistsize", "comment", "comparecolorgroup", "comparedimension", "comparedimensioneps", "comparepalet", "complement", "completebtxrendering", "completecontent", "completeindex", "completelist", "completelistofabbreviations", "completelistofchemicals", "completelistoffigures", "completelistofgraphics", "completelistofintermezzi", "completelistoflogos", "completelistofpublications", "completelistofsorts", "completelistofsynonyms", "completelistoftables", "completepagenumber", "completeregister", "complexes", "complexorsimple", "complexorsimpleempty", "component", "composedcollector", "composedlayer", "compresult", "cong", "constantdimen", "constantdimenargument", "constantemptyargument", "constantnumber", "constantnumberargument", "contentreference", "continuednumber", "continueifinputfile", "convertargument", "convertcommand", "convertedcounter", "converteddimen", "convertedsubcounter", "convertmonth", "convertnumber", "convertvalue", "convertvboxtohbox", "coprod", "copyboxfromcache", "copybtxlabeltext", "copyfield", "copyheadtext", "copylabeltext", "copymathlabeltext", "copyoperatortext", "copypages", "copyparameters", "copyposition", "copyprefixtext", "copyright", "copysuffixtext", "copytaglabeltext", "copyunittext", "correctwhitespace", "countersubs", "counttoken", "counttokens", "cramped", "crampedclap", "crampedllap", "crampedrlap", "crightarrow", "crightoverleftarrow", "cstroke", "ctop", "ctxcommand", "ctxdirectcommand", "ctxdirectlua", "ctxfunction", "ctxlatecommand", "ctxlatelua", "ctxloadluafile", "ctxlua", "ctxluabuffer", "ctxluacode", "ctxreport", "ctxsprint", "cup", "curlyeqprec", "curlyeqsucc", "curlyvee", "curlywedge", "currentassignmentlistkey", "currentassignmentlistvalue", "currentbtxuservariable", "currentcommalistitem", "currentcomponent", "currentdate", "currentenvironment", "currentfeaturetest", "currentheadnumber", "currentinterface", "currentlanguage", "currentlistentrydestinationattribute", "currentlistentrylimitedtext", "currentlistentrynumber", "currentlistentrypagenumber", "currentlistentryreferenceattribute", "currentlistentrytitle", "currentlistentrytitlerendered", "currentlistsymbol", "currentmainlanguage", "currentmessagetext", "currentmoduleparameter", "currentoutputstream", "currentproduct", "currentproject", "currentregime", "currentregisterpageuserdata", "currentresponses", "currenttime", "currentvalue", "currentxtablecolumn", "currentxtablerow", "curvearrowleft", "curvearrowright", "cwopencirclearrow", "cyrillicA", "cyrillicAE", "cyrillicAbreve", "cyrillicAdiaeresis", "cyrillicB", "cyrillicBIGYUS", "cyrillicBIGYUSiotified", "cyrillicC", "cyrillicCH", "cyrillicCHEDC", "cyrillicCHEDCabkhasian", "cyrillicCHEabkhasian", "cyrillicCHEdiaeresis", "cyrillicCHEkhakassian", "cyrillicCHEvertstroke", "cyrillicD", "cyrillicDASIAPNEUMATA", "cyrillicDJE", "cyrillicDZE", "cyrillicDZEabkhasian", "cyrillicDZHE", "cyrillicE", "cyrillicELtail", "cyrillicEMtail", "cyrillicENDC", "cyrillicENGHE", "cyrillicENhook", "cyrillicENtail", "cyrillicEREV", "cyrillicERY", "cyrillicERtick", "cyrillicEbreve", "cyrillicEdiaeresis", "cyrillicEgrave", "cyrillicEiotified", "cyrillicF", "cyrillicFITA", "cyrillicG", "cyrillicGHEmidhook", "cyrillicGHEstroke", "cyrillicGHEupturn", "cyrillicGJE", "cyrillicH", "cyrillicHA", "cyrillicHADC", "cyrillicHRDSN", "cyrillicI", "cyrillicIE", "cyrillicII", "cyrillicISHRT", "cyrillicISHRTtail", "cyrillicIZHITSA", "cyrillicIZHITSAdoublegrave", "cyrillicIdiaeresis", "cyrillicIgrave", "cyrillicImacron", "cyrillicJE", "cyrillicK", "cyrillicKADC", "cyrillicKAbashkir", "cyrillicKAhook", "cyrillicKAstroke", "cyrillicKAvertstroke", "cyrillicKJE", "cyrillicKOPPA", "cyrillicKSI", "cyrillicL", "cyrillicLITTLEYUS", "cyrillicLITTLEYUSiotified", "cyrillicLJE", "cyrillicM", "cyrillicN", "cyrillicNJE", "cyrillicO", "cyrillicOMEGA", "cyrillicOMEGAround", "cyrillicOMEGAtitlo", "cyrillicOT", "cyrillicObarred", "cyrillicObarreddiaeresis", "cyrillicOdiaeresis", "cyrillicP", "cyrillicPALATALIZATION", "cyrillicPALOCHKA", "cyrillicPEmidhook", "cyrillicPSI", "cyrillicPSILIPNEUMATA", "cyrillicR", "cyrillicS", "cyrillicSCHWA", "cyrillicSCHWAdiaeresis", "cyrillicSDSC", "cyrillicSEMISOFT", "cyrillicSFTSN", "cyrillicSH", "cyrillicSHCH", "cyrillicSHHA", "cyrillicT", "cyrillicTEDC", "cyrillicTETSE", "cyrillicTITLO", "cyrillicTSHE", "cyrillicU", "cyrillicUK", "cyrillicUSHRT", "cyrillicUdiaeresis", "cyrillicUdoubleacute", "cyrillicUmacron", "cyrillicV", "cyrillicYA", "cyrillicYAT", "cyrillicYERUdiaeresis", "cyrillicYI", "cyrillicYO", "cyrillicYU", "cyrillicYstr", "cyrillicYstrstroke", "cyrillicZ", "cyrillicZDSC", "cyrillicZEdiaeresis", "cyrillicZH", "cyrillicZHEbreve", "cyrillicZHEdescender", "cyrillicZHEdiaeresis", "cyrillica", "cyrillicabreve", "cyrillicadiaeresis", "cyrillicae", "cyrillicb", "cyrillicbigyus", "cyrillicbigyusiotified", "cyrillicc", "cyrillicch", "cyrilliccheabkhasian", "cyrillicchedc", "cyrillicchedcabkhasian", "cyrillicchediaeresis", "cyrillicchekhakassian", "cyrillicchevertstroke", "cyrillicd", "cyrillicdje", "cyrillicdze", "cyrillicdzeabkhasian", "cyrillicdzhe", "cyrillice", "cyrillicebreve", "cyrillicediaeresis", "cyrillicegrave", "cyrilliceiotified", "cyrilliceltail", "cyrillicemtail", "cyrillicendc", "cyrillicenghe", "cyrillicenhook", "cyrillicentail", "cyrillicerev", "cyrillicertick", "cyrillicery", "cyrillicf", "cyrillicfita", "cyrillicg", "cyrillicghemidhook", "cyrillicghestroke", "cyrillicgheupturn", "cyrillicgje", "cyrillich", "cyrillicha", "cyrillichadc", "cyrillichrdsn", "cyrillici", "cyrillicidiaeresis", "cyrillicie", "cyrillicigrave", "cyrillicii", "cyrillicimacron", "cyrillicishrt", "cyrillicishrttail", "cyrillicizhitsa", "cyrillicizhitsadoublegrave", "cyrillicje", "cyrillick", "cyrillickabashkir", "cyrillickadc", "cyrillickahook", "cyrillickastroke", "cyrillickavertstroke", "cyrillickje", "cyrillickoppa", "cyrillicksi", "cyrillicl", "cyrilliclittleyus", "cyrilliclittleyusiotified", "cyrilliclje", "cyrillicm", "cyrillicn", "cyrillicnje", "cyrillico", "cyrillicobarred", "cyrillicobarreddiaeresis", "cyrillicodiaeresis", "cyrillicomega", "cyrillicomegaround", "cyrillicomegatitlo", "cyrillicot", "cyrillicp", "cyrillicpemidhook", "cyrillicpsi", "cyrillicr", "cyrillics", "cyrillicschwa", "cyrillicschwadiaeresis", "cyrillicsdsc", "cyrillicsemisoft", "cyrillicsftsn", "cyrillicsh", "cyrillicshch", "cyrillicshha", "cyrillict", "cyrillictedc", "cyrillictetse", "cyrillictshe", "cyrillicu", "cyrillicudiaeresis", "cyrillicudoubleacute", "cyrillicuk", "cyrillicumacron", "cyrillicushrt", "cyrillicv", "cyrillicya", "cyrillicyat", "cyrillicyerudiaeresis", "cyrillicyi", "cyrillicyo", "cyrillicystr", "cyrillicystrstroke", "cyrillicyu", "cyrillicz", "cyrilliczdsc", "cyrilliczediaeresis", "cyrilliczh", "cyrilliczhebreve", "cyrilliczhedescender", "cyrilliczhediaeresis", "d", "dag", "dagger", "daleth", "dasharrow", "dashedleftarrow", "dashedrightarrow", "dashv", "datasetvariable", "date", "dayoftheweek", "dayspermonth", "dbinom", "dcaron", "dcurl", "ddag", "ddagger", "dddot", "ddot", "ddots", "decrement", "decrementcounter", "decrementedcounter", "decrementpagenumber", "decrementsubpagenumber", "decrementvalue", "defaultinterface", "defaultobjectpage", "defaultobjectreference", "defcatcodecommand", "defconvertedargument", "defconvertedcommand", "defconvertedvalue", "define", "defineMPinstance", "defineTABLEsetup", "defineaccent", "defineactivecharacter", "definealternativestyle", "defineanchor", "defineattachment", "defineattribute", "definebackground", "definebar", "defineblock", "definebodyfont", "definebodyfontenvironment", "definebodyfontswitch", "definebreakpoint", "definebreakpoints", "definebtx", "definebtxdataset", "definebtxregister", "definebtxrendering", "definebuffer", "definebutton", "definecapitals", "definecharacter", "definecharacterkerning", "definecharacterspacing", "definechemical", "definechemicals", "definechemicalsymbol", "definecollector", "definecolor", "definecolorgroup", "definecolumnbreak", "definecombination", "definecombinedlist", "definecommand", "definecomment", "definecomplexorsimple", "definecomplexorsimpleempty", "defineconversion", "defineconversionset", "definecounter", "definedataset", "definedelimitedtext", "definedeq", "definedescription", "definedfont", "defineeffect", "defineenumeration", "defineexpandable", "defineexternalfigure", "definefallbackfamily", "definefield", "definefieldbody", "definefieldbodyset", "definefieldcategory", "definefieldstack", "definefiguresymbol", "definefileconstant", "definefilefallback", "definefilesynonym", "definefiller", "definefirstline", "definefittingpage", "definefloat", "definefont", "definefontalternative", "definefontfallback", "definefontfamily", "definefontfamilypreset", "definefontfeature", "definefontfile", "definefontsize", "definefontsolution", "definefontstyle", "definefontsynonym", "defineformula", "defineformulaalternative", "defineformulaframed", "defineframed", "defineframedcontent", "defineframedtable", "defineframedtext", "definefrozenfont", "defineglobalcolor", "definegraphictypesynonym", "definegridsnapping", "definehbox", "definehead", "defineheadalternative", "definehelp", "definehigh", "definehighlight", "definehspace", "definehypenationfeatures", "defineindentedtext", "defineindenting", "defineinitial", "defineinsertion", "defineinteraction", "defineinteractionbar", "defineinteractionmenu", "defineinterfaceconstant", "defineinterfaceelement", "defineinterfacevariable", "defineinterlinespace", "defineintermediatecolor", "defineitemgroup", "defineitems", "definelabel", "definelabelclass", "definelayer", "definelayerpreset", "definelayout", "definelinefiller", "definelinenote", "definelinenumbering", "definelines", "definelist", "definelistalternative", "definelistextra", "definelow", "definelowhigh", "definelowmidhigh", "definemakeup", "definemarginblock", "definemargindata", "definemarker", "definemarking", "definemathaccent", "definemathalignment", "definemathcases", "definemathcommand", "definemathdouble", "definemathdoubleextensible", "definemathematics", "definemathextensible", "definemathfence", "definemathfraction", "definemathframed", "definemathmatrix", "definemathornament", "definemathover", "definemathoverextensible", "definemathovertextextensible", "definemathradical", "definemathstackers", "definemathstyle", "definemathtriplet", "definemathunder", "definemathunderextensible", "definemathundertextextensible", "definemathunstacked", "definemeasure", "definemessageconstant", "definemixedcolumns", "definemode", "definemultitonecolor", "definenamedcolor", "definenamespace", "definenarrower", "definenote", "defineornament", "defineoutputroutine", "defineoutputroutinecommand", "defineoverlay", "definepage", "definepagebreak", "definepagechecker", "definepagegrid", "definepagegridarea", "definepagegridspan", "definepageinjection", "definepageinjectionalternative", "definepageshift", "definepagestate", "definepairedbox", "definepalet", "definepapersize", "defineparagraph", "defineparagraphs", "defineparallel", "defineparbuilder", "defineplacement", "definepositioning", "defineprefixset", "defineprocesscolor", "defineprocessor", "defineprofile", "defineprogram", "definepushbutton", "definepushsymbol", "definereference", "definereferenceformat", "defineregister", "definerenderingwindow", "defineresetset", "definescale", "definescript", "definesection", "definesectionblock", "definesectionlevels", "defineselector", "defineseparatorset", "defineshift", "definesidebar", "definesort", "definesorting", "definespotcolor", "definestartstop", "definestyle", "definestyleinstance", "definesubfield", "definesubformula", "definesymbol", "definesynonym", "definesynonyms", "definesystemattribute", "definesystemconstant", "definesystemvariable", "definetabletemplate", "definetabulate", "definetabulation", "definetext", "definetextbackground", "definetextflow", "definetooltip", "definetransparency", "definetwopasslist", "definetype", "definetypeface", "definetypescriptprefix", "definetypescriptsynonym", "definetypesetting", "definetyping", "defineunit", "defineviewerlayer", "definevspace", "definevspacing", "definevspacingamount", "definextable", "delimited", "delimitedtext", "delta", "depthofstring", "depthonlybox", "depthspanningtext", "depthstrut", "determineheadnumber", "determinelistcharacteristics", "determinenoflines", "determineregistercharacteristics", "devanagarinumerals", "dfrac", "dhook", "diameter", "diamond", "diamondsuit", "differentialD", "differentiald", "digamma", "digits", "dimensiontocount", "directboxfromcache", "directcolor", "directcolored", "directconvertedcounter", "directcopyboxfromcache", "directdummyparameter", "directgetboxllx", "directgetboxlly", "directhighlight", "directlocalframed", "directluacode", "directselect", "directsetbar", "directsetup", "directsymbol", "directvspacing", "dis", "disabledirectives", "disableexperiments", "disablemode", "disableoutputstream", "disableparpositions", "disableregime", "disabletrackers", "displaymath", "displaymathematics", "displaymessage", "distributedhsize", "div", "dividedsize", "divideontimes", "divides", "doadaptleftskip", "doadaptrightskip", "doaddfeature", "doassign", "doassignempty", "doboundtext", "docheckassignment", "docheckedpagestate", "docheckedpair", "documentvariable", "dodoubleargument", "dodoubleargumentwithset", "dodoubleempty", "dodoubleemptywithset", "dodoublegroupempty", "doeassign", "doexpandedrecurse", "dofastloopcs", "dogetattribute", "dogetattributeid", "dogetcommacommandelement", "dogobbledoubleempty", "dogobblesingleempty", "doif", "doifMPgraphicelse", "doifallcommon", "doifallcommonelse", "doifalldefinedelse", "doifallmodes", "doifallmodeselse", "doifassignmentelse", "doifblackelse", "doifbothsides", "doifbothsidesoverruled", "doifboxelse", "doifbufferelse", "doifcolor", "doifcolorelse", "doifcommandhandler", "doifcommandhandlerelse", "doifcommon", "doifcommonelse", "doifcontent", "doifconversiondefinedelse", "doifconversionnumberelse", "doifcounter", "doifcounterelse", "doifcurrentfonthasfeatureelse", "doifdefined", "doifdefinedcounter", "doifdefinedcounterelse", "doifdefinedelse", "doifdimensionelse", "doifdimenstringelse", "doifdocumentargument", "doifdocumentargumentelse", "doifdocumentfilename", "doifdocumentfilenameelse", "doifdrawingblackelse", "doifelse", "doifelseMPgraphic", "doifelseallcommon", "doifelsealldefined", "doifelseallmodes", "doifelseassignment", "doifelseblack", "doifelsebox", "doifelseboxincache", "doifelsebuffer", "doifelsecolor", "doifelsecommandhandler", "doifelsecommon", "doifelseconversiondefined", "doifelseconversionnumber", "doifelsecounter", "doifelsecurrentfonthasfeature", "doifelsecurrentsortingused", "doifelsecurrentsynonymshown", "doifelsecurrentsynonymused", "doifelsedefined", "doifelsedefinedcounter", "doifelsedimension", "doifelsedimenstring", "doifelsedocumentargument", "doifelsedocumentfilename", "doifelsedrawingblack", "doifelseempty", "doifelseemptyvalue", "doifelseemptyvariable", "doifelseenv", "doifelsefastoptionalcheck", "doifelsefastoptionalcheckcs", "doifelsefieldbody", "doifelsefieldcategory", "doifelsefigure", "doifelsefile", "doifelsefiledefined", "doifelsefileexists", "doifelsefirstchar", "doifelseflagged", "doifelsefontchar", "doifelsefontpresent", "doifelsefontsynonym", "doifelsehasspace", "doifelsehelp", "doifelseincsname", "doifelseinelement", "doifelseinputfile", "doifelseinsertion", "doifelseinset", "doifelseinstring", "doifelseinsymbolset", "doifelseintoks", "doifelseintwopassdata", "doifelseitalic", "doifelselanguage", "doifelselayerdata", "doifelselayoutdefined", "doifelselayoutsomeline", "doifelselayouttextline", "doifelseleapyear", "doifelselist", "doifelselocation", "doifelselocfile", "doifelsemainfloatbody", "doifelsemarkedpage", "doifelsemarking", "doifelsemeaning", "doifelsemessage", "doifelsemode", "doifelsenextbgroup", "doifelsenextbgroupcs", "doifelsenextchar", "doifelsenextoptional", "doifelsenextoptionalcs", "doifelsenextparenthesis", "doifelsenonzeropositive", "doifelsenoteonsamepage", "doifelsenothing", "doifelsenumber", "doifelseobjectfound", "doifelseobjectreferencefound", "doifelseoddpage", "doifelseoddpagefloat", "doifelseoldercontext", "doifelseolderversion", "doifelseoverlapping", "doifelseoverlay", "doifelseparallel", "doifelseparentfile", "doifelsepath", "doifelsepathexists", "doifelsepatterns", "doifelseposition", "doifelsepositionaction", "doifelsepositiononpage", "doifelsepositionsonsamepage", "doifelsepositionsonthispage", "doifelsepositionsused", "doifelsereferencefound", "doifelserightpagefloat", "doifelserighttoleftinbox", "doifelsesamelinereference", "doifelsesamestring", "doifelsesetups", "doifelsesomebackground", "doifelsesomespace", "doifelsesomething", "doifelsesometoks", "doifelsestringinstring", "doifelsestructurelisthasnumber", "doifelsestructurelisthaspage", "doifelsesymboldefined", "doifelsesymbolset", "doifelsetext", "doifelsetextflow", "doifelsetextflowcollector", "doifelsetopofpage", "doifelsetypingfile", "doifelseundefined", "doifelseurldefined", "doifelsevalue", "doifelsevaluenothing", "doifelsevariable", "doifempty", "doifemptyelse", "doifemptytoks", "doifemptyvalue", "doifemptyvalueelse", "doifemptyvariable", "doifemptyvariableelse", "doifenv", "doifenvelse", "doiffastoptionalcheckcselse", "doiffastoptionalcheckelse", "doiffieldbodyelse", "doiffieldcategoryelse", "doiffigureelse", "doiffile", "doiffiledefinedelse", "doiffileelse", "doiffileexistselse", "doiffirstcharelse", "doifflaggedelse", "doiffontcharelse", "doiffontpresentelse", "doiffontsynonymelse", "doifhasspaceelse", "doifhelpelse", "doifincsnameelse", "doifinelementelse", "doifinputfileelse", "doifinsertionelse", "doifinset", "doifinsetelse", "doifinstring", "doifinstringelse", "doifinsymbolset", "doifinsymbolsetelse", "doifintokselse", "doifintwopassdataelse", "doifitalicelse", "doiflanguageelse", "doiflayerdataelse", "doiflayoutdefinedelse", "doiflayoutsomelineelse", "doiflayouttextlineelse", "doifleapyearelse", "doiflistelse", "doiflocationelse", "doiflocfileelse", "doifmainfloatbodyelse", "doifmarkingelse", "doifmeaningelse", "doifmessageelse", "doifmode", "doifmodeelse", "doifnextbgroupcselse", "doifnextbgroupelse", "doifnextcharelse", "doifnextoptionalcselse", "doifnextoptionalelse", "doifnextparenthesiselse", "doifnonzeropositiveelse", "doifnot", "doifnotallcommon", "doifnotallmodes", "doifnotcommandhandler", "doifnotcommon", "doifnotcounter", "doifnotdocumentargument", "doifnotdocumentfilename", "doifnotempty", "doifnotemptyvalue", "doifnotemptyvariable", "doifnotenv", "doifnoteonsamepageelse", "doifnotescollected", "doifnotfile", "doifnotflagged", "doifnothing", "doifnothingelse", "doifnotinset", "doifnotinsidesplitfloat", "doifnotinstring", "doifnotmode", "doifnotnumber", "doifnotsamestring", "doifnotsetups", "doifnotvalue", "doifnotvariable", "doifnumber", "doifnumberelse", "doifobjectfoundelse", "doifobjectreferencefoundelse", "doifoddpageelse", "doifoddpagefloatelse", "doifoldercontextelse", "doifolderversionelse", "doifoverlappingelse", "doifoverlayelse", "doifparallelelse", "doifparentfileelse", "doifpathelse", "doifpathexistselse", "doifpatternselse", "doifposition", "doifpositionaction", "doifpositionactionelse", "doifpositionelse", "doifpositiononpageelse", "doifpositionsonsamepageelse", "doifpositionsonthispageelse", "doifpositionsusedelse", "doifreferencefoundelse", "doifrightpagefloatelse", "doifrighttoleftinboxelse", "doifsamelinereferenceelse", "doifsamestring", "doifsamestringelse", "doifsetups", "doifsetupselse", "doifsomebackground", "doifsomebackgroundelse", "doifsomespaceelse", "doifsomething", "doifsomethingelse", "doifsometoks", "doifsometokselse", "doifstringinstringelse", "doifstructurelisthasnumberelse", "doifstructurelisthaspageelse", "doifsymboldefinedelse", "doifsymbolsetelse", "doiftext", "doiftextelse", "doiftextflowcollectorelse", "doiftextflowelse", "doiftopofpageelse", "doiftypingfileelse", "doifundefined", "doifundefinedcounter", "doifundefinedelse", "doifurldefinedelse", "doifvalue", "doifvalueelse", "doifvaluenothing", "doifvaluenothingelse", "doifvaluesomething", "doifvariable", "doifvariableelse", "doindentation", "dollar", "doloop", "doloopoverlist", "donothing", "dontconvertfont", "dontleavehmode", "dontpermitspacesbetweengroups", "dopositionaction", "doprocesslocalsetups", "doquadrupleargument", "doquadrupleempty", "doquadruplegroupempty", "doquintupleargument", "doquintupleempty", "doquintuplegroupempty", "dorechecknextindentation", "dorecurse", "dorepeatwithcommand", "doreplacefeature", "doresetandafffeature", "doresetattribute", "dorotatebox", "dosetattribute", "dosetleftskipadaption", "dosetrightskipadaption", "dosetupcheckedinterlinespace", "doseventupleargument", "doseventupleempty", "dosingleargument", "dosingleempty", "dosinglegroupempty", "dosixtupleargument", "dosixtupleempty", "dostepwiserecurse", "dosubtractfeature", "dot", "doteq", "doteqdot", "dotfskip", "dotlessI", "dotlessJ", "dotlessi", "dotlessj", "dotlessjstroke", "dotminus", "dotoks", "dotplus", "dotripleargument", "dotripleargumentwithset", "dotripleempty", "dotripleemptywithset", "dotriplegroupempty", "dots", "dottedrightarrow", "doublebar", "doublebond", "doublebrace", "doublebracket", "doublecap", "doublecup", "doubleparent", "doubleprime", "doubleverticalbar", "dowith", "dowithnextbox", "dowithnextboxcontent", "dowithnextboxcontentcs", "dowithnextboxcs", "dowithpargument", "dowithrange", "dowithwargument", "downarrow", "downdasharrow", "downdownarrows", "downharpoonleft", "downharpoonright", "downuparrows", "downwhitearrow", "downzigzagarrow", "dpofstring", "dstroke", "dtail", "dummydigit", "dummyparameter", "dzcaronligature", "dzligature", "eTeX", "eacute", "ebreve", "ecaron", "ecedilla", "ecircumflex", "ecircumflexacute", "ecircumflexdotbelow", "ecircumflexgrave", "ecircumflexhook", "ecircumflextilde", "edefconvertedargument", "ediaeresis", "edotaccent", "edotbelow", "edoublegrave", "efcmaxheight", "efcmaxwidth", "efcminheight", "efcminwidth", "efcparameter", "effect", "egrave", "ehook", "einvertedbreve", "elapsedseconds", "elapsedtime", "eleftarrowfill", "eleftharpoondownfill", "eleftharpoonupfill", "eleftrightarrowfill", "ell", "em", "emacron", "emdash", "emphasisboldface", "emphasistypeface", "emptylines", "emptyset", "emspace", "enabledirectives", "enableexperiments", "enablemode", "enableoutputstream", "enableparpositions", "enableregime", "enabletrackers", "endash", "endnote", "enskip", "enspace", "env", "environment", "envvar", "eogonek", "eoverbarfill", "eoverbracefill", "eoverbracketfill", "eoverparentfill", "epos", "epsilon", "eq", "eqcirc", "eqeq", "eqeqeq", "eqgtr", "eqless", "eqsim", "eqslantgtr", "eqslantless", "equaldigits", "equalscolon", "equiv", "erightarrowfill", "erightharpoondownfill", "erightharpoonupfill", "eta", "eth", "ethiopic", "etilde", "etwoheadrightarrowfill", "eunderbarfill", "eunderbracefill", "eunderbracketfill", "eunderparentfill", "exclamdown", "executeifdefined", "exists", "exitloop", "exitloopnow", "expandcheckedcsname", "expanded", "expandfontsynonym", "expdoif", "expdoifcommonelse", "expdoifelse", "expdoifelsecommon", "expdoifelseinset", "expdoifinsetelse", "expdoifnot", "exponentiale", "externalfigure", "externalfigurecollectionmaxheight", "externalfigurecollectionmaxwidth", "externalfigurecollectionminheight", "externalfigurecollectionminwidth", "externalfigurecollectionparameter", "fakebox", "fallingdotseq", "fastdecrement", "fastincrement", "fastlocalframed", "fastloopfinal", "fastloopindex", "fastscale", "fastsetup", "fastsetupwithargument", "fastsetupwithargumentswapped", "fastswitchtobodyfont", "fastsxsy", "feature", "fence", "fenced", "fetchallmarkings", "fetchallmarks", "fetchmark", "fetchmarking", "fetchonemark", "fetchonemarking", "fetchruntinecommand", "fetchtwomarkings", "fetchtwomarks", "ffiligature", "ffligature", "fflligature", "fhook", "field", "fieldbody", "fieldstack", "fifthoffivearguments", "fifthofsixarguments", "figurefilename", "figurefilepath", "figurefiletype", "figurefullname", "figureheight", "figurenaturalheight", "figurenaturalwidth", "figurespace", "figuresymbol", "figurewidth", "filename", "filigature", "filledhboxb", "filledhboxc", "filledhboxg", "filledhboxk", "filledhboxm", "filledhboxr", "filledhboxy", "filler", "fillinline", "fillinrules", "fillintext", "filterfromnext", "filterfromvalue", "filterpages", "filterreference", "findtwopassdata", "finishregisterentry", "firstcharacter", "firstcounter", "firstcountervalue", "firstoffivearguments", "firstoffourarguments", "firstofoneargument", "firstofoneunexpanded", "firstofsixarguments", "firstofthreearguments", "firstofthreeunexpanded", "firstoftwoarguments", "firstoftwounexpanded", "firstrealpage", "firstrealpagenumber", "firstsubcountervalue", "firstsubpage", "firstsubpagenumber", "firstuserpage", "firstuserpagenumber", "fitfield", "fitfieldframed", "fittopbaselinegrid", "fiveeighths", "fivesixths", "fixedspace", "fixedspaces", "flag", "flat", "flligature", "floatuserdataparameter", "flushbox", "flushboxregister", "flushcollector", "flushedrightlastline", "flushlayer", "flushlocalfloats", "flushnextbox", "flushnotes", "flushoutputstream", "flushshapebox", "flushtextflow", "flushtokens", "flushtoks", "fontalternative", "fontbody", "fontchar", "fontcharbyindex", "fontclass", "fontclassname", "fontface", "fontfeaturelist", "fontsize", "fontstyle", "footnote", "footnotetext", "forall", "forcecharacterstripping", "forcelocalfloats", "forgeteverypar", "forgetparameters", "forgetragged", "formula", "formulanumber", "foundbox", "fourfifths", "fourperemspace", "fourthoffivearguments", "fourthoffourarguments", "fourthofsixarguments", "frac", "framed", "frameddimension", "framedparameter", "framedtext", "freezedimenmacro", "freezemeasure", "frenchspacing", "from", "fromlinenote", "frown", "frozenhbox", "frule", "gacute", "gamma", "gbreve", "gcaron", "gcircumflex", "gcommaaccent", "gdefconvertedargument", "gdefconvertedcommand", "gdotaccent", "ge", "geq", "geqq", "geqslant", "getMPdrawing", "getMPlayer", "getboxfromcache", "getboxllx", "getboxlly", "getbuffer", "getbufferdata", "getcommacommandsize", "getcommalistsize", "getdayoftheweek", "getdayspermonth", "getdefinedbuffer", "getdocumentargument", "getdocumentargumentdefault", "getdocumentfilename", "getdummyparameters", "getemptyparameters", "geteparameters", "getexpandedparameters", "getfiguredimensions", "getfirstcharacter", "getfirsttwopassdata", "getfromcommacommand", "getfromcommalist", "getfromtwopassdata", "getglyphdirect", "getglyphstyled", "getgparameters", "getlasttwopassdata", "getlocalfloat", "getlocalfloats", "getmarking", "getmessage", "getnamedglyphdirect", "getnamedglyphstyled", "getnamedtwopassdatalist", "getnaturaldimensions", "getnoflines", "getobject", "getobjectdimensions", "getpaletsize", "getparameters", "getprivatechar", "getprivateslot", "getrandomcount", "getrandomdimen", "getrandomfloat", "getrandomnumber", "getrandomseed", "getraweparameters", "getrawgparameters", "getrawnoflines", "getrawparameters", "getrawxparameters", "getreference", "getreferenceentry", "getroundednoflines", "gets", "getsubstring", "gettwopassdata", "gettwopassdatalist", "getuvalue", "getvalue", "getvariable", "getvariabledefault", "getxparameters", "gg", "ggg", "gggtr", "gimel", "globaldisablemode", "globalenablemode", "globalletempty", "globalpopbox", "globalpopmacro", "globalpreventmode", "globalprocesscommalist", "globalpushbox", "globalpushmacro", "globalswapcounts", "globalswapdimens", "globalswapmacros", "globalundefine", "glyphfontfile", "gnapprox", "gneqq", "gnsim", "gobbledoubleempty", "gobbleeightarguments", "gobblefivearguments", "gobblefiveoptionals", "gobblefourarguments", "gobblefouroptionals", "gobbleninearguments", "gobbleoneargument", "gobbleoneoptional", "gobblesevenarguments", "gobblesingleempty", "gobblesixarguments", "gobblespacetokens", "gobbletenarguments", "gobblethreearguments", "gobblethreeoptionals", "gobbletwoarguments", "gobbletwooptionals", "gobbleuntil", "gobbleuntilrelax", "godown", "goto", "gotobox", "gotopage", "grabbufferdata", "grabbufferdatadirect", "grabuntil", "grave", "graycolor", "grayvalue", "greedysplitstring", "greekAlpha", "greekAlphadasia", "greekAlphadasiaperispomeni", "greekAlphadasiatonos", "greekAlphadasiavaria", "greekAlphaiotasub", "greekAlphaiotasubdasia", "greekAlphaiotasubdasiaperispomeni", "greekAlphaiotasubdasiatonos", "greekAlphaiotasubdasiavaria", "greekAlphaiotasubpsili", "greekAlphaiotasubpsiliperispomeni", "greekAlphaiotasubpsilitonos", "greekAlphaiotasubpsilivaria", "greekAlphamacron", "greekAlphapsili", "greekAlphapsiliperispomeni", "greekAlphapsilitonos", "greekAlphapsilivaria", "greekAlphatonos", "greekAlphavaria", "greekAlphavrachy", "greekBeta", "greekChi", "greekCoronis", "greekDelta", "greekEpsilon", "greekEpsilondasia", "greekEpsilondasiatonos", "greekEpsilondasiavaria", "greekEpsilonpsili", "greekEpsilonpsilitonos", "greekEpsilonpsilivaria", "greekEpsilontonos", "greekEpsilonvaria", "greekEta", "greekEtadasia", "greekEtadasiaperispomeni", "greekEtadasiatonos", "greekEtadasiavaria", "greekEtaiotasub", "greekEtaiotasubdasia", "greekEtaiotasubdasiaperispomeni", "greekEtaiotasubdasiatonos", "greekEtaiotasubdasiavaria", "greekEtaiotasubpsili", "greekEtaiotasubpsiliperispomeni", "greekEtaiotasubpsilitonos", "greekEtaiotasubpsilivaria", "greekEtapsili", "greekEtapsiliperispomeni", "greekEtapsilitonos", "greekEtapsilivaria", "greekEtatonos", "greekEtavaria", "greekGamma", "greekIota", "greekIotadasia", "greekIotadasiaperispomeni", "greekIotadasiatonos", "greekIotadasiavaria", "greekIotadialytika", "greekIotamacron", "greekIotapsili", "greekIotapsiliperispomeni", "greekIotapsilitonos", "greekIotapsilivaria", "greekIotatonos", "greekIotavaria", "greekIotavrachy", "greekKappa", "greekLambda", "greekMu", "greekNu", "greekOmega", "greekOmegadasia", "greekOmegadasiaperispomeni", "greekOmegadasiatonos", "greekOmegadasiavaria", "greekOmegaiotasub", "greekOmegaiotasubdasia", "greekOmegaiotasubdasiaperispomeni", "greekOmegaiotasubdasiatonos", "greekOmegaiotasubdasiavaria", "greekOmegaiotasubpsili", "greekOmegaiotasubpsiliperispomeni", "greekOmegaiotasubpsilitonos", "greekOmegaiotasubpsilivaria", "greekOmegapsili", "greekOmegapsiliperispomeni", "greekOmegapsilitonos", "greekOmegapsilivaria", "greekOmegatonos", "greekOmegavaria", "greekOmicron", "greekOmicrondasia", "greekOmicrondasiatonos", "greekOmicrondasiavaria", "greekOmicronpsili", "greekOmicronpsilitonos", "greekOmicronpsilivaria", "greekOmicrontonos", "greekOmicronvaria", "greekPhi", "greekPi", "greekPsi", "greekRho", "greekRhodasia", "greekSigma", "greekSigmalunate", "greekTau", "greekTheta", "greekUpsilon", "greekUpsilondasia", "greekUpsilondasiaperispomeni", "greekUpsilondasiatonos", "greekUpsilondasiavaria", "greekUpsilondialytika", "greekUpsilonmacron", "greekUpsilontonos", "greekUpsilonvaria", "greekUpsilonvrachy", "greekXi", "greekZeta", "greekalpha", "greekalphadasia", "greekalphadasiaperispomeni", "greekalphadasiatonos", "greekalphadasiavaria", "greekalphaiotasub", "greekalphaiotasubdasia", "greekalphaiotasubdasiaperispomeni", "greekalphaiotasubdasiatonos", "greekalphaiotasubdasiavaria", "greekalphaiotasubperispomeni", "greekalphaiotasubpsili", "greekalphaiotasubpsiliperispomeni", "greekalphaiotasubpsilitonos", "greekalphaiotasubpsilivaria", "greekalphaiotasubtonos", "greekalphaiotasubvaria", "greekalphamacron", "greekalphaoxia", "greekalphaperispomeni", "greekalphapsili", "greekalphapsiliperispomeni", "greekalphapsilitonos", "greekalphapsilivaria", "greekalphatonos", "greekalphavaria", "greekalphavrachy", "greekbeta", "greekchi", "greekdasia", "greekdasiaperispomeni", "greekdasiatonos", "greekdasiavaria", "greekdelta", "greekdialytikaperispomeni", "greekdialytikatonos", "greekdialytikavaria", "greekdigamma", "greekepsilon", "greekepsilonalt", "greekepsilondasia", "greekepsilondasiatonos", "greekepsilondasiavaria", "greekepsilonoxia", "greekepsilonpsili", "greekepsilonpsilitonos", "greekepsilonpsilivaria", "greekepsilontonos", "greekepsilonvaria", "greeketa", "greeketadasia", "greeketadasiaperispomeni", "greeketadasiatonos", "greeketadasiavaria", "greeketaiotasub", "greeketaiotasubdasia", "greeketaiotasubdasiaperispomeni", "greeketaiotasubdasiatonos", "greeketaiotasubdasiavaria", "greeketaiotasubperispomeni", "greeketaiotasubpsili", "greeketaiotasubpsiliperispomeni", "greeketaiotasubpsilitonos", "greeketaiotasubpsilivaria", "greeketaiotasubtonos", "greeketaiotasubvaria", "greeketaoxia", "greeketaperispomeni", "greeketapsili", "greeketapsiliperispomeni", "greeketapsilitonos", "greeketapsilivaria", "greeketatonos", "greeketavaria", "greekfinalsigma", "greekgamma", "greekiota", "greekiotadasia", "greekiotadasiaperispomeni", "greekiotadasiatonos", "greekiotadasiavaria", "greekiotadialytika", "greekiotadialytikaperispomeni", "greekiotadialytikatonos", "greekiotadialytikavaria", "greekiotamacron", "greekiotaoxia", "greekiotaperispomeni", "greekiotapsili", "greekiotapsiliperispomeni", "greekiotapsilitonos", "greekiotapsilivaria", "greekiotatonos", "greekiotavaria", "greekiotavrachy", "greekkappa", "greekkoppa", "greeklambda", "greekmu", "greeknu", "greeknumerals", "greeknumkoppa", "greekomega", "greekomegadasia", "greekomegadasiaperispomeni", "greekomegadasiatonos", "greekomegadasiavaria", "greekomegaiotasub", "greekomegaiotasubdasia", "greekomegaiotasubdasiaperispomeni", "greekomegaiotasubdasiatonos", "greekomegaiotasubdasiavaria", "greekomegaiotasubperispomeni", "greekomegaiotasubpsili", "greekomegaiotasubpsiliperispomeni", "greekomegaiotasubpsilitonos", "greekomegaiotasubpsilivaria", "greekomegaiotasubtonos", "greekomegaiotasubvaria", "greekomegaoxia", "greekomegaperispomeni", "greekomegapsili", "greekomegapsiliperispomeni", "greekomegapsilitonos", "greekomegapsilivaria", "greekomegatonos", "greekomegavaria", "greekomicron", "greekomicrondasia", "greekomicrondasiatonos", "greekomicrondasiavaria", "greekomicronoxia", "greekomicronpsili", "greekomicronpsilitonos", "greekomicronpsilivaria", "greekomicrontonos", "greekomicronvaria", "greekoxia", "greekperispomeni", "greekphi", "greekphialt", "greekpi", "greekpialt", "greekprosgegrammeni", "greekpsi", "greekpsili", "greekpsiliperispomeni", "greekpsilitonos", "greekpsilivaria", "greekrho", "greekrhoalt", "greekrhodasia", "greekrhopsili", "greeksampi", "greeksigma", "greeksigmalunate", "greekstigma", "greektau", "greektheta", "greekthetaalt", "greektonos", "greekupsilon", "greekupsilondasia", "greekupsilondasiaperispomeni", "greekupsilondasiatonos", "greekupsilondasiavaria", "greekupsilondiaeresis", "greekupsilondialytikaperispomeni", "greekupsilondialytikatonos", "greekupsilondialytikavaria", "greekupsilonmacron", "greekupsilonoxia", "greekupsilonperispomeni", "greekupsilonpsili", "greekupsilonpsiliperispomeni", "greekupsilonpsilitonos", "greekupsilonpsilivaria", "greekupsilontonos", "greekupsilonvaria", "greekupsilonvrachy", "greekvaria", "greekxi", "greekzeta", "grid", "groupedcommand", "gsetboxllx", "gsetboxlly", "gstroke", "gt", "gtrapprox", "gtrdot", "gtreqless", "gtreqqless", "gtrless", "gtrsim", "guilsingleleft", "guilsingleright", "gujaratinumerals", "gurmurkhinumerals", "hairline", "hairspace", "halflinestrut", "halfstrut", "halfwaybox", "handletokens", "handwritten", "hangul", "hanzi", "hash", "hat", "hbar", "hboxofvbox", "hboxreference", "hcaron", "hcircumflex", "hdofstring", "headhbox", "headlanguage", "headnumber", "headnumbercontent", "headnumberdistance", "headnumberwidth", "headreferenceattributes", "headsetupspacing", "headtext", "headtextcontent", "headtextdistance", "headtexts", "headtextwidth", "headvbox", "headwidth", "heartsuit", "hebrewAlef", "hebrewAyin", "hebrewBet", "hebrewDalet", "hebrewGimel", "hebrewHe", "hebrewHet", "hebrewKaf", "hebrewKaffinal", "hebrewLamed", "hebrewMem", "hebrewMemfinal", "hebrewNun", "hebrewNunfinal", "hebrewPe", "hebrewPefinal", "hebrewQof", "hebrewResh", "hebrewSamekh", "hebrewShin", "hebrewTav", "hebrewTet", "hebrewTsadi", "hebrewTsadifinal", "hebrewVav", "hebrewYod", "hebrewZayin", "heightanddepthofstring", "heightofstring", "heightspanningtext", "helptext", "hglue", "hiddenbar", "hiddencitation", "hiddencite", "hideblocks", "high", "highlight", "highordinalstr", "hilo", "himilo", "hl", "hookleftarrow", "hookrightarrow", "horizontalgrowingbar", "horizontalpositionbar", "hphantom", "hpos", "hsizefraction", "hslash", "hsmash", "hsmashbox", "hsmashed", "hspace", "hstroke", "htdpofstring", "htofstring", "hyphen", "hyphenatedcoloredword", "hyphenatedfile", "hyphenatedfilename", "hyphenatedhbox", "hyphenatedpar", "hyphenatedurl", "hyphenatedword", "iacute", "ibox", "ibreve", "icaron", "icircumflex", "ideographichalffillspace", "ideographicspace", "idiaeresis", "idotaccent", "idotbelow", "idoublegrave", "ifassignment", "iff", "ifinobject", "ifinoutputstream", "ifparameters", "iftrialtypesetting", "ignoreimplicitspaces", "ignorevalue", "igrave", "ihook", "iiiint", "iiiintop", "iiint", "iiintop", "iint", "iintop", "iinvertedbreve", "ijligature", "imacron", "imaginaryi", "imaginaryj", "imath", "immediatesavetwopassdata", "impliedby", "implies", "imply", "in", "includemenu", "includeversioninfo", "increment", "incrementcounter", "incrementedcounter", "incrementpagenumber", "incrementsubpagenumber", "incrementvalue", "indentation", "index", "infofont", "infofontbold", "inframed", "infty", "infull", "inheritparameter", "inhibitblank", "ininner", "ininneredge", "ininnermargin", "initializeboxstack", "inleft", "inleftedge", "inleftmargin", "inline", "inlinebuffer", "inlinedbox", "inlinemath", "inlinemathematics", "inlinemessage", "inlineordisplaymath", "inlineprettyprintbuffer", "inlinerange", "inmargin", "inmframed", "innerflushshapebox", "inother", "inouter", "inouteredge", "inoutermargin", "input", "inputfilebarename", "inputfilename", "inputfilerealsuffix", "inputfilesuffix", "inputgivenfile", "inright", "inrightedge", "inrightmargin", "insertpages", "installactionhandler", "installactivecharacter", "installanddefineactivecharacter", "installattributestack", "installautocommandhandler", "installautosetuphandler", "installbasicautosetuphandler", "installbasicparameterhandler", "installbottomframerenderer", "installcommandhandler", "installcorenamespace", "installdefinehandler", "installdefinitionset", "installdefinitionsetmember", "installdirectcommandhandler", "installdirectparameterhandler", "installdirectparametersethandler", "installdirectsetuphandler", "installdirectstyleandcolorhandler", "installframedautocommandhandler", "installframedcommandhandler", "installlanguage", "installleftframerenderer", "installnamespace", "installoutputroutine", "installpagearrangement", "installparameterhandler", "installparameterhashhandler", "installparametersethandler", "installparentinjector", "installrightframerenderer", "installrootparameterhandler", "installsetuphandler", "installsetuponlycommandhandler", "installshipoutmethod", "installsimplecommandhandler", "installsimpleframedcommandhandler", "installstyleandcolorhandler", "installswitchcommandhandler", "installswitchsetuphandler", "installtexdirective", "installtextracker", "installtopframerenderer", "installunitsseparator", "installunitsspace", "installversioninfo", "int", "intclockwise", "integerrounding", "integers", "interactionbar", "interactionbuttons", "interactionmenu", "intercal", "intertext", "intop", "invisibletimes", "invokepageheandler", "iogonek", "iota", "istltdir", "istrtdir", "italic", "italicbold", "italiccorrection", "italicface", "item", "items", "itemtag", "itilde", "jcaron", "jcircumflex", "jmath", "jobfilename", "jobfilesuffix", "kap", "kappa", "kcaron", "kcommaaccent", "keepblocks", "keeplinestogether", "keepunwantedspaces", "kerncharacters", "khook", "kkra", "koreancirclenumerals", "koreannumerals", "koreannumeralsc", "koreannumeralsp", "koreanparentnumerals", "lVert", "labellanguage", "labeltext", "labeltexts", "lacute", "lambda", "lambdabar", "land", "langle", "language", "languageCharacters", "languagecharacters", "languagecharwidth", "lastcounter", "lastcountervalue", "lastdigit", "lastlinewidth", "lastnaturalboxdp", "lastnaturalboxht", "lastnaturalboxwd", "lastpredefinedsymbol", "lastrealpage", "lastrealpagenumber", "lastsubcountervalue", "lastsubpage", "lastsubpagenumber", "lasttwodigits", "lastuserpage", "lastuserpagenumber", "lateluacode", "latin", "layeredtext", "layerheight", "layerwidth", "lazysavetaggedtwopassdata", "lazysavetwopassdata", "lbar", "lbox", "lbrace", "lbracket", "lcaron", "lceil", "lcommaaccent", "lcurl", "ldotmiddle", "ldotp", "ldots", "le", "leadsto", "left", "leftaligned", "leftarrow", "leftarrowtail", "leftarrowtriangle", "leftbottombox", "leftbox", "leftdasharrow", "leftguillemot", "leftharpoondown", "leftharpoonup", "lefthbox", "leftheadtext", "leftlabeltext", "leftleftarrows", "leftline", "leftmathlabeltext", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "leftrightarrow", "leftrightarrows", "leftrightarrowtriangle", "leftrightharpoons", "leftrightsquigarrow", "leftskipadaption", "leftsquigarrow", "leftsubguillemot", "leftthreetimes", "lefttopbox", "lefttoright", "lefttorighthbox", "lefttorightvbox", "lefttorightvtop", "leftwavearrow", "leftwhitearrow", "leq", "leqq", "leqslant", "lessapprox", "lessdot", "lesseqgtr", "lesseqqgtr", "lessgtr", "lesssim", "letbeundefined", "letcatcodecommand", "letcscsname", "letcsnamecs", "letcsnamecsname", "letdummyparameter", "letempty", "letgvalue", "letgvalueempty", "letgvalurelax", "letterampersand", "letterat", "letterbackslash", "letterbar", "letterbgroup", "letterclosebrace", "lettercolon", "letterdollar", "letterdoublequote", "letteregroup", "letterescape", "letterexclamationmark", "letterhash", "letterhat", "letterleftbrace", "letterleftbracket", "letterleftparenthesis", "letterless", "lettermore", "letteropenbrace", "letterpercent", "letterquestionmark", "letterrightbrace", "letterrightbracket", "letterrightparenthesis", "lettersinglequote", "letterslash", "letterspacing", "lettertilde", "letterunderscore", "letvalue", "letvalueempty", "letvaluerelax", "lfence", "lfloor", "lgroup", "lhbox", "lhooknwarrow", "lhooksearrow", "limitatefirstline", "limitatelines", "limitatetext", "line", "linefeed", "linenote", "linespanningtext", "linethickness", "linterval", "listcitation", "listcite", "listlength", "listnamespaces", "ljligature", "ll", "llangle", "llap", "llbracket", "llcorner", "lll", "llless", "lmoustache", "lnapprox", "lneq", "lneqq", "lnot", "lnsim", "loadanyfile", "loadanyfileonce", "loadbtxdefinitionfile", "loadbtxreplacementfile", "loadcldfile", "loadcldfileonce", "loadfontgoodies", "loadluafile", "loadluafileonce", "loadspellchecklist", "loadtexfile", "loadtexfileonce", "loadtypescriptfile", "localframed", "localframedwithsettings", "localhsize", "localpopbox", "localpopmacro", "localpushbox", "localpushmacro", "localundefine", "locatedfilepath", "locatefilepath", "locfilename", "logo", "lohi", "lointerval", "lomihi", "longleftarrow", "longleftrightarrow", "longmapsfrom", "longmapsto", "longrightarrow", "longrightsquigarrow", "looparrowleft", "looparrowright", "lor", "low", "lowerbox", "lowercased", "lowercasestring", "lowerleftdoubleninequote", "lowerleftsingleninequote", "lowerrightdoubleninequote", "lowerrightsingleninequote", "lozenge", "lparent", "lrcorner", "lrointerval", "lrtbbox", "lstroke", "lt", "ltimes", "ltop", "luaTeX", "luacode", "luaconditional", "luaenvironment", "luaexpanded", "luaexpr", "luafunction", "luajitTeX", "luamajorversion", "luaminorversion", "luaparameterset", "luasetup", "luaversion", "lvert", "m", "mLeftarrow", "mLeftrightarrow", "mRightarrow", "mainlanguage", "makecharacteractive", "makerawcommalist", "makestrutofbox", "maltese", "mapfontsize", "mapsdown", "mapsfrom", "mapsto", "mapsup", "margindata", "margintext", "markcontent", "marking", "markinjector", "markpage", "mat", "math", "mathampersand", "mathbf", "mathbi", "mathblackboard", "mathbs", "mathdefault", "mathdollar", "mathdouble", "mathematics", "mathfraktur", "mathfunction", "mathhash", "mathhyphen", "mathit", "mathitalic", "mathlabellanguage", "mathlabeltext", "mathlabeltexts", "mathop", "mathover", "mathpercent", "mathrm", "mathscript", "mathsl", "mathss", "mathtext", "mathtextbf", "mathtextbi", "mathtextbs", "mathtextit", "mathtextsl", "mathtexttf", "mathtf", "mathtriplet", "mathtt", "mathunder", "mathupright", "mathword", "mathwordbf", "mathwordbi", "mathwordbs", "mathwordit", "mathwordsl", "mathwordtf", "maxaligned", "mbox", "mcframed", "measure", "measured", "measuredangle", "measuredeq", "medskip", "medspace", "menubutton", "mequal", "message", "metaTeX", "mfence", "mframed", "mfunction", "mfunctionlabeltext", "mhbox", "mho", "mhookleftarrow", "mhookrightarrow", "mid", "midaligned", "middle", "middlealigned", "middlebox", "midhbox", "minimalhbox", "minus", "minuscolon", "mirror", "mixedcaps", "mkvibuffer", "mleftarrow", "mleftharpoondown", "mleftharpoonup", "mleftrightarrow", "mleftrightharpoons", "mmapsto", "models", "moduleparameter", "molecule", "mono", "monobold", "mononormal", "month", "monthlong", "monthshort", "mp", "mprandomnumber", "mrel", "mrightarrow", "mrightharpoondown", "mrightharpoonup", "mrightleftharpoons", "mrightoverleftarrow", "mtext", "mtriplerel", "mtwoheadleftarrow", "mtwoheadrightarrow", "mu", "multimap", "nHdownarrow", "nHuparrow", "nLeftarrow", "nLeftrightarrow", "nRightarrow", "nVDash", "nVdash", "nVleftarrow", "nVleftrightarrow", "nVrightarrow", "nabla", "nacute", "namedheadnumber", "namedstructureheadlocation", "namedstructureuservariable", "namedstructurevariable", "namedtaggedlabeltexts", "napostrophe", "napprox", "napproxEq", "narrownobreakspace", "nasymp", "natural", "naturalhbox", "naturalhpack", "naturalnumbers", "naturalvbox", "naturalvcenter", "naturalvpack", "naturalvtop", "naturalwd", "ncaron", "ncommaaccent", "ncong", "ncurl", "ndivides", "ne", "nearrow", "neg", "negatecolorbox", "negated", "negativesign", "negthinspace", "neng", "neq", "nequiv", "neswarrow", "newattribute", "newcatcodetable", "newcounter", "newevery", "newfrenchspacing", "newmode", "newsignal", "newsystemmode", "nexists", "nextbox", "nextboxdp", "nextboxht", "nextboxhtdp", "nextboxwd", "nextcounter", "nextcountervalue", "nextdepth", "nextparagraphs", "nextrealpage", "nextrealpagenumber", "nextsubcountervalue", "nextsubpage", "nextsubpagenumber", "nextuserpage", "nextuserpagenumber", "ngeq", "ngrave", "ngtr", "ngtrless", "ngtrsim", "ni", "nihongo", "nin", "njligature", "nleftarrow", "nleftrightarrow", "nleq", "nless", "nlessgtr", "nlesssim", "nmid", "nni", "nobar", "nobreakspace", "nocap", "nocitation", "nocite", "nodetostring", "noffigurepages", "noflines", "noflocalfloats", "noheaderandfooterlines", "noheightstrut", "noindentation", "noitem", "nonfrenchspacing", "nonmathematics", "normal", "normalboldface", "normalframedwithsettings", "normalitalicface", "normalizebodyfontsize", "normalizedfontsize", "normalizefontdepth", "normalizefontheight", "normalizefontline", "normalizefontwidth", "normalizetextdepth", "normalizetextheight", "normalizetextline", "normalizetextwidth", "normalslantedface", "normaltypeface", "nospace", "not", "note", "notesymbol", "notin", "notopandbottomlines", "notragged", "nowns", "nparallel", "nprec", "npreccurlyeq", "nrightarrow", "nsim", "nsimeq", "nsqsubseteq", "nsqsupseteq", "nsubset", "nsubseteq", "nsucc", "nsucccurlyeq", "nsupset", "nsupseteq", "ntilde", "ntimes", "ntriangleleft", "ntrianglelefteq", "ntriangleright", "ntrianglerighteq", "nu", "numberofpoints", "numbers", "nvDash", "nvdash", "nvleftarrow", "nvleftrightarrow", "nvrightarrow", "nwarrow", "nwsearrow", "oacute", "obeydepth", "objectdepth", "objectheight", "objectmargin", "objectwidth", "obox", "obreve", "ocaron", "ocircumflex", "ocircumflexacute", "ocircumflexdotbelow", "ocircumflexgrave", "ocircumflexhook", "ocircumflextilde", "odiaeresis", "odiaeresismacron", "odot", "odotaccent", "odotaccentmacron", "odotbelow", "odoublegrave", "oeligature", "offset", "offsetbox", "ograve", "ohm", "ohook", "ohorn", "ohornacute", "ohorndotbelow", "ohorngrave", "ohornhook", "ohorntilde", "ohungarumlaut", "oiiint", "oiint", "oint", "ointclockwise", "ointctrclockwise", "oinvertedbreve", "omacron", "omega", "omicron", "ominus", "onedigitrounding", "oneeighth", "onefifth", "onehalf", "onequarter", "onesixth", "onesuperior", "onethird", "oogonek", "oogonekmacron", "operatorlanguage", "operatortext", "oplus", "ordfeminine", "ordinaldaynumber", "ordinalstr", "ordmasculine", "ornamenttext", "oslash", "ostroke", "ostrokeacute", "otilde", "otildemacron", "otimes", "outputfilename", "outputstreambox", "outputstreamcopy", "outputstreamunvbox", "outputstreamunvcopy", "over", "overbar", "overbars", "overbarunderbar", "overbrace", "overbraceunderbrace", "overbracket", "overbracketunderbracket", "overlaybutton", "overlaycolor", "overlaydepth", "overlayfigure", "overlayheight", "overlaylinecolor", "overlaylinewidth", "overlayoffset", "overlayrollbutton", "overlaywidth", "overleftarrow", "overloaderror", "overparent", "overparentunderparent", "overrightarrow", "overset", "overstrike", "overstrikes", "owns", "page", "pagearea", "pagebreak", "pagefigure", "pagegridspanwidth", "pageinjection", "pagenumber", "pagereference", "pagestaterealpage", "paletsize", "paragraphmark", "parallel", "part", "partial", "pdfTeX", "pdfactualtext", "pdfbackendactualtext", "pdfbackendcurrentresources", "pdfbackendsetcatalog", "pdfbackendsetcolorspace", "pdfbackendsetextgstate", "pdfbackendsetinfo", "pdfbackendsetname", "pdfbackendsetpageattribute", "pdfbackendsetpageresource", "pdfbackendsetpagesattribute", "pdfbackendsetpattern", "pdfbackendsetshade", "pdfcolor", "pdfeTeX", "percent", "percentdimen", "periodcentered", "periods", "permitcaretescape", "permitcircumflexescape", "permitspacesbetweengroups", "perp", "persiandecimals", "persiannumerals", "perthousand", "phantom", "phantombox", "phi", "phook", "pi", "pickupgroupedcommand", "pitchfork", "placeattachments", "placebookmarks", "placebtxrendering", "placechemical", "placecitation", "placecombinedlist", "placecomments", "placecontent", "placecurrentformulanumber", "placedbox", "placefigure", "placefloat", "placefloatwithsetups", "placefootnotes", "placeformula", "placeframed", "placegraphic", "placeheadnumber", "placeheadtext", "placehelp", "placeindex", "placeinitial", "placeintermezzo", "placelayer", "placelayeredtext", "placelegend", "placelist", "placelistofabbreviations", "placelistofchemicals", "placelistoffigures", "placelistofgraphics", "placelistofintermezzi", "placelistoflogos", "placelistofpublications", "placelistofsorts", "placelistofsynonyms", "placelistoftables", "placelocalfootnotes", "placelocalnotes", "placement", "placenamedfloat", "placenamedformula", "placenotes", "placeongrid", "placeontopofeachother", "placepagenumber", "placepairedbox", "placeparallel", "placerawlist", "placeregister", "placerenderingwindow", "placesidebyside", "placesubformula", "placetable", "pm", "popattribute", "popmacro", "popmode", "popsystemmode", "position", "positionoverlay", "positionregionoverlay", "positivesign", "postponenotes", "prec", "precapprox", "preccurlyeq", "preceq", "preceqq", "precnapprox", "precneq", "precneqq", "precnsim", "precsim", "predefinedfont", "predefinefont", "predefinesymbol", "prefixedpagenumber", "prefixlanguage", "prefixtext", "prependetoks", "prependgvalue", "prependtocommalist", "prependtoks", "prependtoksonce", "prependvalue", "presetbtxlabeltext", "presetdocument", "presetfieldsymbols", "presetheadtext", "presetlabeltext", "presetmathlabeltext", "presetoperatortext", "presetprefixtext", "presetsuffixtext", "presettaglabeltext", "presetunittext", "pretocommalist", "prettyprintbuffer", "prevcounter", "prevcountervalue", "preventmode", "prevrealpage", "prevrealpagenumber", "prevsubcountervalue", "prevsubpage", "prevsubpagenumber", "prevuserpage", "prevuserpagenumber", "prime", "primes", "procent", "processMPbuffer", "processMPfigurefile", "processaction", "processallactionsinset", "processassignlist", "processassignmentcommand", "processassignmentlist", "processbetween", "processblocks", "processbodyfontenvironmentlist", "processcolorcomponents", "processcommacommand", "processcommalist", "processcommalistwithparameters", "processcontent", "processfile", "processfilemany", "processfilenone", "processfileonce", "processfirstactioninset", "processisolatedchars", "processisolatedwords", "processlinetablebuffer", "processlinetablefile", "processlist", "processmonth", "processranges", "processseparatedlist", "processtexbuffer", "processtokens", "processuntil", "processxtablebuffer", "processyear", "prod", "product", "profiledbox", "profilegivenbox", "program", "project", "propto", "pseudoMixedCapped", "pseudoSmallCapped", "pseudoSmallcapped", "pseudosmallcapped", "psi", "punctuationspace", "purenumber", "pushattribute", "pushbutton", "pushmacro", "pushmode", "pushoutputstream", "pushsystemmode", "putboxincache", "putnextboxincache", "qquad", "quad", "quadrupleprime", "quads", "quarterstrut", "questiondown", "questionedeq", "quitcommalist", "quitprevcommalist", "quittypescriptscanning", "quotation", "quote", "quotedbl", "quotedblbase", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "quotesingle", "quotesinglebase", "rVert", "racute", "raggedbottom", "raggedcenter", "raggedleft", "raggedright", "raggedwidecenter", "raisebox", "randomizetext", "randomnumber", "rangle", "rationals", "rawcounter", "rawcountervalue", "rawdate", "rawdoifelseinset", "rawdoifinset", "rawdoifinsetelse", "rawgetparameters", "rawprocessaction", "rawprocesscommacommand", "rawprocesscommalist", "rawstructurelistuservariable", "rawsubcountervalue", "rbox", "rbrace", "rbracket", "rcaron", "rceil", "rcommaaccent", "rdoublegrave", "readfile", "readfixfile", "readjobfile", "readlocfile", "readsetfile", "readsysfile", "readtexfile", "readxmlfile", "realSmallCapped", "realSmallcapped", "realpagenumber", "reals", "realsmallcapped", "recursedepth", "recurselevel", "recursestring", "redoconvertfont", "ref", "reference", "referenceprefix", "referring", "registerattachment", "registerctxluafile", "registered", "registerexternalfigure", "registerfontclass", "registerhyphenationexception", "registerhyphenationpattern", "registermenubuttons", "registersort", "registersynonym", "registerunit", "regular", "relatemarking", "relateparameterhandlers", "relaxvalueifundefined", "relbar", "remainingcharacters", "remark", "removebottomthings", "removedepth", "removefromcommalist", "removelastskip", "removelastspace", "removemarkedcontent", "removepunctuation", "removesubstring", "removetoks", "removeunwantedspaces", "replacefeature", "replaceincommalist", "replaceword", "rescan", "rescanwithsetup", "resetMPdrawing", "resetMPenvironment", "resetMPinstance", "resetallattributes", "resetandaddfeature", "resetbar", "resetboxesincache", "resetbreakpoints", "resetbuffer", "resetcharacteralign", "resetcharacterkerning", "resetcharacterspacing", "resetcharacterstripping", "resetcollector", "resetcounter", "resetdigitsmanipulation", "resetdirection", "resetfeature", "resetflag", "resetfontcolorsheme", "resetfontfallback", "resetfontsolution", "resethyphenationfeatures", "resetinjector", "resetinteractionmenu", "resetitaliccorrection", "resetlayer", "resetlocalfloats", "resetmarker", "resetmarking", "resetmode", "resetpagenumber", "resetparallel", "resetpath", "resetpenalties", "resetprofile", "resetrecurselevel", "resetreference", "resetreplacement", "resetscript", "resetsetups", "resetshownsynonyms", "resetsubpagenumber", "resetsymbolset", "resetsystemmode", "resettimer", "resettrackers", "resettrialtypesetting", "resetusedsortings", "resetusedsynonyms", "resetuserpagenumber", "resetvalue", "resetvisualizers", "reshapebox", "resolvedglyphdirect", "resolvedglyphstyled", "restartcounter", "restorebox", "restorecatcodes", "restorecounter", "restorecurrentattributes", "restoreendofline", "restoreglobalbodyfont", "restriction", "reusableMPgraphic", "reuseMPgraphic", "reuserandomseed", "reverseddoubleprime", "reversedprime", "reversedtripleprime", "revivefeature", "rfence", "rfloor", "rgroup", "rhbox", "rho", "rhooknearrow", "rhookswarrow", "right", "rightaligned", "rightangle", "rightarrow", "rightarrowbar", "rightarrowtail", "rightarrowtriangle", "rightbottombox", "rightbox", "rightdasharrow", "rightguillemot", "rightharpoondown", "rightharpoonup", "righthbox", "rightheadtext", "rightlabeltext", "rightleftarrows", "rightleftharpoons", "rightline", "rightmathlabeltext", "rightorleftpageaction", "rightrightarrows", "rightskipadaption", "rightsquigarrow", "rightsubguillemot", "rightthreearrows", "rightthreetimes", "righttoleft", "righttolefthbox", "righttoleftvbox", "righttoleftvtop", "righttopbox", "rightwavearrow", "rightwhitearrow", "ring", "rinterval", "rinvertedbreve", "risingdotseq", "rlap", "rlointerval", "rmoustache", "rneq", "robustaddtocommalist", "robustdoifelseinset", "robustdoifinsetelse", "robustpretocommalist", "rointerval", "rollbutton", "roman", "romanC", "romanD", "romanI", "romanII", "romanIII", "romanIV", "romanIX", "romanL", "romanM", "romanV", "romanVI", "romanVII", "romanVIII", "romanX", "romanXI", "romanXII", "romanc", "romand", "romani", "romanii", "romaniii", "romaniv", "romanix", "romanl", "romanm", "romannumerals", "romanv", "romanvi", "romanvii", "romanviii", "romanx", "romanxi", "romanxii", "rootradical", "rotate", "rparent", "rrangle", "rrbracket", "rrointerval", "rtimes", "rtop", "ruledhbox", "ruledhpack", "ruledmbox", "ruledtopv", "ruledtpack", "ruledvbox", "ruledvpack", "ruledvtop", "runMPbuffer", "runninghbox", "rvert", "sacute", "safechar", "samplefile", "sans", "sansbold", "sansnormal", "sansserif", "savebox", "savebtxdataset", "savebuffer", "savecounter", "savecurrentattributes", "savenormalmeaning", "savetaggedtwopassdata", "savetwopassdata", "sbox", "scale", "scaron", "scedilla", "schwa", "schwahook", "scircumflex", "scommaaccent", "screen", "searrow", "secondoffivearguments", "secondoffourarguments", "secondofsixarguments", "secondofthreearguments", "secondofthreeunexpanded", "secondoftwoarguments", "secondoftwounexpanded", "section", "sectionmark", "seeindex", "select", "selectblocks", "serializecommalist", "serializedcommalist", "serif", "serifbold", "serifnormal", "setJSpreamble", "setMPlayer", "setMPpositiongraphic", "setMPpositiongraphicrange", "setMPtext", "setMPvariable", "setMPvariables", "setbar", "setbigbodyfont", "setboxllx", "setboxlly", "setbreakpoints", "setcapstrut", "setcatcodetable", "setcharacteralign", "setcharactercasing", "setcharactercleaning", "setcharacterkerning", "setcharacterspacing", "setcharacterstripping", "setcharstrut", "setcollector", "setcolormodell", "setcounter", "setcounterown", "setcurrentfontclass", "setdataset", "setdefaultpenalties", "setdigitsmanipulation", "setdirection", "setdocumentargument", "setdocumentargumentdefault", "setdocumentfilename", "setdummyparameter", "setelementexporttag", "setemeasure", "setevalue", "setevariable", "setevariables", "setfirstline", "setflag", "setfont", "setfontcolorsheme", "setfontfeature", "setfontsolution", "setfontstrut", "setgmeasure", "setgvalue", "setgvariable", "setgvariables", "sethboxregister", "sethyphenatedurlafter", "sethyphenatedurlbefore", "sethyphenatedurlnormal", "sethyphenationfeatures", "setinitial", "setinjector", "setinteraction", "setinterfacecommand", "setinterfaceconstant", "setinterfaceelement", "setinterfacemessage", "setinterfacevariable", "setinternalrendering", "setitaliccorrection", "setlayer", "setlayerframed", "setlayertext", "setlinefiller", "setlocalhsize", "setmainbodyfont", "setmainparbuilder", "setmarker", "setmarking", "setmathstyle", "setmeasure", "setmessagetext", "setminus", "setmode", "setnostrut", "setnote", "setnotetext", "setobject", "setoldstyle", "setpagegrid", "setpagereference", "setpagestate", "setpagestaterealpageno", "setpenalties", "setpercentdimen", "setposition", "setpositionbox", "setpositiondata", "setpositiondataplus", "setpositiononly", "setpositionplus", "setpositionstrut", "setprofile", "setrandomseed", "setreference", "setreferencedobject", "setregisterentry", "setreplacement", "setrigidcolumnbalance", "setrigidcolumnhsize", "setscript", "setsectionblock", "setsimplecolumnhsize", "setsmallbodyfont", "setsmallcaps", "setstackbox", "setstructurepageregister", "setstrut", "setsuperiors", "setsystemmode", "settabular", "settaggedmetadata", "settextcontent", "settightobject", "settightreferencedobject", "settightunreferencedobject", "settrialtypesetting", "setuevalue", "setugvalue", "setunreferencedobject", "setup", "setupMPgraphics", "setupMPinstance", "setupMPpage", "setupMPvariables", "setupTABLE", "setupTEXpage", "setupalign", "setupalternativestyles", "setuparranging", "setupattachment", "setupattachments", "setupbackend", "setupbackground", "setupbackgrounds", "setupbar", "setupbars", "setupblackrules", "setupblank", "setupbleeding", "setupblock", "setupbodyfont", "setupbookmark", "setupbottom", "setupbottomtexts", "setupbtx", "setupbtxdataset", "setupbtxlabeltext", "setupbtxlist", "setupbtxregister", "setupbtxrendering", "setupbuffer", "setupbutton", "setupcapitals", "setupcaption", "setupcaptions", "setupcharacterkerning", "setupcharacterspacing", "setupchemical", "setupchemicalframed", "setupclipping", "setupcollector", "setupcolor", "setupcolors", "setupcolumns", "setupcolumnspan", "setupcombination", "setupcombinedlist", "setupcomment", "setupcontent", "setupcounter", "setupdataset", "setupdelimitedtext", "setupdescription", "setupdirections", "setupdocument", "setupeffect", "setupenumeration", "setupenumerations", "setupenv", "setupexport", "setupexternalfigure", "setupexternalsoundtracks", "setupfield", "setupfieldbody", "setupfieldcategory", "setupfieldcontentframed", "setupfieldlabelframed", "setupfields", "setupfieldtotalframed", "setupfiller", "setupfillinlines", "setupfillinrules", "setupfirstline", "setupfittingpage", "setupfloat", "setupfloatcaption", "setupfloats", "setupfloatsplitting", "setupfontexpansion", "setupfontprotrusion", "setupfonts", "setupfontsolution", "setupfooter", "setupfootertexts", "setupforms", "setupformula", "setupformulae", "setupformulaframed", "setupframed", "setupframedcontent", "setupframedtable", "setupframedtablecolumn", "setupframedtablerow", "setupframedtext", "setupframedtexts", "setupglobalreferenceprefix", "setuphead", "setupheadalternative", "setupheader", "setupheadertexts", "setupheadnumber", "setupheads", "setupheadtext", "setuphelp", "setuphigh", "setuphighlight", "setuphyphenation", "setuphyphenmark", "setupindentedtext", "setupindenting", "setupindex", "setupinitial", "setupinsertion", "setupinteraction", "setupinteractionbar", "setupinteractionmenu", "setupinteractionscreen", "setupinterlinespace", "setupitaliccorrection", "setupitemgroup", "setupitemizations", "setupitemize", "setupitems", "setuplabel", "setuplabeltext", "setuplanguage", "setuplayer", "setuplayeredtext", "setuplayout", "setuplayouttext", "setuplegend", "setuplinefiller", "setuplinefillers", "setuplinenote", "setuplinenumbering", "setuplines", "setuplinetable", "setuplinewidth", "setuplist", "setuplistalternative", "setuplistextra", "setuplocalfloats", "setuplocalinterlinespace", "setuplow", "setuplowhigh", "setuplowmidhigh", "setupmakeup", "setupmarginblock", "setupmargindata", "setupmarginframed", "setupmarginrule", "setupmarginrules", "setupmarking", "setupmathalignment", "setupmathcases", "setupmathematics", "setupmathfence", "setupmathfraction", "setupmathfractions", "setupmathframed", "setupmathlabeltext", "setupmathmatrix", "setupmathornament", "setupmathradical", "setupmathstackers", "setupmathstyle", "setupmixedcolumns", "setupmodule", "setupnarrower", "setupnotation", "setupnotations", "setupnote", "setupnotes", "setupoffset", "setupoffsetbox", "setupoperatortext", "setupoppositeplacing", "setupoutputroutine", "setuppagechecker", "setuppagecomment", "setuppagegrid", "setuppagegridarea", "setuppagegridareatext", "setuppagegridlines", "setuppagegridspan", "setuppagegridstart", "setuppageinjection", "setuppageinjectionalternative", "setuppagenumber", "setuppagenumbering", "setuppageshift", "setuppagestate", "setuppagetransitions", "setuppairedbox", "setuppalet", "setuppaper", "setuppapersize", "setupparagraph", "setupparagraphintro", "setupparagraphnumbering", "setupparagraphs", "setupparallel", "setupperiods", "setupplacement", "setuppositionbar", "setuppositioning", "setupprefixtext", "setupprocessor", "setupprofile", "setupprograms", "setupquotation", "setupquote", "setuprealpagenumber", "setupreferenceformat", "setupreferenceprefix", "setupreferencestructureprefix", "setupreferencing", "setupregister", "setupregisters", "setuprenderingwindow", "setuprotate", "setups", "setupscale", "setupscript", "setupscripts", "setupsectionblock", "setupselector", "setupshift", "setupsidebar", "setupsorting", "setupspacing", "setupspellchecking", "setupstartstop", "setupstretched", "setupstruts", "setupstyle", "setupsubformula", "setupsubformulas", "setupsubpagenumber", "setupsuffixtext", "setupsymbolset", "setupsynctex", "setupsynonyms", "setuptables", "setuptabulate", "setuptabulation", "setuptagging", "setuptaglabeltext", "setuptext", "setuptextbackground", "setuptextflow", "setuptextrules", "setuptexttexts", "setupthinrules", "setuptolerance", "setuptooltip", "setuptop", "setuptoptexts", "setuptype", "setuptyping", "setupunit", "setupunittext", "setupurl", "setupuserpagenumber", "setupversion", "setupviewerlayer", "setupvspacing", "setupwhitespace", "setupwithargument", "setupwithargumentswapped", "setupxml", "setupxtable", "setuvalue", "setuxvalue", "setvalue", "setvariable", "setvariables", "setvboxregister", "setvisualizerfont", "setvtopregister", "setwidthof", "setxmeasure", "setxvalue", "setxvariable", "setxvariables", "seveneighths", "sfrac", "shapedhbox", "sharp", "shiftdown", "shiftup", "showallmakeup", "showattributes", "showbodyfont", "showbodyfontenvironment", "showboxes", "showbtxdatasetauthors", "showbtxdatasetcompleteness", "showbtxdatasetfields", "showbtxfields", "showbtxhashedauthors", "showbtxtables", "showchardata", "showcharratio", "showcolor", "showcolorbar", "showcolorcomponents", "showcolorgroup", "showcolorset", "showcolorstruts", "showcounter", "showdirectives", "showdirsinmargin", "showedebuginfo", "showexperiments", "showfont", "showfontdata", "showfontitalics", "showfontkerns", "showfontparameters", "showfontstrip", "showfontstyle", "showframe", "showglyphs", "showgrid", "showgridsnapping", "showhelp", "showhyphenationtrace", "showhyphens", "showinjector", "showjustification", "showkerning", "showlayout", "showlayoutcomponents", "showligature", "showligatures", "showlogcategories", "showmakeup", "showmargins", "showmessage", "showminimalbaseline", "shownextbox", "showotfcomposition", "showpalet", "showparentchain", "showprint", "showsetups", "showsetupsdefinition", "showstruts", "showsymbolset", "showtimer", "showtokens", "showtrackers", "showvalue", "showvariable", "showwarning", "sigma", "sim", "simeq", "simplealignedbox", "simplealignedboxplus", "simplealignedspreadbox", "simplegroupedcommand", "simplereversealignedbox", "simplereversealignedboxplus", "singalcharacteralign", "singlebond", "singleverticalbar", "sixperemspace", "sixthofsixarguments", "slanted", "slantedbold", "slantedface", "slash", "slicepages", "slong", "slovenianNumerals", "sloveniannumerals", "small", "smallbodyfont", "smallbold", "smallbolditalic", "smallboldslanted", "smallcappedcharacters", "smallcappedromannumerals", "smaller", "smallitalicbold", "smallnormal", "smallskip", "smallslanted", "smallslantedbold", "smalltype", "smash", "smashbox", "smashboxed", "smashedhbox", "smashedvbox", "smile", "snaptogrid", "softhyphen", "solidus", "someheadnumber", "somekindoftab", "someline", "somelocalfloat", "somenamedheadnumber", "someplace", "somewhere", "space", "spadesuit", "spanishNumerals", "spanishnumerals", "speech", "sphericalangle", "splitatasterisk", "splitatcolon", "splitatcolons", "splitatcomma", "splitatperiod", "splitdfrac", "splitfilename", "splitfloat", "splitfrac", "splitoffbase", "splitofffull", "splitoffkind", "splitoffname", "splitoffpath", "splitoffroot", "splitofftokens", "splitofftype", "splitstring", "spreadhbox", "sqcap", "sqcup", "sqrt", "sqsubset", "sqsubseteq", "sqsubsetneq", "sqsupset", "sqsupseteq", "sqsupsetneq", "square", "squaredots", "ssharp", "stackrel", "star", "stareq", "startJScode", "startJSpreamble", "startLUA", "startMP", "startMPclip", "startMPcode", "startMPdefinitions", "startMPdrawing", "startMPenvironment", "startMPextensions", "startMPinclusions", "startMPinitializations", "startMPpage", "startMPpositiongraphic", "startMPpositionmethod", "startMPrun", "startPARSEDXML", "startTABLE", "startTABLEbody", "startTABLEfoot", "startTABLEhead", "startTABLEnext", "startTC", "startTD", "startTDs", "startTEX", "startTEXpage", "startTH", "startTN", "startTR", "startTRs", "startTX", "startTY", "startXML", "startalign", "startalignment", "startallmodes", "startappendices", "startarrangedpages", "startaside", "startattachment", "startbackground", "startbackmatter", "startbar", "startbbordermatrix", "startbitmapimage", "startblockquote", "startbodymatter", "startbordermatrix", "startboxedcolumns", "startbtxlabeltext", "startbtxrenderingdefinitions", "startbuffer", "startcases", "startcatcodetable", "startcenteraligned", "startchapter", "startcharacteralign", "startcheckedfences", "startchemical", "startchemicaltext", "startcollect", "startcollecting", "startcolor", "startcolorintent", "startcoloronly", "startcolorset", "startcolumns", "startcolumnspan", "startcombination", "startcomment", "startcomponent", "startcontextcode", "startcontextdefinitioncode", "startctxfunction", "startctxfunctiondefinition", "startcurrentcolor", "startcurrentlistentrywrapper", "startdelimited", "startdelimitedtext", "startdisplaymath", "startdmath", "startdocument", "starteffect", "startelement", "startembeddedxtable", "startendnote", "startendofline", "startenvironment", "startexceptions", "startexpanded", "startexpandedcollect", "startextendedcatcodetable", "startexternalfigurecollection", "startfact", "startfigure", "startfiguretext", "startfittingpage", "startfixed", "startfloatcombination", "startfont", "startfontclass", "startfontsolution", "startfootnote", "startformula", "startformulas", "startframed", "startframedcell", "startframedcontent", "startframedrow", "startframedtable", "startframedtext", "startfrontmatter", "startgoto", "startgraphictext", "startgridsnapping", "starthanging", "starthbox", "starthboxestohbox", "starthboxregister", "starthead", "startheadtext", "starthelptext", "starthiding", "starthighlight", "starthyphenation", "startimath", "startindentation", "startindentedtext", "startinteraction", "startinteractionmenu", "startinterface", "startintermezzotext", "startintertext", "startitem", "startitemgroup", "startitemgroupcolumns", "startitemize", "startknockout", "startlabeltext", "startlayout", "startleftaligned", "startlegend", "startline", "startlinealignment", "startlinecorrection", "startlinefiller", "startlinenote", "startlinenumbering", "startlines", "startlinetable", "startlinetablebody", "startlinetablecell", "startlinetablehead", "startlocalfootnotes", "startlocalheadsetup", "startlocallinecorrection", "startlocalnotes", "startlocalsetups", "startlua", "startluacode", "startluaparameterset", "startluasetups", "startmakeup", "startmarginblock", "startmarginrule", "startmarkedcontent", "startmathalignment", "startmathcases", "startmathlabeltext", "startmathmatrix", "startmathmode", "startmathstyle", "startmatrices", "startmatrix", "startmaxaligned", "startmdformula", "startmidaligned", "startmiddlealigned", "startmiddlemakeup", "startmixedcolumns", "startmode", "startmodeset", "startmodule", "startmoduletestsection", "startmpformula", "startnamedsection", "startnamedsubformulas", "startnarrow", "startnarrower", "startnegative", "startnicelyfilledbox", "startnointerference", "startnotallmodes", "startnotext", "startnotmode", "startoperatortext", "startopposite", "startoutputstream", "startoverlay", "startoverprint", "startpacked", "startpagecomment", "startpagefigure", "startpagegrid", "startpagegridspan", "startpagelayout", "startpagemakeup", "startpar", "startparagraph", "startparagraphs", "startparagraphscell", "startparbuilder", "startpart", "startpath", "startplacechemical", "startplacefigure", "startplacefloat", "startplaceformula", "startplacegraphic", "startplaceintermezzo", "startplacelegend", "startplacepairedbox", "startplacetable", "startpositioning", "startpositionoverlay", "startpositive", "startpostponing", "startprefixtext", "startprocessassignmentcommand", "startprocessassignmentlist", "startprocesscommacommand", "startprocesscommalist", "startproduct", "startproject", "startprotect", "startprotectedcolors", "startpublication", "startpunctuation", "startquotation", "startquote", "startrandomized", "startrandomseed", "startrawsetups", "startreadingfile", "startreferenceprefix", "startregime", "startregister", "startreusableMPgraphic", "startrightaligned", "startscript", "startsdformula", "startsection", "startsectionblock", "startsectionblockenvironment", "startsectionlevel", "startsetups", "startshapebox", "startshift", "startsidebar", "startsimplecolumns", "startspecialitem", "startspeech", "startspformula", "startspread", "startstandardmakeup", "startstartstop", "startstaticMPfigure", "startstaticMPgraphic", "startstrictinspectnextcharacter", "startstructurepageregister", "startstrut", "startstyle", "startsubformulas", "startsubject", "startsubjectlevel", "startsubsection", "startsubsentence", "startsubstack", "startsubsubject", "startsubsubsection", "startsubsubsubject", "startsubsubsubsection", "startsubsubsubsubject", "startsubsubsubsubsection", "startsubsubsubsubsubject", "startsuffixtext", "startsymbolset", "starttable", "starttablehead", "starttables", "starttabletail", "starttabletext", "starttabulate", "starttabulatehead", "starttabulatetail", "starttagged", "starttaglabeltext", "starttexcode", "starttexdefinition", "starttext", "starttextbackground", "starttextbackgroundmanual", "starttextcolor", "starttextcolorintent", "starttextflow", "starttextmakeup", "starttextrule", "starttitle", "starttokens", "starttransparent", "starttypescript", "starttypescriptcollection", "starttyping", "startuniqueMPgraphic", "startuniqueMPpagegraphic", "startunittext", "startunpacked", "startusableMPgraphic", "startuseMPgraphic", "startusemathstyleparameter", "startusingbtxspecification", "startvbox", "startvboxregister", "startvboxtohbox", "startvboxtohboxseparator", "startviewerlayer", "startvtop", "startvtopregister", "startxcell", "startxcellgroup", "startxgroup", "startxmldisplayverbatim", "startxmlinlineverbatim", "startxmlraw", "startxmlsetups", "startxrow", "startxrowgroup", "startxtable", "startxtablebody", "startxtablefoot", "startxtablehead", "startxtablenext", "stligature", "stopJScode", "stopJSpreamble", "stopLUA", "stopMP", "stopMPclip", "stopMPcode", "stopMPdefinitions", "stopMPdrawing", "stopMPenvironment", "stopMPextensions", "stopMPinclusions", "stopMPinitializations", "stopMPpage", "stopMPpositiongraphic", "stopMPpositionmethod", "stopMPrun", "stopPARSEDXML", "stopTABLE", "stopTABLEbody", "stopTABLEfoot", "stopTABLEhead", "stopTABLEnext", "stopTC", "stopTD", "stopTDs", "stopTEX", "stopTEXpage", "stopTH", "stopTN", "stopTR", "stopTRs", "stopTX", "stopTY", "stopXML", "stopalign", "stopalignment", "stopallmodes", "stopappendices", "stoparrangedpages", "stopaside", "stopattachment", "stopbackground", "stopbackmatter", "stopbar", "stopbbordermatrix", "stopbitmapimage", "stopblockquote", "stopbodymatter", "stopbordermatrix", "stopboxedcolumns", "stopbtxlabeltext", "stopbtxrenderingdefinitions", "stopbuffer", "stopcases", "stopcatcodetable", "stopcenteraligned", "stopchapter", "stopcharacteralign", "stopcheckedfences", "stopchemical", "stopchemicaltext", "stopcollect", "stopcollecting", "stopcolor", "stopcolorintent", "stopcoloronly", "stopcolorset", "stopcolumns", "stopcolumnspan", "stopcombination", "stopcomment", "stopcomponent", "stopcontextcode", "stopcontextdefinitioncode", "stopctxfunction", "stopctxfunctiondefinition", "stopcurrentcolor", "stopcurrentlistentrywrapper", "stopdelimited", "stopdelimitedtext", "stopdisplaymath", "stopdmath", "stopdocument", "stopeffect", "stopelement", "stopembeddedxtable", "stopendnote", "stopendofline", "stopenvironment", "stopexceptions", "stopexpanded", "stopexpandedcollect", "stopextendedcatcodetable", "stopexternalfigurecollection", "stopfact", "stopfigure", "stopfiguretext", "stopfittingpage", "stopfixed", "stopfloatcombination", "stopfont", "stopfontclass", "stopfontsolution", "stopfootnote", "stopformula", "stopformulas", "stopframed", "stopframedcell", "stopframedcontent", "stopframedrow", "stopframedtable", "stopframedtext", "stopfrontmatter", "stopgoto", "stopgraphictext", "stopgridsnapping", "stophanging", "stophbox", "stophboxestohbox", "stophboxregister", "stophead", "stopheadtext", "stophelptext", "stophiding", "stophighlight", "stophyphenation", "stopimath", "stopindentation", "stopindentedtext", "stopinteraction", "stopinteractionmenu", "stopinterface", "stopintermezzotext", "stopintertext", "stopitem", "stopitemgroup", "stopitemgroupcolumns", "stopitemize", "stopknockout", "stoplabeltext", "stoplayout", "stopleftaligned", "stoplegend", "stopline", "stoplinealignment", "stoplinecorrection", "stoplinefiller", "stoplinenote", "stoplinenumbering", "stoplines", "stoplinetable", "stoplinetablebody", "stoplinetablecell", "stoplinetablehead", "stoplocalfootnotes", "stoplocalheadsetup", "stoplocallinecorrection", "stoplocalnotes", "stoplocalsetups", "stoplua", "stopluacode", "stopluaparameterset", "stopluasetups", "stopmakeup", "stopmarginblock", "stopmarginrule", "stopmarkedcontent", "stopmathalignment", "stopmathcases", "stopmathlabeltext", "stopmathmatrix", "stopmathmode", "stopmathstyle", "stopmatrices", "stopmatrix", "stopmaxaligned", "stopmdformula", "stopmidaligned", "stopmiddlealigned", "stopmiddlemakeup", "stopmixedcolumns", "stopmode", "stopmodeset", "stopmodule", "stopmoduletestsection", "stopmpformula", "stopnamedsection", "stopnamedsubformulas", "stopnarrow", "stopnarrower", "stopnegative", "stopnicelyfilledbox", "stopnointerference", "stopnotallmodes", "stopnotext", "stopnotmode", "stopoperatortext", "stopopposite", "stopoutputstream", "stopoverlay", "stopoverprint", "stoppacked", "stoppagecomment", "stoppagefigure", "stoppagegrid", "stoppagegridspan", "stoppagelayout", "stoppagemakeup", "stoppar", "stopparagraph", "stopparagraphs", "stopparagraphscell", "stopparbuilder", "stoppart", "stoppath", "stopplacechemical", "stopplacefigure", "stopplacefloat", "stopplaceformula", "stopplacegraphic", "stopplaceintermezzo", "stopplacelegend", "stopplacepairedbox", "stopplacetable", "stoppositioning", "stoppositionoverlay", "stoppositive", "stoppostponing", "stopprefixtext", "stopprocessassignmentcommand", "stopprocessassignmentlist", "stopprocesscommacommand", "stopprocesscommalist", "stopproduct", "stopproject", "stopprotect", "stopprotectedcolors", "stoppublication", "stoppunctuation", "stopquotation", "stopquote", "stoprandomized", "stoprandomseed", "stoprawsetups", "stopreadingfile", "stopreferenceprefix", "stopregime", "stopregister", "stopreusableMPgraphic", "stoprightaligned", "stopscript", "stopsdformula", "stopsection", "stopsectionblock", "stopsectionblockenvironment", "stopsectionlevel", "stopsetups", "stopshapebox", "stopshift", "stopsidebar", "stopsimplecolumns", "stopspecialitem", "stopspeech", "stopspformula", "stopspread", "stopstandardmakeup", "stopstartstop", "stopstaticMPfigure", "stopstaticMPgraphic", "stopstrictinspectnextcharacter", "stopstructurepageregister", "stopstrut", "stopstyle", "stopsubformulas", "stopsubject", "stopsubjectlevel", "stopsubsection", "stopsubsentence", "stopsubstack", "stopsubsubject", "stopsubsubsection", "stopsubsubsubject", "stopsubsubsubsection", "stopsubsubsubsubject", "stopsubsubsubsubsection", "stopsubsubsubsubsubject", "stopsuffixtext", "stopsymbolset", "stoptable", "stoptablehead", "stoptables", "stoptabletail", "stoptabletext", "stoptabulate", "stoptabulatehead", "stoptabulatetail", "stoptagged", "stoptaglabeltext", "stoptexcode", "stoptexdefinition", "stoptext", "stoptextbackground", "stoptextbackgroundmanual", "stoptextcolor", "stoptextcolorintent", "stoptextflow", "stoptextmakeup", "stoptextrule", "stoptitle", "stoptokens", "stoptransparent", "stoptypescript", "stoptypescriptcollection", "stoptyping", "stopuniqueMPgraphic", "stopuniqueMPpagegraphic", "stopunittext", "stopunpacked", "stopusableMPgraphic", "stopuseMPgraphic", "stopusemathstyleparameter", "stopusingbtxspecification", "stopvbox", "stopvboxregister", "stopvboxtohbox", "stopvboxtohboxseparator", "stopviewerlayer", "stopvtop", "stopvtopregister", "stopxcell", "stopxcellgroup", "stopxgroup", "stopxmldisplayverbatim", "stopxmlinlineverbatim", "stopxmlraw", "stopxmlsetups", "stopxrow", "stopxrowgroup", "stopxtable", "stopxtablebody", "stopxtablefoot", "stopxtablehead", "stopxtablenext", "stretched", "strictdoifelsenextoptional", "strictdoifnextoptionalelse", "stripcharacter", "strippedcsname", "stripspaces", "structurelistuservariable", "structurenumber", "structuretitle", "structureuservariable", "structurevariable", "strut", "strutdp", "strutgap", "strutht", "struthtdp", "struttedbox", "strutwd", "style", "styleinstance", "subject", "subpagenumber", "subsection", "subsentence", "subset", "subseteq", "subseteqq", "subsetneq", "subsetneqq", "substituteincommalist", "subsubject", "subsubsection", "subsubsubject", "subsubsubsection", "subsubsubsubject", "subsubsubsubsection", "subsubsubsubsubject", "subtractfeature", "succ", "succapprox", "succcurlyeq", "succeq", "succeqq", "succnapprox", "succneq", "succneqq", "succnsim", "succsim", "suffixlanguage", "suffixtext", "sum", "supset", "supseteq", "supseteqq", "supsetneq", "supsetneqq", "surd", "surdradical", "swapcounts", "swapdimens", "swapface", "swapmacros", "swaptypeface", "swarrow", "switchstyleonly", "switchtobodyfont", "switchtocolor", "switchtointerlinespace", "symbol", "symbolreference", "synchronizeblank", "synchronizeindenting", "synchronizemarking", "synchronizeoutputstreams", "synchronizestrut", "synchronizewhitespace", "synctexblockfilename", "synctexresetfilename", "synctexsetfilename", "systemlog", "systemlogfirst", "systemloglast", "systemsetups", "tLeftarrow", "tLeftrightarrow", "tRightarrow", "tabulateautoline", "tabulateautorule", "tabulateline", "tabulaterule", "taggedctxcommand", "taggedlabeltexts", "taglabellanguage", "taglabeltext", "tau", "tbinom", "tbox", "tcaron", "tcedilla", "tcommaaccent", "tcurl", "tequal", "test", "testandsplitstring", "testcolumn", "testfeature", "testfeatureonce", "testpage", "testpageonly", "testpagesync", "testtokens", "tex", "texdefinition", "texsetup", "textAngstrom", "textacute", "textampersand", "textasciicircum", "textasciitilde", "textat", "textbackslash", "textbar", "textbottomcomma", "textbottomdot", "textbraceleft", "textbraceright", "textbreve", "textbrokenbar", "textbullet", "textcaron", "textcedilla", "textcelsius", "textcent", "textcircledP", "textcircumflex", "textcitation", "textcite", "textcomma", "textcontrolspace", "textcurrency", "textdag", "textddag", "textdegree", "textdiaeresis", "textdiv", "textdollar", "textdong", "textdotaccent", "textellipsis", "texteuro", "textflowcollector", "textfraction", "textgrave", "texthash", "texthorizontalbar", "texthungarumlaut", "texthyphen", "textkelvin", "textlognot", "textmacron", "textmath", "textmho", "textminus", "textmu", "textmultiply", "textnumero", "textogonek", "textohm", "textormathchar", "textounce", "textpercent", "textperiod", "textplus", "textpm", "textreference", "textring", "textrule", "textslash", "textsterling", "texttilde", "textunderscore", "textvisiblespace", "textyen", "thai", "thainumerals", "thefirstcharacter", "thenormalizedbodyfontsize", "therefore", "theremainingcharacters", "theta", "thickspace", "thinrule", "thinrules", "thinspace", "thirdoffivearguments", "thirdoffourarguments", "thirdofsixarguments", "thirdofthreearguments", "thirdofthreeunexpanded", "thook", "thookleftarrow", "thookrightarrow", "thorn", "threedigitrounding", "threeeighths", "threefifths", "threeperemspace", "threequarter", "threesuperior", "tibetannumerals", "tightlayer", "tilde", "times", "tinyfont", "title", "tlap", "tleftarrow", "tleftharpoondown", "tleftharpoonup", "tleftrightarrow", "tleftrightharpoons", "tmapsto", "to", "tochar", "tolinenote", "tooltip", "top", "topbox", "topleftbox", "toplinebox", "toprightbox", "topskippedbox", "tracecatcodetables", "tracedfontname", "traceoutputroutines", "tracepositions", "trademark", "translate", "transparencycomponents", "transparent", "trel", "triangle", "triangledown", "triangleleft", "triangleq", "triangleright", "trightarrow", "trightharpoondown", "trightharpoonup", "trightleftharpoons", "trightoverleftarrow", "triplebond", "tripleprime", "tripleverticalbar", "truefilename", "truefontname", "tstroke", "ttraggedright", "ttriplerel", "ttwoheadleftarrow", "ttwoheadrightarrow", "turnediota", "twodigitrounding", "twofifths", "twoheaddownarrow", "twoheadleftarrow", "twoheadrightarrow", "twoheadrightarrowtail", "twoheaduparrow", "twosuperior", "twothirds", "tx", "txx", "typ", "type", "typebuffer", "typedefinedbuffer", "typeface", "typefile", "typeinlinebuffer", "typescriptone", "typescriptprefix", "typescriptthree", "typescripttwo", "typesetbuffer", "typesetfile", "uacute", "ubreve", "ucaron", "ucircumflex", "uconvertnumber", "udiaeresis", "udiaeresisacute", "udiaeresiscaron", "udiaeresisgrave", "udiaeresismacron", "udotbelow", "udots", "udoublegrave", "uedcatcodecommand", "ugrave", "uhook", "uhorn", "uhornacute", "uhorndotbelow", "uhorngrave", "uhornhook", "uhorntilde", "uhungarumlaut", "uinvertedbreve", "ulcorner", "umacron", "undefinevalue", "undepthed", "underbar", "underbars", "underbrace", "underbracket", "underdash", "underdashes", "underdot", "underdots", "underleftarrow", "underparent", "underrandom", "underrandoms", "underrightarrow", "underset", "understrike", "understrikes", "undoassign", "unexpandeddocumentvariable", "unframed", "unhhbox", "unihex", "uniqueMPgraphic", "uniqueMPpagegraphic", "unit", "unitlanguage", "unitshigh", "unitslow", "unittext", "unknown", "unprotected", "unregisterhyphenationpattern", "unspaceafter", "unspaceargument", "unspaced", "unspacestring", "untexargument", "untexcommand", "uogonek", "upand", "uparrow", "updasharrow", "updownarrow", "updownarrowbar", "updownarrows", "upharpoonleft", "upharpoonright", "uplus", "uppercased", "uppercasestring", "upperleftdoubleninequote", "upperleftdoublesixquote", "upperleftsingleninequote", "upperleftsinglesixquote", "upperrightdoubleninequote", "upperrightdoublesixquote", "upperrightsingleninequote", "upperrightsinglesixquote", "upsilon", "upuparrows", "upwhitearrow", "urcorner", "uring", "url", "useJSscripts", "useMPenvironmentbuffer", "useMPgraphic", "useMPlibrary", "useMPrun", "useMPvariables", "useURL", "usealignparameter", "useblankparameter", "useblocks", "usebodyfont", "usebodyfontparameter", "usebtxdataset", "usebtxdefinitions", "usecitation", "usecolors", "usecomponent", "usedirectory", "usedummycolorparameter", "usedummystyleandcolor", "usedummystyleparameter", "useenvironment", "useexternaldocument", "useexternalfigure", "useexternalrendering", "useexternalsoundtrack", "usefigurebase", "usefile", "usegridparameter", "useindentingparameter", "useindentnextparameter", "useinterlinespaceparameter", "uselanguageparameter", "useluamodule", "usemathstyleparameter", "usemodule", "useproduct", "useprofileparameter", "useproject", "usereferenceparameter", "userpagenumber", "usesetupsparameter", "usestaticMPfigure", "usesubpath", "usesymbols", "usetexmodule", "usetypescript", "usetypescriptfile", "useurl", "usezipfile", "utfchar", "utflower", "utfupper", "utilde", "utilityregisterlength", "vDash", "varTheta", "varepsilon", "varkappa", "varnothing", "varphi", "varpi", "varrho", "varsigma", "vartheta", "vboxreference", "vdash", "vdots", "vec", "vee", "veebar", "veeeq", "verbatim", "verbatimstring", "verbosenumber", "version", "vert", "verticalgrowingbar", "verticalpositionbar", "veryraggedcenter", "veryraggedleft", "veryraggedright", "vglue", "viewerlayer", "vl", "vphantom", "vpos", "vsmash", "vsmashbox", "vsmashed", "vspace", "vspacing", "wcircumflex", "wdofstring", "wedge", "wedgeeq", "weekday", "whitearrowupfrombar", "widehat", "widetilde", "widthofstring", "widthspanningtext", "withoutpt", "word", "wordright", "words", "wordtonumber", "wp", "wr", "writebetweenlist", "writedatatolist", "writestatus", "writetolist", "xLeftarrow", "xLeftrightarrow", "xRightarrow", "xdefconvertedargument", "xequal", "xfrac", "xhookleftarrow", "xhookrightarrow", "xi", "xleftarrow", "xleftharpoondown", "xleftharpoonup", "xleftrightarrow", "xleftrightharpoons", "xmapsto", "xmladdindex", "xmlafterdocumentsetup", "xmlaftersetup", "xmlall", "xmlappenddocumentsetup", "xmlappendsetup", "xmlapplyselectors", "xmlatt", "xmlattdef", "xmlattribute", "xmlattributedef", "xmlbadinclusions", "xmlbeforedocumentsetup", "xmlbeforesetup", "xmlchainatt", "xmlchainattdef", "xmlchecknamespace", "xmlcommand", "xmlconcat", "xmlconcatrange", "xmlcontext", "xmlcount", "xmldefaulttotext", "xmldirectives", "xmldirectivesafter", "xmldirectivesbefore", "xmldisplayverbatim", "xmldoif", "xmldoifelse", "xmldoifelseempty", "xmldoifelseselfempty", "xmldoifelsetext", "xmldoifelsevalue", "xmldoifnot", "xmldoifnotselfempty", "xmldoifnottext", "xmldoifselfempty", "xmldoiftext", "xmlelement", "xmlfilter", "xmlfirst", "xmlflush", "xmlflushcontext", "xmlflushdocumentsetups", "xmlflushlinewise", "xmlflushpure", "xmlflushspacewise", "xmlflushtext", "xmlinclude", "xmlinclusion", "xmlinclusions", "xmlinfo", "xmlinjector", "xmlinlineprettyprint", "xmlinlineprettyprinttext", "xmlinlineverbatim", "xmlinstalldirective", "xmllast", "xmllastatt", "xmllastmatch", "xmlloadbuffer", "xmlloaddata", "xmlloaddirectives", "xmlloadfile", "xmlloadonly", "xmlmain", "xmlmapvalue", "xmlname", "xmlnamespace", "xmlnonspace", "xmlpath", "xmlpos", "xmlposition", "xmlprependdocumentsetup", "xmlprependsetup", "xmlprettyprint", "xmlprettyprinttext", "xmlprocessbuffer", "xmlprocessdata", "xmlprocessfile", "xmlpure", "xmlraw", "xmlrefatt", "xmlregistereddocumentsetups", "xmlregisteredsetups", "xmlregisterns", "xmlremapname", "xmlremapnamespace", "xmlremovedocumentsetup", "xmlremovesetup", "xmlresetdocumentsetups", "xmlresetinjectors", "xmlresetsetups", "xmlsave", "xmlsetentity", "xmlsetfunction", "xmlsetinjectors", "xmlsetsetup", "xmlsetup", "xmlshow", "xmlsnippet", "xmlstrip", "xmlstripnolines", "xmlstripped", "xmlstrippednolines", "xmltag", "xmltexentity", "xmltext", "xmltobuffer", "xmltobufferverbose", "xmltofile", "xmlvalue", "xmlverbatim", "xrel", "xrightarrow", "xrightharpoondown", "xrightharpoonup", "xrightleftharpoons", "xrightoverleftarrow", "xsplitstring", "xtriplerel", "xtwoheadleftarrow", "xtwoheadrightarrow", "xxfrac", "xypos", "yacute", "ycircumflex", "ydiaeresis", "ydotbelow", "yen", "ygrave", "yhook", "ymacron", "ytilde", "zacute", "zcaron", "zdotaccent", "zerowidthnobreakspace", "zerowidthspace", "zeta", "zhook", "zstroke", "zwj", "zwnj" },
["cs"]={ "Cisla", "Kap", "MESIC", "Rimskecislice", "SLOVA", "SLOVO", "Slova", "Slovo", "VSEDNIDEN", "Znak", "Znaky", "aktualnicislonadpisu", "aktualnidatum", "barevnalista", "barva", "cernalinka", "cernelinky", "cisla", "cislonadpisu", "cislorovnice", "cislostrany", "datum", "definuj", "definujakcent", "definujbarvu", "definujblok", "definujbloksekce", "definujbuffer", "definujfont", "definujformatodkazu", "definujhbox", "definujinterakcnimenu", "definujkombinovanyseznam", "definujkonverzi", "definujnadpis", "definujobrazeksymbol", "definujodkaz", "definujodstavce", "definujopis", "definujoramovani", "definujoramovanytext", "definujpaletu", "definujplvouciobjekt", "definujpodpole", "definujpole", "definujpopis", "definujpopisek", "definujprekryv", "definujprikaz", "definujprofil", "definujprogram", "definujprostredizakladnihofontu", "definujrejstrik", "definujsablonutabulky", "definujsekci", "definujseznam", "definujskupinubarev", "definujstartstop", "definujstyl", "definujstylfontu", "definujsymbol", "definujsynonumumfontu", "definujsynonyma", "definujtabelaci", "definujtext", "definujtrideni", "definujupravu", "definujvelikostpapiru", "definujvycet", "definujzakladnifont", "definujzasobnikpoli", "definujznaceni", "definujznak", "delkaseznamu", "externiobraz", "hlavnijazyk", "hodnotabarvy", "instalacejazyka", "interakcnilista", "interakcnitlacitka", "interaktivnimenu", "jazyk", "jdidolu", "jdina", "jdinabox", "jdinastranu", "klonujpole", "komponenta", "konvertujcislo", "kopirujpole", "korekcebilehomista", "matematika", "meritko", "mesic", "mezera", "mrizka", "nastavbarvu", "nastavbarvy", "nastavbilamista", "nastavblok", "nastavbloksekce", "nastavbuffer", "nastavcernelinky", "nastavcislonadpisu", "nastavcislostrany", "nastavcislovaniodstavcu", "nastavcislovaniradku", "nastavcislovanistran", "nastavcitaci", "nastavdeleniplvoucichobjektu", "nastavdelitko", "nastavdolnitexty", "nastavhorejsek", "nastavhornitexty", "nastavinterakci", "nastavinterakcnilistu", "nastavinterakcnimenu", "nastavinterakcniobrazovku", "nastavjazyk", "nastavkapitalky", "nastavkombinovanyseznam", "nastavkomentar", "nastavkomentarstrany", "nastavmarginalnilinky", "nastavmeziradkovoumezeru", "nastavnadpis", "nastavnadpisy", "nastavodkazovani", "nastavodsazovani", "nastavodstavce", "nastavopis", "nastavoramovanetexty", "nastavoramovani", "nastavorez", "nastavotoceni", "nastavpaletu", "nastavplvouciobjekt", "nastavplvouciobjekty", "nastavpodcislostrany", "nastavpole", "nastavpolozky", "nastavpopisek", "nastavpopisky", "nastavpozadi", "nastavprechodstrany", "nastavpreskok", "nastavprogramy", "nastavradkovani", "nastavradky", "nastavrejstrik", "nastavrovnice", "nastavsadusymbolu", "nastavseznam", "nastavsirkucary", "nastavsloupce", "nastavspodek", "nastavsynonyma", "nastavtabelaci", "nastavtabulky", "nastavtenkelinky", "nastavtext", "nastavtextovelinky", "nastavtexttexty", "nastavtextyupati", "nastavtextyzahlavi", "nastavtoleranci", "nastavtrideni", "nastavtype", "nastavumisteniprotejsku", "nastavumistovani", "nastavupati", "nastavupravu", "nastavurl", "nastavusporadani", "nastavvelikostpapiru", "nastavvsechnapole", "nastavvycty", "nastavvyplnovelinky", "nastavvyplnoveradky", "nastavvzhled", "nastavzahlavi", "nastavzakladnifont", "nastavzarovnani", "nastavznaceni", "nastavzuzeni", "nastrane", "nejakyradek", "nekde", "neznamo", "nivy", "nizky", "nokap", "obrazovka", "odkaz", "odkaznastranu", "odkaznatext", "odkazujici", "opis", "opissoubor", "oramovani", "oref", "orez", "otocit", "oznaceni", "pis", "plnezneni", "pole", "polozka", "polozky", "porovnejpaletu", "porovnejskupinubarev", "pozadi", "pozice", "poznamka", "pref", "prelozit", "prepninazakladnifont", "preskoc", "prizpusobivepole", "prizpusobvzhled", "produkt", "projekt", "prostredi", "resetznaceni", "rimskecislice", "rozdelplvouciobjekt", "roztazene", "schovejbloky", "sedabarva", "sloupec", "slovovpravo", "stanovcharakteristickuseznamu", "stanovcislonadpisu", "startbarva", "startinteraktivnimenu", "startjdina", "startkomponenta", "startmarginalnilinka", "startnadpis", "startoramovani", "startpolozka", "startpozadi", "startprodukt", "startprojekt", "startprostredi", "startpublikace", "startradek", "starttextovalinka", "startumistirovnici", "startzarovnanonastred", "startzarovnanovlevo", "startzarovnanovpravo", "startzhustene", "stopbarva", "stopinteraktivnimenu", "stopjdina", "stopkomponenta", "stopmarginalnilinka", "stopnadpis", "stoporamovani", "stoppolozka", "stoppozadi", "stopprodukt", "stopprojekt", "stopprostredi", "stoppublikace", "stopradek", "stoptextovalinka", "stopumistirovnici", "stopzarovnanonastred", "stopzarovnanovlevo", "stopzarovnanovpravo", "stopzhustene", "strana", "tecky", "tenkalinka", "tenkelinky", "textovalinka", "tlacitko", "tlacitkomenu", "tloustkacary", "tref", "tvrdamezera", "tvrdemezery", "ukazbarvu", "ukazmrizku", "ukaznastaveni", "ukazpaletu", "ukazpodpery", "ukazpostredizakladnihofontu", "ukazramecek", "ukazsadusymbolu", "ukazskupinubarev", "ukazupravu", "ukazvytisk", "ukazvzhled", "ukazzakladnifont", "umistikombinovanyseznam", "umistilokalnipoznamkypodcarou", "umistinadsebe", "umistinamrizku", "umistipodrovnici", "umistipoznamkypodcarou", "umistirejstrik", "umistirovnici", "umistiseznam", "umistivedlesebe", "umistizalozky", "urcicharakteristikurejstriku", "uzijJSscripts", "uzijURL", "uzijadresar", "uzijbloky", "uzijexternidokument", "uzijexterniobraz", "uzijexternizvuk", "uzijmodul", "uzijsymbol", "uzijurl", "verze", "vlasovalinka", "vradku", "vsedniden", "vyberbloky", "vyplnenytext", "vyplnovelinky", "vyplnovyradek", "vysoky", "zachovejbloky", "zadnamezera", "zadnehorniadolniradky", "zadnezahlaviaupati", "zalozka", "zapisdoseznamu", "zapismeziseznam", "zaramovani", "zarovnanonastred", "zarovnanovlevo", "zarovnanovpravo", "zasobnikpoli", "ziskejbuffer", "ziskejznaceni", "znaceni", "znak", "znaky", "zpracujbloky", "zrcadlit", "zref" },
["de"]={ "Buchstabe", "Buchstaben", "Kap", "MONAT", "Roemischezahlen", "WOCHENTAG", "WOERTER", "WORT", "Woerter", "Wort", "Ziffern", "amgitterausrichten", "aufseite", "ausfuelltext", "ausschnitt", "bearbeitebloecke", "behaltebloecke", "bei", "bemerkung", "benutzeverzeichnis", "beschriftung", "bestimmekopfnummer", "bestimmelistencharakeristika", "bestimmeregistercharakteristika", "bildschirm", "blanko", "buchstabe", "buchstaben", "datum", "defineschriftsynonym", "definiereabbsymbol", "definiereabsaetze", "definiereabschnitt", "definiereabschnittsblock", "definiereakzent", "definierebefehl", "definierebeschreibung", "definierebeschriftung", "definiereblock", "definierefarbe", "definierefarbengruppe", "definierefeld", "definierefeldstapel", "definierefliesstext", "definierefliesstextumgebung", "definieregleitobjekt", "definierehbox", "definiereinteraktionsmenue", "definierekonversion", "definierelabel", "definiereliste", "definieren", "definierenummerierung", "definiereoverlay", "definierepalette", "definierepapierformat", "definiereprofil", "definiereprogramme", "definierepuffer", "definierereferenz", "definierereferenzformat", "definiereregister", "definiereschrift", "definiereschriftstil", "definieresortieren", "definierestartstop", "definierestil", "definieresubfeld", "definieresymbol", "definieresynonyme", "definieretabellenvorlage", "definieretabulator", "definieretext", "definieretippen", "definiereueberschrift", "definiereumbruch", "definiereumrahmt", "definiereumrahmtertext", "definierezeichen", "definierezusammengestellteliste", "drehen", "duennelinie", "duennerumriss", "einezeile", "externeabbildung", "farbbalken", "farbe", "farbewert", "feld", "feldstapel", "festesspatium", "format", "formelnummer", "gefuelltesrechteck", "gefuelltezeile", "gestreckt", "gitter", "graufarbe", "haarlinie", "hauptsprache", "heutigesdatum", "heutigeskopfnummer", "hintergrund", "hoch", "holebeschriftung", "holepuffer", "imumriss", "installieresprache", "interaktionsbalken", "interaktionsknopfe", "interaktionsmenue", "inzeile", "irgendwo", "keinekopfundfusszeilen", "keinspatium", "keinzeilenobenundunten", "klonierefeld", "knopf", "komponente", "konvertierezahl", "kopfnummer", "kopierefeld", "korrigierezwischenraum", "liniendicke", "linksbuendig", "listenlaenge", "mathematik", "menueknopf", "monat", "nachunten", "nokap", "notiz", "passelayoutan", "passendfeld", "platzierebookmarks", "platziereformel", "platzierefussnoten", "platziereliste", "platzierelokalefussnoten", "platzierenebeneinander", "platziereregister", "platziereuntereinander", "platziereunterformel", "platzierezusammengestellteliste", "pos", "posten", "produkt", "programm", "projekt", "punkt", "rechteck", "rechtecke", "rechtsbuendig", "referenz", "referieren", "roemischezahlen", "ruecksetztenbeschriftung", "schreibezurliste", "schreibezwischenliste", "seite", "seitenreferenz", "seitenummer", "settext", "spalte", "spatium", "spiegeln", "sprache", "startfarbe", "starthintergrund", "startinteraktionsmenue", "startkleinerdurchschuss", "startkomponente", "startkopf", "startlinksbuendig", "startmarginallinie", "startplatziereformel", "startpos", "startprodukt", "startprojekt", "startpublikation", "startrechtsbuendig", "starttextlinie", "startumgebung", "startumrahmt", "startzeile", "startzentriert", "startzu", "stelleabsaetzeein", "stelleabsatznummerierungein", "stelleabschnittsblockein", "stelleanordnenein", "stelleaufzaehlungenein", "stelleausrichtungein", "stelleausschnittein", "stellebeschreibungein", "stellebeschriftungein", "stellebilderunterschriftein", "stellebildunterschriftein", "stellebindestrichein", "stelleblankoein", "stelleblockein", "stelledrehenein", "stelleduennerumrissein", "stelleeinziehenein", "stelleengerein", "stellefarbeein", "stellefarbenein", "stellefeldein", "stellefelderin", "stellefliesstextein", "stelleformelnein", "stellefusszeileein", "stellefusszeilentextein", "stellegefuelltesrechteckein", "stellegefuelltezeileein", "stellegegenueberplatzierenein", "stellegleitobjekteein", "stellegleitobjektein", "stellehintergruendeein", "stellehintergrundein", "stelleinteraktionein", "stelleinteraktionsbalkenein", "stelleinteraktionsbildschirmein", "stelleinteraktionsmenueein", "stellekommentarein", "stellekopfzahlein", "stellekopfzeileein", "stellekopfzeilentextein", "stellelayoutein", "stellelinienbreiteein", "stellelisteein", "stellemarginallinieein", "stellenobenein", "stellepaletteein", "stellepapierformatein", "stelleplatziegeteiltegleitobjekt", "stellepositionierenein", "stellepostenein", "stelleprogrammein", "stellepufferein", "stellerechteckein", "stellereferenzierenein", "stelleregisterein", "stelleseitenkommentarein", "stelleseitennummerein", "stelleseitennummeriernungein", "stelleseitenuebergangein", "stellesortierenein", "stellespaltenein", "stellespatiumein", "stellespracheein", "stellesymbolsetein", "stellesynonymein", "stelletabellenein", "stelletabulatorein", "stelletextein", "stelletextobenein", "stelletexttexteein", "stelletextumrissein", "stelletextuntenein", "stelletipein", "stelletippenein", "stelletoleranzein", "stelleueberschriftein", "stelleueberschriftenein", "stelleumbruchein", "stelleumrahmtein", "stelleumrahmtetexteein", "stelleuntenein", "stelleunterseitennummerein", "stelleurlein", "stelleversalienein", "stellezeilenabstandein", "stellezeilenein", "stellezeilennumerierungein", "stellezitierenein", "stellezusammengestelltelisteein", "stellezwischenraumein", "stopfarbe", "stophintergrund", "stopinteraktionsmenue", "stopkleinerdurchschuss", "stopkomponente", "stopkopf", "stoplinksbuendig", "stopmarginallinie", "stopplatziereformel", "stoppos", "stopprodukt", "stopprojekt", "stoppublikation", "stoprechtsbuendig", "stoptextlinie", "stopumgebung", "stopumrahmt", "stopzeile", "stopzentriert", "stopzu", "teilegleitobjekt", "textlinie", "textreferenz", "tief", "tiho", "tip", "tippedatei", "tippen", "tippepuffer", "ueber", "uebersetzten", "umgebung", "umrahmt", "unbekant", "verbergebloecke", "vergleichefarbengruppe", "vergleichepalette", "verwendeJSscript", "verwendeURL", "verwendebloecke", "verwendeexteresdokument", "verwendeexterneabbildung", "verwendeexternestonstueck", "verwendemodul", "verwendesymbole", "verwendeurl", "volleswort", "von", "waehlebloeckeaus", "wechselezumfliesstext", "wochentag", "wortrechts", "zeigedruck", "zeigeeinstellungen", "zeigefarbe", "zeigefarbengruppe", "zeigefliesstext", "zeigefliesstextumgebung", "zeigegitter", "zeigelayout", "zeigepalette", "zeigerahmen", "zeigestruts", "zeigeumbruch", "zentriert", "ziffern", "zu", "zurbox", "zurseite" },
["en"]={},
diff --git a/context/data/scite/context/scite-context-data-context.properties b/context/data/scite/context/scite-context-data-context.properties
index bfe2cf344..9cb2b51e7 100644
--- a/context/data/scite/context/scite-context-data-context.properties
+++ b/context/data/scite/context/scite-context-data-context.properties
@@ -123,101 +123,102 @@ scratchmx scratchmy scratchunicode scratchmin scratchmax \
scratchleftskip scratchrightskip scratchtopskip scratchbottomskip doif \
doifnot doifelse doifinset doifnotinset doifelseinset \
doifinsetelse doifelsenextchar doifnextcharelse doifelsenextoptional doifnextoptionalelse \
-doifelsenextoptionalcs doifnextoptionalcselse doifelsefastoptionalcheck doiffastoptionalcheckelse doifelsenextbgroup \
-doifnextbgroupelse doifelsenextbgroupcs doifnextbgroupcselse doifelsenextparenthesis doifnextparenthesiselse \
-doifelseundefined doifundefinedelse doifelsedefined doifdefinedelse doifundefined \
-doifdefined doifelsevalue doifvalue doifnotvalue doifnothing \
-doifsomething doifelsenothing doifnothingelse doifelsesomething doifsomethingelse \
-doifvaluenothing doifvaluesomething doifelsevaluenothing doifvaluenothingelse doifelsedimension \
-doifdimensionelse doifelsenumber doifnumberelse doifnumber doifnotnumber \
-doifelsecommon doifcommonelse doifcommon doifnotcommon doifinstring \
-doifnotinstring doifelseinstring doifinstringelse doifelseassignment doifassignmentelse \
-docheckassignment doiftext doifelsetext doiftextelse doifnottext \
-tracingall tracingnone loggingall removetoks appendtoks \
-prependtoks appendtotoks prependtotoks to endgraf \
-endpar everyendpar reseteverypar finishpar empty \
-null space quad enspace emspace \
-charspace nbsp crlf obeyspaces obeylines \
-obeyedspace obeyedline obeyedtab obeyedpage normalspace \
-executeifdefined singleexpandafter doubleexpandafter tripleexpandafter dontleavehmode \
-removelastspace removeunwantedspaces keepunwantedspaces removepunctuation wait \
-writestatus define defineexpandable redefine setmeasure \
-setemeasure setgmeasure setxmeasure definemeasure freezemeasure \
-measure measured installcorenamespace getvalue getuvalue \
-setvalue setevalue setgvalue setxvalue letvalue \
-letgvalue resetvalue undefinevalue ignorevalue setuvalue \
-setuevalue setugvalue setuxvalue globallet glet \
-udef ugdef uedef uxdef checked \
-unique getparameters geteparameters getgparameters getxparameters \
-forgetparameters copyparameters getdummyparameters dummyparameter directdummyparameter \
-setdummyparameter letdummyparameter usedummystyleandcolor usedummystyleparameter usedummycolorparameter \
-processcommalist processcommacommand quitcommalist quitprevcommalist processaction \
-processallactions processfirstactioninset processallactionsinset unexpanded expanded \
-startexpanded stopexpanded protected protect unprotect \
-firstofoneargument firstoftwoarguments secondoftwoarguments firstofthreearguments secondofthreearguments \
-thirdofthreearguments firstoffourarguments secondoffourarguments thirdoffourarguments fourthoffourarguments \
-firstoffivearguments secondoffivearguments thirdoffivearguments fourthoffivearguments fifthoffivearguments \
-firstofsixarguments secondofsixarguments thirdofsixarguments fourthofsixarguments fifthofsixarguments \
-sixthofsixarguments firstofoneunexpanded firstoftwounexpanded secondoftwounexpanded firstofthreeunexpanded \
-secondofthreeunexpanded thirdofthreeunexpanded gobbleoneargument gobbletwoarguments gobblethreearguments \
-gobblefourarguments gobblefivearguments gobblesixarguments gobblesevenarguments gobbleeightarguments \
-gobbleninearguments gobbletenarguments gobbleoneoptional gobbletwooptionals gobblethreeoptionals \
-gobblefouroptionals gobblefiveoptionals dorecurse doloop exitloop \
-dostepwiserecurse recurselevel recursedepth dofastloopcs fastloopindex \
-fastloopfinal dowith newconstant setnewconstant setconstant \
-setconstantvalue newconditional settrue setfalse settruevalue \
-setfalsevalue newmacro setnewmacro newfraction newsignal \
-dosingleempty dodoubleempty dotripleempty doquadrupleempty doquintupleempty \
-dosixtupleempty doseventupleempty dosingleargument dodoubleargument dotripleargument \
-doquadrupleargument doquintupleargument dosixtupleargument doseventupleargument dosinglegroupempty \
-dodoublegroupempty dotriplegroupempty doquadruplegroupempty doquintuplegroupempty permitspacesbetweengroups \
-dontpermitspacesbetweengroups nopdfcompression maximumpdfcompression normalpdfcompression modulonumber \
-dividenumber getfirstcharacter doifelsefirstchar doiffirstcharelse startnointerference \
-stopnointerference twodigits threedigits leftorright offinterlineskip \
-oninterlineskip nointerlineskip strut halfstrut quarterstrut \
-depthstrut halflinestrut noheightstrut setstrut strutbox \
-strutht strutdp strutwd struthtdp begstrut \
-endstrut lineheight leftboundary rightboundary signalcharacter \
-ordordspacing ordopspacing ordbinspacing ordrelspacing ordopenspacing \
-ordclosespacing ordpunctspacing ordinnerspacing opordspacing opopspacing \
-opbinspacing oprelspacing opopenspacing opclosespacing oppunctspacing \
-opinnerspacing binordspacing binopspacing binbinspacing binrelspacing \
-binopenspacing binclosespacing binpunctspacing bininnerspacing relordspacing \
-relopspacing relbinspacing relrelspacing relopenspacing relclosespacing \
-relpunctspacing relinnerspacing openordspacing openopspacing openbinspacing \
-openrelspacing openopenspacing openclosespacing openpunctspacing openinnerspacing \
-closeordspacing closeopspacing closebinspacing closerelspacing closeopenspacing \
-closeclosespacing closepunctspacing closeinnerspacing punctordspacing punctopspacing \
-punctbinspacing punctrelspacing punctopenspacing punctclosespacing punctpunctspacing \
-punctinnerspacing innerordspacing inneropspacing innerbinspacing innerrelspacing \
-inneropenspacing innerclosespacing innerpunctspacing innerinnerspacing normalreqno \
-startimath stopimath normalstartimath normalstopimath startdmath \
-stopdmath normalstartdmath normalstopdmath normalsuperscript normalsubscript \
-normalnosuperscript normalnosubscript superscript subscript nosuperscript \
-nosubscript uncramped cramped triggermathstyle mathstylefont \
-mathsmallstylefont mathstyleface mathsmallstyleface mathstylecommand mathpalette \
-mathstylehbox mathstylevbox mathstylevcenter mathstylevcenteredhbox mathstylevcenteredvbox \
-mathtext setmathsmalltextbox setmathtextbox pushmathstyle popmathstyle \
-triggerdisplaystyle triggertextstyle triggerscriptstyle triggerscriptscriptstyle triggeruncrampedstyle \
-triggercrampedstyle triggersmallstyle triggeruncrampedsmallstyle triggercrampedsmallstyle triggerbigstyle \
-triggeruncrampedbigstyle triggercrampedbigstyle luaexpr expelsedoif expdoif \
-expdoifnot expdoifelsecommon expdoifcommonelse expdoifelseinset expdoifinsetelse \
-ctxdirectlua ctxlatelua ctxsprint ctxwrite ctxcommand \
-ctxdirectcommand ctxlatecommand ctxreport ctxlua luacode \
-lateluacode directluacode registerctxluafile ctxloadluafile luaversion \
-luamajorversion luaminorversion ctxluacode luaconditional luaexpanded \
-startluaparameterset stopluaparameterset luaparameterset definenamedlua obeylualines \
-obeyluatokens startluacode stopluacode startlua stoplua \
-startctxfunction stopctxfunction ctxfunction startctxfunctiondefinition stopctxfunctiondefinition \
-installctxfunction cldprocessfile cldloadfile cldcontext cldcommand \
-carryoverpar lastlinewidth assumelongusagecs Umathbotaccent righttolefthbox \
-lefttorighthbox righttoleftvbox lefttorightvbox righttoleftvtop lefttorightvtop \
-rtlhbox ltrhbox rtlvbox ltrvbox rtlvtop \
-ltrvtop autodirhbox autodirvbox autodirvtop leftorrighthbox \
-leftorrightvbox leftorrightvtop lefttoright righttoleft synchronizelayoutdirection \
-synchronizedisplaydirection synchronizeinlinedirection lesshyphens morehyphens nohyphens \
-dohyphens Ucheckedstartdisplaymath Ucheckedstopdisplaymath break nobreak \
-allowbreak goodbreak nospace nospacing dospacing \
-naturalhbox naturalvbox naturalhpack naturalvpack frule \
-compoundhyphenpenalty start stop
+doifelsenextoptionalcs doifnextoptionalcselse doifelsefastoptionalcheck doiffastoptionalcheckelse doifelsefastoptionalcheckcs \
+doiffastoptionalcheckcselse doifelsenextbgroup doifnextbgroupelse doifelsenextbgroupcs doifnextbgroupcselse \
+doifelsenextparenthesis doifnextparenthesiselse doifelseundefined doifundefinedelse doifelsedefined \
+doifdefinedelse doifundefined doifdefined doifelsevalue doifvalue \
+doifnotvalue doifnothing doifsomething doifelsenothing doifnothingelse \
+doifelsesomething doifsomethingelse doifvaluenothing doifvaluesomething doifelsevaluenothing \
+doifvaluenothingelse doifelsedimension doifdimensionelse doifelsenumber doifnumberelse \
+doifnumber doifnotnumber doifelsecommon doifcommonelse doifcommon \
+doifnotcommon doifinstring doifnotinstring doifelseinstring doifinstringelse \
+doifelseassignment doifassignmentelse docheckassignment doiftext doifelsetext \
+doiftextelse doifnottext tracingall tracingnone loggingall \
+removetoks appendtoks prependtoks appendtotoks prependtotoks \
+to endgraf endpar everyendpar reseteverypar \
+finishpar empty null space quad \
+enspace emspace charspace nbsp crlf \
+obeyspaces obeylines obeyedspace obeyedline obeyedtab \
+obeyedpage normalspace executeifdefined singleexpandafter doubleexpandafter \
+tripleexpandafter dontleavehmode removelastspace removeunwantedspaces keepunwantedspaces \
+removepunctuation wait writestatus define defineexpandable \
+redefine setmeasure setemeasure setgmeasure setxmeasure \
+definemeasure freezemeasure measure measured installcorenamespace \
+getvalue getuvalue setvalue setevalue setgvalue \
+setxvalue letvalue letgvalue resetvalue undefinevalue \
+ignorevalue setuvalue setuevalue setugvalue setuxvalue \
+globallet glet udef ugdef uedef \
+uxdef checked unique getparameters geteparameters \
+getgparameters getxparameters forgetparameters copyparameters getdummyparameters \
+dummyparameter directdummyparameter setdummyparameter letdummyparameter usedummystyleandcolor \
+usedummystyleparameter usedummycolorparameter processcommalist processcommacommand quitcommalist \
+quitprevcommalist processaction processallactions processfirstactioninset processallactionsinset \
+unexpanded expanded startexpanded stopexpanded protected \
+protect unprotect firstofoneargument firstoftwoarguments secondoftwoarguments \
+firstofthreearguments secondofthreearguments thirdofthreearguments firstoffourarguments secondoffourarguments \
+thirdoffourarguments fourthoffourarguments firstoffivearguments secondoffivearguments thirdoffivearguments \
+fourthoffivearguments fifthoffivearguments firstofsixarguments secondofsixarguments thirdofsixarguments \
+fourthofsixarguments fifthofsixarguments sixthofsixarguments firstofoneunexpanded firstoftwounexpanded \
+secondoftwounexpanded firstofthreeunexpanded secondofthreeunexpanded thirdofthreeunexpanded gobbleoneargument \
+gobbletwoarguments gobblethreearguments gobblefourarguments gobblefivearguments gobblesixarguments \
+gobblesevenarguments gobbleeightarguments gobbleninearguments gobbletenarguments gobbleoneoptional \
+gobbletwooptionals gobblethreeoptionals gobblefouroptionals gobblefiveoptionals dorecurse \
+doloop exitloop dostepwiserecurse recurselevel recursedepth \
+dofastloopcs fastloopindex fastloopfinal dowith newconstant \
+setnewconstant setconstant setconstantvalue newconditional settrue \
+setfalse settruevalue setfalsevalue newmacro setnewmacro \
+newfraction newsignal dosingleempty dodoubleempty dotripleempty \
+doquadrupleempty doquintupleempty dosixtupleempty doseventupleempty dosingleargument \
+dodoubleargument dotripleargument doquadrupleargument doquintupleargument dosixtupleargument \
+doseventupleargument dosinglegroupempty dodoublegroupempty dotriplegroupempty doquadruplegroupempty \
+doquintuplegroupempty permitspacesbetweengroups dontpermitspacesbetweengroups nopdfcompression maximumpdfcompression \
+normalpdfcompression modulonumber dividenumber getfirstcharacter doifelsefirstchar \
+doiffirstcharelse startnointerference stopnointerference twodigits threedigits \
+leftorright offinterlineskip oninterlineskip nointerlineskip strut \
+halfstrut quarterstrut depthstrut halflinestrut noheightstrut \
+setstrut strutbox strutht strutdp strutwd \
+struthtdp strutgap begstrut endstrut lineheight \
+leftboundary rightboundary signalcharacter ordordspacing ordopspacing \
+ordbinspacing ordrelspacing ordopenspacing ordclosespacing ordpunctspacing \
+ordinnerspacing opordspacing opopspacing opbinspacing oprelspacing \
+opopenspacing opclosespacing oppunctspacing opinnerspacing binordspacing \
+binopspacing binbinspacing binrelspacing binopenspacing binclosespacing \
+binpunctspacing bininnerspacing relordspacing relopspacing relbinspacing \
+relrelspacing relopenspacing relclosespacing relpunctspacing relinnerspacing \
+openordspacing openopspacing openbinspacing openrelspacing openopenspacing \
+openclosespacing openpunctspacing openinnerspacing closeordspacing closeopspacing \
+closebinspacing closerelspacing closeopenspacing closeclosespacing closepunctspacing \
+closeinnerspacing punctordspacing punctopspacing punctbinspacing punctrelspacing \
+punctopenspacing punctclosespacing punctpunctspacing punctinnerspacing innerordspacing \
+inneropspacing innerbinspacing innerrelspacing inneropenspacing innerclosespacing \
+innerpunctspacing innerinnerspacing normalreqno startimath stopimath \
+normalstartimath normalstopimath startdmath stopdmath normalstartdmath \
+normalstopdmath normalsuperscript normalsubscript normalnosuperscript normalnosubscript \
+superscript subscript nosuperscript nosubscript uncramped \
+cramped triggermathstyle mathstylefont mathsmallstylefont mathstyleface \
+mathsmallstyleface mathstylecommand mathpalette mathstylehbox mathstylevbox \
+mathstylevcenter mathstylevcenteredhbox mathstylevcenteredvbox mathtext setmathsmalltextbox \
+setmathtextbox pushmathstyle popmathstyle triggerdisplaystyle triggertextstyle \
+triggerscriptstyle triggerscriptscriptstyle triggeruncrampedstyle triggercrampedstyle triggersmallstyle \
+triggeruncrampedsmallstyle triggercrampedsmallstyle triggerbigstyle triggeruncrampedbigstyle triggercrampedbigstyle \
+luaexpr expelsedoif expdoif expdoifnot expdoifelsecommon \
+expdoifcommonelse expdoifelseinset expdoifinsetelse ctxdirectlua ctxlatelua \
+ctxsprint ctxwrite ctxcommand ctxdirectcommand ctxlatecommand \
+ctxreport ctxlua luacode lateluacode directluacode \
+registerctxluafile ctxloadluafile luaversion luamajorversion luaminorversion \
+ctxluacode luaconditional luaexpanded startluaparameterset stopluaparameterset \
+luaparameterset definenamedlua obeylualines obeyluatokens startluacode \
+stopluacode startlua stoplua startctxfunction stopctxfunction \
+ctxfunction startctxfunctiondefinition stopctxfunctiondefinition installctxfunction cldprocessfile \
+cldloadfile cldcontext cldcommand carryoverpar lastlinewidth \
+assumelongusagecs Umathbotaccent righttolefthbox lefttorighthbox righttoleftvbox \
+lefttorightvbox righttoleftvtop lefttorightvtop rtlhbox ltrhbox \
+rtlvbox ltrvbox rtlvtop ltrvtop autodirhbox \
+autodirvbox autodirvtop leftorrighthbox leftorrightvbox leftorrightvtop \
+lefttoright righttoleft synchronizelayoutdirection synchronizedisplaydirection synchronizeinlinedirection \
+lesshyphens morehyphens nohyphens dohyphens Ucheckedstartdisplaymath \
+Ucheckedstopdisplaymath break nobreak allowbreak goodbreak \
+nospace nospacing dospacing naturalhbox naturalvbox \
+naturalhpack naturalvpack frule compoundhyphenpenalty start \
+stop
diff --git a/context/data/scite/context/scite-context-data-interfaces.properties b/context/data/scite/context/scite-context-data-interfaces.properties
index 44d0d0ce7..ac391baa6 100644
--- a/context/data/scite/context/scite-context-data-interfaces.properties
+++ b/context/data/scite/context/scite-context-data-interfaces.properties
@@ -1066,134 +1066,134 @@ stopxmlinlineverbatim stopxmlraw stopxmlsetups stopxrow stopxrowgroup \
stopxtable stopxtablebody stopxtablefoot stopxtablehead stopxtablenext \
stretched strictdoifelsenextoptional strictdoifnextoptionalelse stripcharacter strippedcsname \
stripspaces structurelistuservariable structurenumber structuretitle structureuservariable \
-structurevariable strut strutdp strutht struthtdp \
-struttedbox strutwd style styleinstance subject \
-subpagenumber subsection subsentence subset subseteq \
-subseteqq subsetneq subsetneqq substituteincommalist subsubject \
-subsubsection subsubsubject subsubsubsection subsubsubsubject subsubsubsubsection \
-subsubsubsubsubject subtractfeature succ succapprox succcurlyeq \
-succeq succeqq succnapprox succneq succneqq \
-succnsim succsim suffixlanguage suffixtext sum \
-supset supseteq supseteqq supsetneq supsetneqq \
-surd surdradical swapcounts swapdimens swapface \
-swapmacros swaptypeface swarrow switchstyleonly switchtobodyfont \
-switchtocolor switchtointerlinespace symbol symbolreference synchronizeblank \
-synchronizeindenting synchronizemarking synchronizeoutputstreams synchronizestrut synchronizewhitespace \
-synctexblockfilename synctexresetfilename synctexsetfilename systemlog systemlogfirst \
-systemloglast systemsetups tLeftarrow tLeftrightarrow tRightarrow \
-tabulateautoline tabulateautorule tabulateline tabulaterule taggedctxcommand \
-taggedlabeltexts taglabellanguage taglabeltext tau tbinom \
-tbox tcaron tcedilla tcommaaccent tcurl \
-tequal test testandsplitstring testcolumn testfeature \
-testfeatureonce testpage testpageonly testpagesync testtokens \
-tex texdefinition texsetup textAngstrom textacute \
-textampersand textasciicircum textasciitilde textat textbackslash \
-textbar textbottomcomma textbottomdot textbraceleft textbraceright \
-textbreve textbrokenbar textbullet textcaron textcedilla \
-textcelsius textcent textcircledP textcircumflex textcitation \
-textcite textcomma textcontrolspace textcurrency textdag \
-textddag textdegree textdiaeresis textdiv textdollar \
-textdong textdotaccent textellipsis texteuro textflowcollector \
-textfraction textgrave texthash texthorizontalbar texthungarumlaut \
-texthyphen textkelvin textlognot textmacron textmath \
-textmho textminus textmu textmultiply textnumero \
-textogonek textohm textormathchar textounce textpercent \
-textperiod textplus textpm textreference textring \
-textrule textslash textsterling texttilde textunderscore \
-textvisiblespace textyen thai thainumerals thefirstcharacter \
-thenormalizedbodyfontsize therefore theremainingcharacters theta thickspace \
-thinrule thinrules thinspace thirdoffivearguments thirdoffourarguments \
-thirdofsixarguments thirdofthreearguments thirdofthreeunexpanded thook thookleftarrow \
-thookrightarrow thorn threedigitrounding threeeighths threefifths \
-threeperemspace threequarter threesuperior tibetannumerals tightlayer \
-tilde times tinyfont title tlap \
-tleftarrow tleftharpoondown tleftharpoonup tleftrightarrow tleftrightharpoons \
-tmapsto to tochar tolinenote tooltip \
-top topbox topleftbox toplinebox toprightbox \
-topskippedbox tracecatcodetables tracedfontname traceoutputroutines tracepositions \
-trademark translate transparencycomponents transparent trel \
-triangle triangledown triangleleft triangleq triangleright \
-trightarrow trightharpoondown trightharpoonup trightleftharpoons trightoverleftarrow \
-triplebond tripleprime tripleverticalbar truefilename truefontname \
-tstroke ttraggedright ttriplerel ttwoheadleftarrow ttwoheadrightarrow \
-turnediota twodigitrounding twofifths twoheaddownarrow twoheadleftarrow \
-twoheadrightarrow twoheadrightarrowtail twoheaduparrow twosuperior twothirds \
-tx txx typ type typebuffer \
-typedefinedbuffer typeface typefile typeinlinebuffer typescriptone \
-typescriptprefix typescriptthree typescripttwo typesetbuffer typesetfile \
-uacute ubreve ucaron ucircumflex uconvertnumber \
-udiaeresis udiaeresisacute udiaeresiscaron udiaeresisgrave udiaeresismacron \
-udotbelow udots udoublegrave uedcatcodecommand ugrave \
-uhook uhorn uhornacute uhorndotbelow uhorngrave \
-uhornhook uhorntilde uhungarumlaut uinvertedbreve ulcorner \
-umacron undefinevalue undepthed underbar underbars \
-underbrace underbracket underdash underdashes underdot \
-underdots underleftarrow underparent underrandom underrandoms \
-underrightarrow underset understrike understrikes undoassign \
-unexpandeddocumentvariable unframed unhhbox unihex uniqueMPgraphic \
-uniqueMPpagegraphic unit unitlanguage unitshigh unitslow \
-unittext unknown unprotected unregisterhyphenationpattern unspaceafter \
-unspaceargument unspaced unspacestring untexargument untexcommand \
-uogonek upand uparrow updasharrow updownarrow \
-updownarrowbar updownarrows upharpoonleft upharpoonright uplus \
-uppercased uppercasestring upperleftdoubleninequote upperleftdoublesixquote upperleftsingleninequote \
-upperleftsinglesixquote upperrightdoubleninequote upperrightdoublesixquote upperrightsingleninequote upperrightsinglesixquote \
-upsilon upuparrows upwhitearrow urcorner uring \
-url useJSscripts useMPenvironmentbuffer useMPgraphic useMPlibrary \
-useMPrun useMPvariables useURL usealignparameter useblankparameter \
-useblocks usebodyfont usebodyfontparameter usebtxdataset usebtxdefinitions \
-usecitation usecolors usecomponent usedirectory usedummycolorparameter \
-usedummystyleandcolor usedummystyleparameter useenvironment useexternaldocument useexternalfigure \
-useexternalrendering useexternalsoundtrack usefigurebase usefile usegridparameter \
-useindentingparameter useindentnextparameter useinterlinespaceparameter uselanguageparameter useluamodule \
-usemathstyleparameter usemodule useproduct useprofileparameter useproject \
-usereferenceparameter userpagenumber usesetupsparameter usestaticMPfigure usesubpath \
-usesymbols usetexmodule usetypescript usetypescriptfile useurl \
-usezipfile utfchar utflower utfupper utilde \
-utilityregisterlength vDash varTheta varepsilon varkappa \
-varnothing varphi varpi varrho varsigma \
-vartheta vboxreference vdash vdots vec \
-vee veebar veeeq verbatim verbatimstring \
-verbosenumber version vert verticalgrowingbar verticalpositionbar \
-veryraggedcenter veryraggedleft veryraggedright vglue viewerlayer \
-vl vphantom vpos vsmash vsmashbox \
-vsmashed vspace vspacing wcircumflex wdofstring \
-wedge wedgeeq weekday whitearrowupfrombar widehat \
-widetilde widthofstring widthspanningtext withoutpt word \
-wordright words wordtonumber wp wr \
-writebetweenlist writedatatolist writestatus writetolist xLeftarrow \
-xLeftrightarrow xRightarrow xdefconvertedargument xequal xfrac \
-xhookleftarrow xhookrightarrow xi xleftarrow xleftharpoondown \
-xleftharpoonup xleftrightarrow xleftrightharpoons xmapsto xmladdindex \
-xmlafterdocumentsetup xmlaftersetup xmlall xmlappenddocumentsetup xmlappendsetup \
-xmlapplyselectors xmlatt xmlattdef xmlattribute xmlattributedef \
-xmlbadinclusions xmlbeforedocumentsetup xmlbeforesetup xmlchainatt xmlchainattdef \
-xmlchecknamespace xmlcommand xmlconcat xmlconcatrange xmlcontext \
-xmlcount xmldefaulttotext xmldirectives xmldirectivesafter xmldirectivesbefore \
-xmldisplayverbatim xmldoif xmldoifelse xmldoifelseempty xmldoifelseselfempty \
-xmldoifelsetext xmldoifelsevalue xmldoifnot xmldoifnotselfempty xmldoifnottext \
-xmldoifselfempty xmldoiftext xmlelement xmlfilter xmlfirst \
-xmlflush xmlflushcontext xmlflushdocumentsetups xmlflushlinewise xmlflushpure \
-xmlflushspacewise xmlflushtext xmlinclude xmlinclusion xmlinclusions \
-xmlinfo xmlinjector xmlinlineprettyprint xmlinlineprettyprinttext xmlinlineverbatim \
-xmlinstalldirective xmllast xmllastatt xmllastmatch xmlloadbuffer \
-xmlloaddata xmlloaddirectives xmlloadfile xmlloadonly xmlmain \
-xmlmapvalue xmlname xmlnamespace xmlnonspace xmlpath \
-xmlpos xmlposition xmlprependdocumentsetup xmlprependsetup xmlprettyprint \
-xmlprettyprinttext xmlprocessbuffer xmlprocessdata xmlprocessfile xmlpure \
-xmlraw xmlrefatt xmlregistereddocumentsetups xmlregisteredsetups xmlregisterns \
-xmlremapname xmlremapnamespace xmlremovedocumentsetup xmlremovesetup xmlresetdocumentsetups \
-xmlresetinjectors xmlresetsetups xmlsave xmlsetentity xmlsetfunction \
-xmlsetinjectors xmlsetsetup xmlsetup xmlshow xmlsnippet \
-xmlstrip xmlstripnolines xmlstripped xmlstrippednolines xmltag \
-xmltexentity xmltext xmltobuffer xmltobufferverbose xmltofile \
-xmlvalue xmlverbatim xrel xrightarrow xrightharpoondown \
-xrightharpoonup xrightleftharpoons xrightoverleftarrow xsplitstring xtriplerel \
-xtwoheadleftarrow xtwoheadrightarrow xxfrac xypos yacute \
-ycircumflex ydiaeresis ydotbelow yen ygrave \
-yhook ymacron ytilde zacute zcaron \
-zdotaccent zerowidthnobreakspace zerowidthspace zeta zhook \
-zstroke zwj zwnj
+structurevariable strut strutdp strutgap strutht \
+struthtdp struttedbox strutwd style styleinstance \
+subject subpagenumber subsection subsentence subset \
+subseteq subseteqq subsetneq subsetneqq substituteincommalist \
+subsubject subsubsection subsubsubject subsubsubsection subsubsubsubject \
+subsubsubsubsection subsubsubsubsubject subtractfeature succ succapprox \
+succcurlyeq succeq succeqq succnapprox succneq \
+succneqq succnsim succsim suffixlanguage suffixtext \
+sum supset supseteq supseteqq supsetneq \
+supsetneqq surd surdradical swapcounts swapdimens \
+swapface swapmacros swaptypeface swarrow switchstyleonly \
+switchtobodyfont switchtocolor switchtointerlinespace symbol symbolreference \
+synchronizeblank synchronizeindenting synchronizemarking synchronizeoutputstreams synchronizestrut \
+synchronizewhitespace synctexblockfilename synctexresetfilename synctexsetfilename systemlog \
+systemlogfirst systemloglast systemsetups tLeftarrow tLeftrightarrow \
+tRightarrow tabulateautoline tabulateautorule tabulateline tabulaterule \
+taggedctxcommand taggedlabeltexts taglabellanguage taglabeltext tau \
+tbinom tbox tcaron tcedilla tcommaaccent \
+tcurl tequal test testandsplitstring testcolumn \
+testfeature testfeatureonce testpage testpageonly testpagesync \
+testtokens tex texdefinition texsetup textAngstrom \
+textacute textampersand textasciicircum textasciitilde textat \
+textbackslash textbar textbottomcomma textbottomdot textbraceleft \
+textbraceright textbreve textbrokenbar textbullet textcaron \
+textcedilla textcelsius textcent textcircledP textcircumflex \
+textcitation textcite textcomma textcontrolspace textcurrency \
+textdag textddag textdegree textdiaeresis textdiv \
+textdollar textdong textdotaccent textellipsis texteuro \
+textflowcollector textfraction textgrave texthash texthorizontalbar \
+texthungarumlaut texthyphen textkelvin textlognot textmacron \
+textmath textmho textminus textmu textmultiply \
+textnumero textogonek textohm textormathchar textounce \
+textpercent textperiod textplus textpm textreference \
+textring textrule textslash textsterling texttilde \
+textunderscore textvisiblespace textyen thai thainumerals \
+thefirstcharacter thenormalizedbodyfontsize therefore theremainingcharacters theta \
+thickspace thinrule thinrules thinspace thirdoffivearguments \
+thirdoffourarguments thirdofsixarguments thirdofthreearguments thirdofthreeunexpanded thook \
+thookleftarrow thookrightarrow thorn threedigitrounding threeeighths \
+threefifths threeperemspace threequarter threesuperior tibetannumerals \
+tightlayer tilde times tinyfont title \
+tlap tleftarrow tleftharpoondown tleftharpoonup tleftrightarrow \
+tleftrightharpoons tmapsto to tochar tolinenote \
+tooltip top topbox topleftbox toplinebox \
+toprightbox topskippedbox tracecatcodetables tracedfontname traceoutputroutines \
+tracepositions trademark translate transparencycomponents transparent \
+trel triangle triangledown triangleleft triangleq \
+triangleright trightarrow trightharpoondown trightharpoonup trightleftharpoons \
+trightoverleftarrow triplebond tripleprime tripleverticalbar truefilename \
+truefontname tstroke ttraggedright ttriplerel ttwoheadleftarrow \
+ttwoheadrightarrow turnediota twodigitrounding twofifths twoheaddownarrow \
+twoheadleftarrow twoheadrightarrow twoheadrightarrowtail twoheaduparrow twosuperior \
+twothirds tx txx typ type \
+typebuffer typedefinedbuffer typeface typefile typeinlinebuffer \
+typescriptone typescriptprefix typescriptthree typescripttwo typesetbuffer \
+typesetfile uacute ubreve ucaron ucircumflex \
+uconvertnumber udiaeresis udiaeresisacute udiaeresiscaron udiaeresisgrave \
+udiaeresismacron udotbelow udots udoublegrave uedcatcodecommand \
+ugrave uhook uhorn uhornacute uhorndotbelow \
+uhorngrave uhornhook uhorntilde uhungarumlaut uinvertedbreve \
+ulcorner umacron undefinevalue undepthed underbar \
+underbars underbrace underbracket underdash underdashes \
+underdot underdots underleftarrow underparent underrandom \
+underrandoms underrightarrow underset understrike understrikes \
+undoassign unexpandeddocumentvariable unframed unhhbox unihex \
+uniqueMPgraphic uniqueMPpagegraphic unit unitlanguage unitshigh \
+unitslow unittext unknown unprotected unregisterhyphenationpattern \
+unspaceafter unspaceargument unspaced unspacestring untexargument \
+untexcommand uogonek upand uparrow updasharrow \
+updownarrow updownarrowbar updownarrows upharpoonleft upharpoonright \
+uplus uppercased uppercasestring upperleftdoubleninequote upperleftdoublesixquote \
+upperleftsingleninequote upperleftsinglesixquote upperrightdoubleninequote upperrightdoublesixquote upperrightsingleninequote \
+upperrightsinglesixquote upsilon upuparrows upwhitearrow urcorner \
+uring url useJSscripts useMPenvironmentbuffer useMPgraphic \
+useMPlibrary useMPrun useMPvariables useURL usealignparameter \
+useblankparameter useblocks usebodyfont usebodyfontparameter usebtxdataset \
+usebtxdefinitions usecitation usecolors usecomponent usedirectory \
+usedummycolorparameter usedummystyleandcolor usedummystyleparameter useenvironment useexternaldocument \
+useexternalfigure useexternalrendering useexternalsoundtrack usefigurebase usefile \
+usegridparameter useindentingparameter useindentnextparameter useinterlinespaceparameter uselanguageparameter \
+useluamodule usemathstyleparameter usemodule useproduct useprofileparameter \
+useproject usereferenceparameter userpagenumber usesetupsparameter usestaticMPfigure \
+usesubpath usesymbols usetexmodule usetypescript usetypescriptfile \
+useurl usezipfile utfchar utflower utfupper \
+utilde utilityregisterlength vDash varTheta varepsilon \
+varkappa varnothing varphi varpi varrho \
+varsigma vartheta vboxreference vdash vdots \
+vec vee veebar veeeq verbatim \
+verbatimstring verbosenumber version vert verticalgrowingbar \
+verticalpositionbar veryraggedcenter veryraggedleft veryraggedright vglue \
+viewerlayer vl vphantom vpos vsmash \
+vsmashbox vsmashed vspace vspacing wcircumflex \
+wdofstring wedge wedgeeq weekday whitearrowupfrombar \
+widehat widetilde widthofstring widthspanningtext withoutpt \
+word wordright words wordtonumber wp \
+wr writebetweenlist writedatatolist writestatus writetolist \
+xLeftarrow xLeftrightarrow xRightarrow xdefconvertedargument xequal \
+xfrac xhookleftarrow xhookrightarrow xi xleftarrow \
+xleftharpoondown xleftharpoonup xleftrightarrow xleftrightharpoons xmapsto \
+xmladdindex xmlafterdocumentsetup xmlaftersetup xmlall xmlappenddocumentsetup \
+xmlappendsetup xmlapplyselectors xmlatt xmlattdef xmlattribute \
+xmlattributedef xmlbadinclusions xmlbeforedocumentsetup xmlbeforesetup xmlchainatt \
+xmlchainattdef xmlchecknamespace xmlcommand xmlconcat xmlconcatrange \
+xmlcontext xmlcount xmldefaulttotext xmldirectives xmldirectivesafter \
+xmldirectivesbefore xmldisplayverbatim xmldoif xmldoifelse xmldoifelseempty \
+xmldoifelseselfempty xmldoifelsetext xmldoifelsevalue xmldoifnot xmldoifnotselfempty \
+xmldoifnottext xmldoifselfempty xmldoiftext xmlelement xmlfilter \
+xmlfirst xmlflush xmlflushcontext xmlflushdocumentsetups xmlflushlinewise \
+xmlflushpure xmlflushspacewise xmlflushtext xmlinclude xmlinclusion \
+xmlinclusions xmlinfo xmlinjector xmlinlineprettyprint xmlinlineprettyprinttext \
+xmlinlineverbatim xmlinstalldirective xmllast xmllastatt xmllastmatch \
+xmlloadbuffer xmlloaddata xmlloaddirectives xmlloadfile xmlloadonly \
+xmlmain xmlmapvalue xmlname xmlnamespace xmlnonspace \
+xmlpath xmlpos xmlposition xmlprependdocumentsetup xmlprependsetup \
+xmlprettyprint xmlprettyprinttext xmlprocessbuffer xmlprocessdata xmlprocessfile \
+xmlpure xmlraw xmlrefatt xmlregistereddocumentsetups xmlregisteredsetups \
+xmlregisterns xmlremapname xmlremapnamespace xmlremovedocumentsetup xmlremovesetup \
+xmlresetdocumentsetups xmlresetinjectors xmlresetsetups xmlsave xmlsetentity \
+xmlsetfunction xmlsetinjectors xmlsetsetup xmlsetup xmlshow \
+xmlsnippet xmlstrip xmlstripnolines xmlstripped xmlstrippednolines \
+xmltag xmltexentity xmltext xmltobuffer xmltobufferverbose \
+xmltofile xmlvalue xmlverbatim xrel xrightarrow \
+xrightharpoondown xrightharpoonup xrightleftharpoons xrightoverleftarrow xsplitstring \
+xtriplerel xtwoheadleftarrow xtwoheadrightarrow xxfrac xypos \
+yacute ycircumflex ydiaeresis ydotbelow yen \
+ygrave yhook ymacron ytilde zacute \
+zcaron zdotaccent zerowidthnobreakspace zerowidthspace zeta \
+zhook zstroke zwj zwnj
keywordclass.context.cs=\
Cisla Kap MESIC Rimskecislice \
diff --git a/context/data/textadept/context/data/scite-context-data-context.lua b/context/data/textadept/context/data/scite-context-data-context.lua
index c58767270..2cba8b9d0 100644
--- a/context/data/textadept/context/data/scite-context-data-context.lua
+++ b/context/data/textadept/context/data/scite-context-data-context.lua
@@ -1,4 +1,4 @@
return {
["constants"]={ "zerocount", "minusone", "minustwo", "plusone", "plustwo", "plusthree", "plusfour", "plusfive", "plussix", "plusseven", "pluseight", "plusnine", "plusten", "plussixteen", "plushundred", "plustwohundred", "plusthousand", "plustenthousand", "plustwentythousand", "medcard", "maxcard", "maxcardminusone", "zeropoint", "onepoint", "halfapoint", "onebasepoint", "maxcount", "maxdimen", "scaledpoint", "thousandpoint", "points", "halfpoint", "zeroskip", "zeromuskip", "onemuskip", "pluscxxvii", "pluscxxviii", "pluscclv", "pluscclvi", "normalpagebox", "endoflinetoken", "outputnewlinechar", "emptytoks", "empty", "undefined", "voidbox", "emptybox", "emptyvbox", "emptyhbox", "bigskipamount", "medskipamount", "smallskipamount", "fmtname", "fmtversion", "texengine", "texenginename", "texengineversion", "texenginefunctionality", "luatexengine", "pdftexengine", "xetexengine", "unknownengine", "activecatcode", "bgroup", "egroup", "endline", "conditionaltrue", "conditionalfalse", "attributeunsetvalue", "uprotationangle", "rightrotationangle", "downrotationangle", "leftrotationangle", "inicatcodes", "ctxcatcodes", "texcatcodes", "notcatcodes", "txtcatcodes", "vrbcatcodes", "prtcatcodes", "nilcatcodes", "luacatcodes", "tpacatcodes", "tpbcatcodes", "xmlcatcodes", "ctdcatcodes", "escapecatcode", "begingroupcatcode", "endgroupcatcode", "mathshiftcatcode", "alignmentcatcode", "endoflinecatcode", "parametercatcode", "superscriptcatcode", "subscriptcatcode", "ignorecatcode", "spacecatcode", "lettercatcode", "othercatcode", "activecatcode", "commentcatcode", "invalidcatcode", "tabasciicode", "newlineasciicode", "formfeedasciicode", "endoflineasciicode", "endoffileasciicode", "spaceasciicode", "hashasciicode", "dollarasciicode", "commentasciicode", "ampersandasciicode", "colonasciicode", "backslashasciicode", "circumflexasciicode", "underscoreasciicode", "leftbraceasciicode", "barasciicode", "rightbraceasciicode", "tildeasciicode", "delasciicode", "lessthanasciicode", "morethanasciicode", "doublecommentsignal", "atsignasciicode", "exclamationmarkasciicode", "questionmarkasciicode", "doublequoteasciicode", "singlequoteasciicode", "forwardslashasciicode", "primeasciicode", "hyphenasciicode", "activemathcharcode", "activetabtoken", "activeformfeedtoken", "activeendoflinetoken", "batchmodecode", "nonstopmodecode", "scrollmodecode", "errorstopmodecode", "bottomlevelgroupcode", "simplegroupcode", "hboxgroupcode", "adjustedhboxgroupcode", "vboxgroupcode", "vtopgroupcode", "aligngroupcode", "noaligngroupcode", "outputgroupcode", "mathgroupcode", "discretionarygroupcode", "insertgroupcode", "vcentergroupcode", "mathchoicegroupcode", "semisimplegroupcode", "mathshiftgroupcode", "mathleftgroupcode", "vadjustgroupcode", "charnodecode", "hlistnodecode", "vlistnodecode", "rulenodecode", "insertnodecode", "marknodecode", "adjustnodecode", "ligaturenodecode", "discretionarynodecode", "whatsitnodecode", "mathnodecode", "gluenodecode", "kernnodecode", "penaltynodecode", "unsetnodecode", "mathsnodecode", "charifcode", "catifcode", "numifcode", "dimifcode", "oddifcode", "vmodeifcode", "hmodeifcode", "mmodeifcode", "innerifcode", "voidifcode", "hboxifcode", "vboxifcode", "xifcode", "eofifcode", "trueifcode", "falseifcode", "caseifcode", "definedifcode", "csnameifcode", "fontcharifcode", "fontslantperpoint", "fontinterwordspace", "fontinterwordstretch", "fontinterwordshrink", "fontexheight", "fontemwidth", "fontextraspace", "slantperpoint", "mathexheight", "mathemwidth", "interwordspace", "interwordstretch", "interwordshrink", "exheight", "emwidth", "extraspace", "mathsupdisplay", "mathsupnormal", "mathsupcramped", "mathsubnormal", "mathsubcombined", "mathaxisheight", "muquad", "startmode", "stopmode", "startnotmode", "stopnotmode", "startmodeset", "stopmodeset", "doifmode", "doifelsemode", "doifmodeelse", "doifnotmode", "startmodeset", "stopmodeset", "startallmodes", "stopallmodes", "startnotallmodes", "stopnotallmodes", "doifallmodes", "doifelseallmodes", "doifallmodeselse", "doifnotallmodes", "startenvironment", "stopenvironment", "environment", "startcomponent", "stopcomponent", "component", "startproduct", "stopproduct", "product", "startproject", "stopproject", "project", "starttext", "stoptext", "startnotext", "stopnotext", "startdocument", "stopdocument", "documentvariable", "unexpandeddocumentvariable", "setupdocument", "presetdocument", "startmodule", "stopmodule", "usemodule", "usetexmodule", "useluamodule", "setupmodule", "currentmoduleparameter", "moduleparameter", "everystarttext", "everystoptext", "startTEXpage", "stopTEXpage", "enablemode", "disablemode", "preventmode", "definemode", "globalenablemode", "globaldisablemode", "globalpreventmode", "pushmode", "popmode", "typescriptone", "typescripttwo", "typescriptthree", "mathsizesuffix", "mathordcode", "mathopcode", "mathbincode", "mathrelcode", "mathopencode", "mathclosecode", "mathpunctcode", "mathalphacode", "mathinnercode", "mathnothingcode", "mathlimopcode", "mathnolopcode", "mathboxcode", "mathchoicecode", "mathaccentcode", "mathradicalcode", "constantnumber", "constantnumberargument", "constantdimen", "constantdimenargument", "constantemptyargument", "continueifinputfile", "luastringsep", "!!bs", "!!es", "lefttorightmark", "righttoleftmark", "breakablethinspace", "nobreakspace", "nonbreakablespace", "narrownobreakspace", "zerowidthnobreakspace", "ideographicspace", "ideographichalffillspace", "twoperemspace", "threeperemspace", "fourperemspace", "fiveperemspace", "sixperemspace", "figurespace", "punctuationspace", "hairspace", "zerowidthspace", "zerowidthnonjoiner", "zerowidthjoiner", "zwnj", "zwj", "optionalspace", "asciispacechar", "Ux", "eUx", "Umathaccents", "parfillleftskip", "parfillrightskip" },
- ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", "startcontextdefinitioncode", "stopcontextdefinitioncode", "texdefinition", "doifelsesetups", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "fastsetup", "doifelsecommandhandler", "doifcommandhandlerelse", "doifnotcommandhandler", "doifcommandhandler", "newmode", "setmode", "resetmode", "newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode", "booleanmodevalue", "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif", "newlanguage", "newfamily", "newfam", "newhelp", "then", "begcsname", "strippedcsname", "checkedstrippedcsname", "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", "fifthargumentfalse", "fifthsargumenttrue", "sixthargumentfalse", "sixtsargumenttrue", "doglobal", "dodoglobal", "redoglobal", "resetglobal", "donothing", "dontcomplain", "forgetall", "donetrue", "donefalse", "foundtrue", "foundfalse", "inlineordisplaymath", "indisplaymath", "forcedisplaymath", "startforceddisplaymath", "stopforceddisplaymath", "reqno", "mathortext", "htdp", "unvoidbox", "hfilll", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledmbox", "ruledhpack", "ruledvpack", "ruledtpack", "ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", "scratchcounter", "globalscratchcounter", "privatescratchcounter", "scratchdimen", "globalscratchdimen", "privatescratchdimen", "scratchskip", "globalscratchskip", "privatescratchskip", "scratchmuskip", "globalscratchmuskip", "privatescratchmuskip", "scratchtoks", "globalscratchtoks", "privatescratchtoks", "scratchbox", "globalscratchbox", "privatescratchbox", "normalbaselineskip", "normallineskip", "normallineskiplimit", "availablehsize", "localhsize", "setlocalhsize", "distributedhsize", "hsizefraction", "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "flushnextbox", "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchhsize", "scratchvsize", "scratchxoffset", "scratchyoffset", "scratchhoffset", "scratchvoffset", "scratchxposition", "scratchyposition", "scratchtopoffset", "scratchbottomoffset", "scratchleftoffset", "scratchrightoffset", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchcounterfour", "scratchcounterfive", "scratchcountersix", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchdimenfour", "scratchdimenfive", "scratchdimensix", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchskipfour", "scratchskipfive", "scratchskipsix", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchmuskipfour", "scratchmuskipfive", "scratchmuskipsix", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchtoksfour", "scratchtoksfive", "scratchtokssix", "scratchboxone", "scratchboxtwo", "scratchboxthree", "scratchboxfour", "scratchboxfive", "scratchboxsix", "scratchnx", "scratchny", "scratchmx", "scratchmy", "scratchunicode", "scratchmin", "scratchmax", "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", "doif", "doifnot", "doifelse", "doifinset", "doifnotinset", "doifelseinset", "doifinsetelse", "doifelsenextchar", "doifnextcharelse", "doifelsenextoptional", "doifnextoptionalelse", "doifelsenextoptionalcs", "doifnextoptionalcselse", "doifelsefastoptionalcheck", "doiffastoptionalcheckelse", "doifelsenextbgroup", "doifnextbgroupelse", "doifelsenextbgroupcs", "doifnextbgroupcselse", "doifelsenextparenthesis", "doifnextparenthesiselse", "doifelseundefined", "doifundefinedelse", "doifelsedefined", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifnothingelse", "doifelsesomething", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifvaluenothingelse", "doifelsedimension", "doifdimensionelse", "doifelsenumber", "doifnumberelse", "doifnumber", "doifnotnumber", "doifelsecommon", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifelseinstring", "doifinstringelse", "doifelseassignment", "doifassignmentelse", "docheckassignment", "doiftext", "doifelsetext", "doiftextelse", "doifnottext", "tracingall", "tracingnone", "loggingall", "removetoks", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "endpar", "everyendpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "emspace", "charspace", "nbsp", "crlf", "obeyspaces", "obeylines", "obeyedspace", "obeyedline", "obeyedtab", "obeyedpage", "normalspace", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", "removepunctuation", "wait", "writestatus", "define", "defineexpandable", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", "measured", "installcorenamespace", "getvalue", "getuvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "glet", "udef", "ugdef", "uedef", "uxdef", "checked", "unique", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "getdummyparameters", "dummyparameter", "directdummyparameter", "setdummyparameter", "letdummyparameter", "usedummystyleandcolor", "usedummystyleparameter", "usedummycolorparameter", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protected", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "firstoftwounexpanded", "secondoftwounexpanded", "firstofthreeunexpanded", "secondofthreeunexpanded", "thirdofthreeunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "fastloopindex", "fastloopfinal", "dowith", "newconstant", "setnewconstant", "setconstant", "setconstantvalue", "newconditional", "settrue", "setfalse", "settruevalue", "setfalsevalue", "newmacro", "setnewmacro", "newfraction", "newsignal", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "doquintupleargument", "dosixtupleargument", "doseventupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doifelsefirstchar", "doiffirstcharelse", "startnointerference", "stopnointerference", "twodigits", "threedigits", "leftorright", "offinterlineskip", "oninterlineskip", "nointerlineskip", "strut", "halfstrut", "quarterstrut", "depthstrut", "halflinestrut", "noheightstrut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "begstrut", "endstrut", "lineheight", "leftboundary", "rightboundary", "signalcharacter", "ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing", "ordopenspacing", "ordclosespacing", "ordpunctspacing", "ordinnerspacing", "opordspacing", "opopspacing", "opbinspacing", "oprelspacing", "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing", "binordspacing", "binopspacing", "binbinspacing", "binrelspacing", "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing", "relordspacing", "relopspacing", "relbinspacing", "relrelspacing", "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing", "openordspacing", "openopspacing", "openbinspacing", "openrelspacing", "openopenspacing", "openclosespacing", "openpunctspacing", "openinnerspacing", "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing", "closeopenspacing", "closeclosespacing", "closepunctspacing", "closeinnerspacing", "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing", "punctopenspacing", "punctclosespacing", "punctpunctspacing", "punctinnerspacing", "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing", "inneropenspacing", "innerclosespacing", "innerpunctspacing", "innerinnerspacing", "normalreqno", "startimath", "stopimath", "normalstartimath", "normalstopimath", "startdmath", "stopdmath", "normalstartdmath", "normalstopdmath", "normalsuperscript", "normalsubscript", "normalnosuperscript", "normalnosubscript", "superscript", "subscript", "nosuperscript", "nosubscript", "uncramped", "cramped", "triggermathstyle", "mathstylefont", "mathsmallstylefont", "mathstyleface", "mathsmallstyleface", "mathstylecommand", "mathpalette", "mathstylehbox", "mathstylevbox", "mathstylevcenter", "mathstylevcenteredhbox", "mathstylevcenteredvbox", "mathtext", "setmathsmalltextbox", "setmathtextbox", "pushmathstyle", "popmathstyle", "triggerdisplaystyle", "triggertextstyle", "triggerscriptstyle", "triggerscriptscriptstyle", "triggeruncrampedstyle", "triggercrampedstyle", "triggersmallstyle", "triggeruncrampedsmallstyle", "triggercrampedsmallstyle", "triggerbigstyle", "triggeruncrampedbigstyle", "triggercrampedbigstyle", "luaexpr", "expelsedoif", "expdoif", "expdoifnot", "expdoifelsecommon", "expdoifcommonelse", "expdoifelseinset", "expdoifinsetelse", "ctxdirectlua", "ctxlatelua", "ctxsprint", "ctxwrite", "ctxcommand", "ctxdirectcommand", "ctxlatecommand", "ctxreport", "ctxlua", "luacode", "lateluacode", "directluacode", "registerctxluafile", "ctxloadluafile", "luaversion", "luamajorversion", "luaminorversion", "ctxluacode", "luaconditional", "luaexpanded", "startluaparameterset", "stopluaparameterset", "luaparameterset", "definenamedlua", "obeylualines", "obeyluatokens", "startluacode", "stopluacode", "startlua", "stoplua", "startctxfunction", "stopctxfunction", "ctxfunction", "startctxfunctiondefinition", "stopctxfunctiondefinition", "installctxfunction", "cldprocessfile", "cldloadfile", "cldcontext", "cldcommand", "carryoverpar", "lastlinewidth", "assumelongusagecs", "Umathbotaccent", "righttolefthbox", "lefttorighthbox", "righttoleftvbox", "lefttorightvbox", "righttoleftvtop", "lefttorightvtop", "rtlhbox", "ltrhbox", "rtlvbox", "ltrvbox", "rtlvtop", "ltrvtop", "autodirhbox", "autodirvbox", "autodirvtop", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "lefttoright", "righttoleft", "synchronizelayoutdirection", "synchronizedisplaydirection", "synchronizeinlinedirection", "lesshyphens", "morehyphens", "nohyphens", "dohyphens", "Ucheckedstartdisplaymath", "Ucheckedstopdisplaymath", "break", "nobreak", "allowbreak", "goodbreak", "nospace", "nospacing", "dospacing", "naturalhbox", "naturalvbox", "naturalhpack", "naturalvpack", "frule", "compoundhyphenpenalty", "start", "stop" },
+ ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", "startcontextdefinitioncode", "stopcontextdefinitioncode", "texdefinition", "doifelsesetups", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "fastsetup", "doifelsecommandhandler", "doifcommandhandlerelse", "doifnotcommandhandler", "doifcommandhandler", "newmode", "setmode", "resetmode", "newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode", "booleanmodevalue", "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif", "newlanguage", "newfamily", "newfam", "newhelp", "then", "begcsname", "strippedcsname", "checkedstrippedcsname", "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", "fifthargumentfalse", "fifthsargumenttrue", "sixthargumentfalse", "sixtsargumenttrue", "doglobal", "dodoglobal", "redoglobal", "resetglobal", "donothing", "dontcomplain", "forgetall", "donetrue", "donefalse", "foundtrue", "foundfalse", "inlineordisplaymath", "indisplaymath", "forcedisplaymath", "startforceddisplaymath", "stopforceddisplaymath", "reqno", "mathortext", "htdp", "unvoidbox", "hfilll", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledmbox", "ruledhpack", "ruledvpack", "ruledtpack", "ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", "scratchcounter", "globalscratchcounter", "privatescratchcounter", "scratchdimen", "globalscratchdimen", "privatescratchdimen", "scratchskip", "globalscratchskip", "privatescratchskip", "scratchmuskip", "globalscratchmuskip", "privatescratchmuskip", "scratchtoks", "globalscratchtoks", "privatescratchtoks", "scratchbox", "globalscratchbox", "privatescratchbox", "normalbaselineskip", "normallineskip", "normallineskiplimit", "availablehsize", "localhsize", "setlocalhsize", "distributedhsize", "hsizefraction", "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "flushnextbox", "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchhsize", "scratchvsize", "scratchxoffset", "scratchyoffset", "scratchhoffset", "scratchvoffset", "scratchxposition", "scratchyposition", "scratchtopoffset", "scratchbottomoffset", "scratchleftoffset", "scratchrightoffset", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchcounterfour", "scratchcounterfive", "scratchcountersix", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchdimenfour", "scratchdimenfive", "scratchdimensix", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchskipfour", "scratchskipfive", "scratchskipsix", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchmuskipfour", "scratchmuskipfive", "scratchmuskipsix", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchtoksfour", "scratchtoksfive", "scratchtokssix", "scratchboxone", "scratchboxtwo", "scratchboxthree", "scratchboxfour", "scratchboxfive", "scratchboxsix", "scratchnx", "scratchny", "scratchmx", "scratchmy", "scratchunicode", "scratchmin", "scratchmax", "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", "doif", "doifnot", "doifelse", "doifinset", "doifnotinset", "doifelseinset", "doifinsetelse", "doifelsenextchar", "doifnextcharelse", "doifelsenextoptional", "doifnextoptionalelse", "doifelsenextoptionalcs", "doifnextoptionalcselse", "doifelsefastoptionalcheck", "doiffastoptionalcheckelse", "doifelsefastoptionalcheckcs", "doiffastoptionalcheckcselse", "doifelsenextbgroup", "doifnextbgroupelse", "doifelsenextbgroupcs", "doifnextbgroupcselse", "doifelsenextparenthesis", "doifnextparenthesiselse", "doifelseundefined", "doifundefinedelse", "doifelsedefined", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifnothingelse", "doifelsesomething", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifvaluenothingelse", "doifelsedimension", "doifdimensionelse", "doifelsenumber", "doifnumberelse", "doifnumber", "doifnotnumber", "doifelsecommon", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifelseinstring", "doifinstringelse", "doifelseassignment", "doifassignmentelse", "docheckassignment", "doiftext", "doifelsetext", "doiftextelse", "doifnottext", "tracingall", "tracingnone", "loggingall", "removetoks", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "endpar", "everyendpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "emspace", "charspace", "nbsp", "crlf", "obeyspaces", "obeylines", "obeyedspace", "obeyedline", "obeyedtab", "obeyedpage", "normalspace", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", "removepunctuation", "wait", "writestatus", "define", "defineexpandable", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", "measured", "installcorenamespace", "getvalue", "getuvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "glet", "udef", "ugdef", "uedef", "uxdef", "checked", "unique", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "getdummyparameters", "dummyparameter", "directdummyparameter", "setdummyparameter", "letdummyparameter", "usedummystyleandcolor", "usedummystyleparameter", "usedummycolorparameter", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protected", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "firstoftwounexpanded", "secondoftwounexpanded", "firstofthreeunexpanded", "secondofthreeunexpanded", "thirdofthreeunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "fastloopindex", "fastloopfinal", "dowith", "newconstant", "setnewconstant", "setconstant", "setconstantvalue", "newconditional", "settrue", "setfalse", "settruevalue", "setfalsevalue", "newmacro", "setnewmacro", "newfraction", "newsignal", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "doquintupleargument", "dosixtupleargument", "doseventupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doifelsefirstchar", "doiffirstcharelse", "startnointerference", "stopnointerference", "twodigits", "threedigits", "leftorright", "offinterlineskip", "oninterlineskip", "nointerlineskip", "strut", "halfstrut", "quarterstrut", "depthstrut", "halflinestrut", "noheightstrut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "strutgap", "begstrut", "endstrut", "lineheight", "leftboundary", "rightboundary", "signalcharacter", "ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing", "ordopenspacing", "ordclosespacing", "ordpunctspacing", "ordinnerspacing", "opordspacing", "opopspacing", "opbinspacing", "oprelspacing", "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing", "binordspacing", "binopspacing", "binbinspacing", "binrelspacing", "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing", "relordspacing", "relopspacing", "relbinspacing", "relrelspacing", "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing", "openordspacing", "openopspacing", "openbinspacing", "openrelspacing", "openopenspacing", "openclosespacing", "openpunctspacing", "openinnerspacing", "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing", "closeopenspacing", "closeclosespacing", "closepunctspacing", "closeinnerspacing", "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing", "punctopenspacing", "punctclosespacing", "punctpunctspacing", "punctinnerspacing", "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing", "inneropenspacing", "innerclosespacing", "innerpunctspacing", "innerinnerspacing", "normalreqno", "startimath", "stopimath", "normalstartimath", "normalstopimath", "startdmath", "stopdmath", "normalstartdmath", "normalstopdmath", "normalsuperscript", "normalsubscript", "normalnosuperscript", "normalnosubscript", "superscript", "subscript", "nosuperscript", "nosubscript", "uncramped", "cramped", "triggermathstyle", "mathstylefont", "mathsmallstylefont", "mathstyleface", "mathsmallstyleface", "mathstylecommand", "mathpalette", "mathstylehbox", "mathstylevbox", "mathstylevcenter", "mathstylevcenteredhbox", "mathstylevcenteredvbox", "mathtext", "setmathsmalltextbox", "setmathtextbox", "pushmathstyle", "popmathstyle", "triggerdisplaystyle", "triggertextstyle", "triggerscriptstyle", "triggerscriptscriptstyle", "triggeruncrampedstyle", "triggercrampedstyle", "triggersmallstyle", "triggeruncrampedsmallstyle", "triggercrampedsmallstyle", "triggerbigstyle", "triggeruncrampedbigstyle", "triggercrampedbigstyle", "luaexpr", "expelsedoif", "expdoif", "expdoifnot", "expdoifelsecommon", "expdoifcommonelse", "expdoifelseinset", "expdoifinsetelse", "ctxdirectlua", "ctxlatelua", "ctxsprint", "ctxwrite", "ctxcommand", "ctxdirectcommand", "ctxlatecommand", "ctxreport", "ctxlua", "luacode", "lateluacode", "directluacode", "registerctxluafile", "ctxloadluafile", "luaversion", "luamajorversion", "luaminorversion", "ctxluacode", "luaconditional", "luaexpanded", "startluaparameterset", "stopluaparameterset", "luaparameterset", "definenamedlua", "obeylualines", "obeyluatokens", "startluacode", "stopluacode", "startlua", "stoplua", "startctxfunction", "stopctxfunction", "ctxfunction", "startctxfunctiondefinition", "stopctxfunctiondefinition", "installctxfunction", "cldprocessfile", "cldloadfile", "cldcontext", "cldcommand", "carryoverpar", "lastlinewidth", "assumelongusagecs", "Umathbotaccent", "righttolefthbox", "lefttorighthbox", "righttoleftvbox", "lefttorightvbox", "righttoleftvtop", "lefttorightvtop", "rtlhbox", "ltrhbox", "rtlvbox", "ltrvbox", "rtlvtop", "ltrvtop", "autodirhbox", "autodirvbox", "autodirvtop", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "lefttoright", "righttoleft", "synchronizelayoutdirection", "synchronizedisplaydirection", "synchronizeinlinedirection", "lesshyphens", "morehyphens", "nohyphens", "dohyphens", "Ucheckedstartdisplaymath", "Ucheckedstopdisplaymath", "break", "nobreak", "allowbreak", "goodbreak", "nospace", "nospacing", "dospacing", "naturalhbox", "naturalvbox", "naturalhpack", "naturalvpack", "frule", "compoundhyphenpenalty", "start", "stop" },
} \ No newline at end of file
diff --git a/context/data/textadept/context/data/scite-context-data-interfaces.lua b/context/data/textadept/context/data/scite-context-data-interfaces.lua
index 97c4d0014..a848e923d 100644
--- a/context/data/textadept/context/data/scite-context-data-interfaces.lua
+++ b/context/data/textadept/context/data/scite-context-data-interfaces.lua
@@ -1,5 +1,5 @@
return {
- ["common"]={ "AEacute", "AEligature", "AEmacron", "AMSTEX", "Aacute", "Abreve", "Abreveacute", "Abrevedotbelow", "Abrevegrave", "Abrevehook", "Abrevetilde", "Acaron", "Acircumflex", "Acircumflexacute", "Acircumflexdotbelow", "Acircumflexgrave", "Acircumflexhook", "Acircumflextilde", "Adiaeresis", "Adiaeresismacron", "Adotaccent", "Adotaccentmacron", "Adotbelow", "Adoublegrave", "AfterPar", "Agrave", "Ahook", "Ainvertedbreve", "Alpha", "Alphabeticnumerals", "AmSTeX", "Amacron", "And", "Angstrom", "Aogonek", "Aring", "Aringacute", "Arrowvert", "Astroke", "Atilde", "BeforePar", "Beta", "Bhook", "Big", "Bigg", "Biggl", "Biggm", "Biggr", "Bigl", "Bigm", "Bigr", "Box", "Bumpeq", "CONTEXT", "Cacute", "Cap", "Caps", "Ccaron", "Ccedilla", "Ccircumflex", "Cdotaccent", "Character", "Characters", "Chi", "Chook", "ConTeXt", "Context", "ConvertConstantAfter", "ConvertToConstant", "Cstroke", "Cup", "DZcaronligature", "DZligature", "Dafrican", "Dcaron", "Ddownarrow", "Delta", "Dhook", "Doteq", "Downarrow", "Dstroke", "Dzcaronligature", "Dzligature", "ETEX", "Eacute", "Ebreve", "Ecaron", "Ecedilla", "Ecircumflex", "Ecircumflexacute", "Ecircumflexdotbelow", "Ecircumflexgrave", "Ecircumflexhook", "Ecircumflextilde", "Ediaeresis", "Edotaccent", "Edotbelow", "Edoublegrave", "Egrave", "Ehook", "Einvertedbreve", "Emacron", "Eogonek", "Epsilon", "Eta", "Eth", "Etilde", "Eulerconst", "EveryLine", "EveryPar", "Fhook", "Finv", "Gacute", "Game", "Gamma", "Gbreve", "Gcaron", "Gcircumflex", "Gcommaaccent", "Gdotaccent", "GetPar", "Ghook", "GotoPar", "Greeknumerals", "Gstroke", "Hat", "Hcaron", "Hcircumflex", "Hstroke", "IJligature", "INRSTEX", "Iacute", "Ibreve", "Icaron", "Icircumflex", "Idiaeresis", "Idotaccent", "Idotbelow", "Idoublegrave", "Igrave", "Ihook", "Iinvertedbreve", "Im", "Imacron", "Iogonek", "Iota", "Istroke", "Itilde", "Jcircumflex", "Join", "Kappa", "Kcaron", "Kcommaaccent", "Khook", "LAMSTEX", "LATEX", "LJligature", "LUAJITTEX", "LUATEX", "LaTeX", "Lacute", "LamSTeX", "Lambda", "Lbar", "Lcaron", "Lcommaaccent", "Ldotmiddle", "Ldsh", "Leftarrow", "Leftrightarrow", "Ljligature", "Lleftarrow", "Longleftarrow", "Longleftrightarrow", "Longmapsfrom", "Longmapsto", "Longrightarrow", "Lsh", "Lstroke", "Lua", "LuaTeX", "LuajitTeX", "METAFONT", "METAFUN", "METAPOST", "MKII", "MKIV", "MKIX", "MKVI", "MKXI", "MONTH", "MONTHLONG", "MONTHSHORT", "MPII", "MPIV", "MPVI", "MPanchor", "MPbetex", "MPc", "MPcode", "MPcolor", "MPcoloronly", "MPcolumn", "MPd", "MPdrawing", "MPfontsizehskip", "MPgetmultipars", "MPgetmultishape", "MPgetposboxes", "MPh", "MPinclusions", "MPleftskip", "MPll", "MPlr", "MPls", "MPmenubuttons", "MPn", "MPoptions", "MPoverlayanchor", "MPp", "MPpage", "MPpardata", "MPplus", "MPpos", "MPpositiongraphic", "MPposset", "MPr", "MPrawvar", "MPregion", "MPrest", "MPrightskip", "MPrs", "MPstring", "MPtext", "MPtransparency", "MPul", "MPur", "MPv", "MPvar", "MPvariable", "MPvv", "MPw", "MPwhd", "MPx", "MPxy", "MPxywhd", "MPy", "Mapsfrom", "Mapsto", "MetaFont", "MetaFun", "MetaPost", "Mu", "NJligature", "Nacute", "Ncaron", "Ncommaaccent", "Nearrow", "Neng", "Ngrave", "Njligature", "NormalizeFontHeight", "NormalizeFontWidth", "NormalizeTextHeight", "NormalizeTextWidth", "Ntilde", "Nu", "Numbers", "Nwarrow", "OEligature", "Oacute", "Obreve", "Ocaron", "Ocircumflex", "Ocircumflexacute", "Ocircumflexdotbelow", "Ocircumflexgrave", "Ocircumflexhook", "Ocircumflextilde", "Odiaeresis", "Odiaeresismacron", "Odotaccent", "Odotaccentmacron", "Odotbelow", "Odoublegrave", "Ograve", "Ohook", "Ohorn", "Ohornacute", "Ohorndotbelow", "Ohorngrave", "Ohornhook", "Ohorntilde", "Ohungarumlaut", "Oinvertedbreve", "Omacron", "Omega", "Omicron", "Oogonek", "Oogonekmacron", "Ostroke", "Ostrokeacute", "Otilde", "Otildemacron", "P", "PDFETEX", "PDFTEX", "PDFcolor", "PICTEX", "PPCHTEX", "PPCHTeX", "PRAGMA", "Phi", "Phook", "Pi", "PiCTeX", "Plankconst", "PointsToBigPoints", "PointsToReal", "PointsToWholeBigPoints", "PropertyLine", "Psi", "PtToCm", "Racute", "Rcaron", "Rcommaaccent", "Rdoublegrave", "Rdsh", "Re", "ReadFile", "Relbar", "Rho", "Rightarrow", "Rinvertedbreve", "Romannumerals", "Rrightarrow", "Rsh", "S", "Sacute", "ScaledPointsToBigPoints", "ScaledPointsToWholeBigPoints", "Scaron", "Scedilla", "Schwa", "Scircumflex", "Scommaaccent", "Searrow", "Sigma", "Smallcapped", "Subset", "Supset", "Swarrow", "TABLE", "TEX", "TaBlE", "Tau", "Tcaron", "Tcedilla", "Tcommaaccent", "TeX", "TheNormalizedFontSize", "Theta", "Thook", "Thorn", "TransparencyHack", "Tstroke", "Uacute", "Ubreve", "Ucaron", "Ucircumflex", "Udiaeresis", "Udiaeresisacute", "Udiaeresiscaron", "Udiaeresisgrave", "Udiaeresismacron", "Udotbelow", "Udoublegrave", "Ugrave", "Uhook", "Uhorn", "Uhornacute", "Uhorndotbelow", "Uhorngrave", "Uhornhook", "Uhorntilde", "Uhungarumlaut", "Uinvertedbreve", "Umacron", "Uogonek", "Uparrow", "Updownarrow", "Upsilon", "Uring", "Utilde", "Uuparrow", "VDash", "Vdash", "VerboseNumber", "Vert", "Vvdash", "WEEKDAY", "WORD", "WORDS", "Wcircumflex", "WidthSpanningText", "Word", "Words", "XETEX", "XeTeX", "Xi", "Yacute", "Ycircumflex", "Ydiaeresis", "Ydotbelow", "Ygrave", "Yhook", "Ymacron", "Ytilde", "Zacute", "Zcaron", "Zdotaccent", "Zeta", "Zhook", "Zstroke", "aacute", "abbreviation", "abjadnaivenumerals", "abjadnodotnumerals", "abjadnumerals", "about", "abreve", "abreveacute", "abrevedotbelow", "abrevegrave", "abrevehook", "abrevetilde", "acaron", "acircumflex", "acircumflexacute", "acircumflexdotbelow", "acircumflexgrave", "acircumflexhook", "acircumflextilde", "activatespacehandler", "actuarial", "acute", "acwopencirclearrow", "adaptcollector", "adaptfontfeature", "adaptlayout", "adaptpapersize", "addfeature", "addtoJSpreamble", "addtocommalist", "addvalue", "adiaeresis", "adiaeresismacron", "adotaccent", "adotaccentmacron", "adotbelow", "adoublegrave", "aeacute", "aeligature", "aemacron", "aftersplitstring", "aftertestandsplitstring", "agrave", "ahook", "ainvertedbreve", "aleph", "alignbottom", "aligned", "alignedbox", "alignedline", "alignhere", "alignmentcharacter", "allinputpaths", "alpha", "alphabeticnumerals", "alwayscitation", "alwayscite", "amacron", "amalg", "ampersand", "anchor", "angle", "aogonek", "appendetoks", "appendgvalue", "appendtocommalist", "appendtoks", "appendtoksonce", "appendvalue", "apply", "applyalternativestyle", "applyprocessor", "applytocharacters", "applytofirstcharacter", "applytosplitstringchar", "applytosplitstringcharspaced", "applytosplitstringline", "applytosplitstringlinespaced", "applytosplitstringword", "applytosplitstringwordspaced", "applytowords", "approx", "approxEq", "approxeq", "approxnEq", "arabicdecimals", "arabicexnumerals", "arabicnumerals", "arg", "aring", "aringacute", "arrowvert", "asciistr", "aside", "assignalfadimension", "assigndimen", "assigndimension", "assignifempty", "assigntranslation", "assignvalue", "assignwidth", "assumelongusagecs", "ast", "astype", "asymp", "at", "atilde", "atleftmargin", "atpage", "atrightmargin", "attachment", "autocap", "autodirhbox", "autodirvbox", "autodirvtop", "autoinsertnextspace", "autointegral", "automathematics", "autosetups", "availablehsize", "averagecharwidth", "backepsilon", "background", "backgroundimage", "backgroundimagefill", "backgroundline", "backprime", "backsim", "backslash", "bar", "barleftarrow", "barleftarrowrightarrowbar", "barovernorthwestarrow", "barwedge", "basegrid", "baselinebottom", "baselineleftbox", "baselinemiddlebox", "baselinerightbox", "bbordermatrix", "bbox", "because", "beforesplitstring", "beforetestandsplitstring", "beta", "beth", "between", "bhook", "big", "bigbodyfont", "bigcap", "bigcirc", "bigcircle", "bigcup", "bigdiamond", "bigg", "bigger", "biggl", "biggm", "biggr", "bigl", "bigm", "bigodot", "bigoplus", "bigotimes", "bigr", "bigskip", "bigsqcap", "bigsqcup", "bigsquare", "bigstar", "bigtimes", "bigtriangledown", "bigtriangleup", "bigudot", "biguplus", "bigvee", "bigwedge", "binom", "bitmapimage", "blacklozenge", "blackrule", "blackrules", "blacksquare", "blacktriangle", "blacktriangledown", "blacktriangleleft", "blacktriangleright", "blank", "blap", "bleed", "bleedheight", "bleedwidth", "blockligatures", "blockquote", "blocksynctexfile", "bodyfontenvironmentlist", "bodyfontsize", "bold", "boldface", "bolditalic", "boldslanted", "bookmark", "booleanmodevalue", "bordermatrix", "bot", "bottombox", "bottomleftbox", "bottomrightbox", "bowtie", "boxcursor", "boxdot", "boxmarker", "boxminus", "boxofsize", "boxplus", "boxreference", "boxtimes", "bpos", "breakablethinspace", "breakhere", "breve", "bstroke", "btxabbreviatedjournal", "btxaddjournal", "btxalwayscitation", "btxauthorfield", "btxdetail", "btxdirect", "btxdoif", "btxdoifcombiinlistelse", "btxdoifelse", "btxdoifelsecombiinlist", "btxdoifelsesameasprevious", "btxdoifelsesameaspreviouschecked", "btxdoifelseuservariable", "btxdoifnot", "btxdoifsameaspreviouscheckedelse", "btxdoifsameaspreviouselse", "btxdoifuservariableelse", "btxexpandedjournal", "btxfield", "btxfieldname", "btxfieldtype", "btxfirstofrange", "btxflush", "btxflushauthor", "btxflushauthorinverted", "btxflushauthorinvertedshort", "btxflushauthorname", "btxflushauthornormal", "btxflushauthornormalshort", "btxflushsuffix", "btxfoundname", "btxfoundtype", "btxhiddencitation", "btxhybridcite", "btxlabellanguage", "btxlabeltext", "btxlistcitation", "btxloadjournalist", "btxoneorrange", "btxremapauthor", "btxsavejournalist", "btxsetup", "btxsingularorplural", "btxsingularplural", "btxtextcitation", "buildmathaccent", "buildtextaccent", "buildtextbottomcomma", "buildtextbottomdot", "buildtextcedilla", "buildtextgrave", "buildtextmacron", "buildtextognek", "bullet", "button", "cacute", "calligraphic", "camel", "cap", "carriagereturn", "catcodetablename", "cbox", "ccaron", "ccedilla", "ccircumflex", "ccurl", "cdot", "cdotaccent", "cdotp", "cdots", "centeraligned", "centerbox", "centerdot", "centeredbox", "centeredlastline", "centerednextbox", "centerline", "cfrac", "chapter", "character", "characters", "chardescription", "charwidthlanguage", "check", "checkcharacteralign", "checkedchar", "checkedfiller", "checkedstrippedcsname", "checkinjector", "checkmark", "checknextindentation", "checknextinjector", "checkpage", "checkparameters", "checkpreviousinjector", "checksoundtrack", "checktwopassdata", "checkvariables", "chem", "chemical", "chemicalbottext", "chemicalmidtext", "chemicalsymbol", "chemicaltext", "chemicaltoptext", "chi", "chineseallnumerals", "chinesecapnumerals", "chinesenumerals", "chook", "circ", "circeq", "circlearrowleft", "circlearrowright", "circledR", "circledS", "circledast", "circledcirc", "circleddash", "circledequals", "circleonrightarrow", "citation", "cite", "clap", "classfont", "cldcommand", "cldcontext", "cldloadfile", "cldprocessfile", "cleftarrow", "clip", "clonefield", "clubsuit", "collect", "collectedtext", "collectexpanded", "colon", "coloncolonequals", "colonequals", "color", "colorbar", "colorcomponents", "colored", "coloronly", "colorvalue", "column", "columnbreak", "combinepages", "commalistelement", "commalistsentence", "commalistsize", "comment", "comparecolorgroup", "comparedimension", "comparedimensioneps", "comparepalet", "complement", "completebtxrendering", "completecontent", "completeindex", "completelist", "completelistofabbreviations", "completelistofchemicals", "completelistoffigures", "completelistofgraphics", "completelistofintermezzi", "completelistoflogos", "completelistofpublications", "completelistofsorts", "completelistofsynonyms", "completelistoftables", "completepagenumber", "completeregister", "complexes", "complexorsimple", "complexorsimpleempty", "component", "composedcollector", "composedlayer", "compresult", "cong", "constantdimen", "constantdimenargument", "constantemptyargument", "constantnumber", "constantnumberargument", "contentreference", "continuednumber", "continueifinputfile", "convertargument", "convertcommand", "convertedcounter", "converteddimen", "convertedsubcounter", "convertmonth", "convertnumber", "convertvalue", "convertvboxtohbox", "coprod", "copyboxfromcache", "copybtxlabeltext", "copyfield", "copyheadtext", "copylabeltext", "copymathlabeltext", "copyoperatortext", "copypages", "copyparameters", "copyposition", "copyprefixtext", "copyright", "copysuffixtext", "copytaglabeltext", "copyunittext", "correctwhitespace", "countersubs", "counttoken", "counttokens", "cramped", "crampedclap", "crampedllap", "crampedrlap", "crightarrow", "crightoverleftarrow", "cstroke", "ctop", "ctxcommand", "ctxdirectcommand", "ctxdirectlua", "ctxfunction", "ctxlatecommand", "ctxlatelua", "ctxloadluafile", "ctxlua", "ctxluabuffer", "ctxluacode", "ctxreport", "ctxsprint", "cup", "curlyeqprec", "curlyeqsucc", "curlyvee", "curlywedge", "currentassignmentlistkey", "currentassignmentlistvalue", "currentbtxuservariable", "currentcommalistitem", "currentcomponent", "currentdate", "currentenvironment", "currentfeaturetest", "currentheadnumber", "currentinterface", "currentlanguage", "currentlistentrydestinationattribute", "currentlistentrylimitedtext", "currentlistentrynumber", "currentlistentrypagenumber", "currentlistentryreferenceattribute", "currentlistentrytitle", "currentlistentrytitlerendered", "currentlistsymbol", "currentmainlanguage", "currentmessagetext", "currentmoduleparameter", "currentoutputstream", "currentproduct", "currentproject", "currentregime", "currentregisterpageuserdata", "currentresponses", "currenttime", "currentvalue", "currentxtablecolumn", "currentxtablerow", "curvearrowleft", "curvearrowright", "cwopencirclearrow", "cyrillicA", "cyrillicAE", "cyrillicAbreve", "cyrillicAdiaeresis", "cyrillicB", "cyrillicBIGYUS", "cyrillicBIGYUSiotified", "cyrillicC", "cyrillicCH", "cyrillicCHEDC", "cyrillicCHEDCabkhasian", "cyrillicCHEabkhasian", "cyrillicCHEdiaeresis", "cyrillicCHEkhakassian", "cyrillicCHEvertstroke", "cyrillicD", "cyrillicDASIAPNEUMATA", "cyrillicDJE", "cyrillicDZE", "cyrillicDZEabkhasian", "cyrillicDZHE", "cyrillicE", "cyrillicELtail", "cyrillicEMtail", "cyrillicENDC", "cyrillicENGHE", "cyrillicENhook", "cyrillicENtail", "cyrillicEREV", "cyrillicERY", "cyrillicERtick", "cyrillicEbreve", "cyrillicEdiaeresis", "cyrillicEgrave", "cyrillicEiotified", "cyrillicF", "cyrillicFITA", "cyrillicG", "cyrillicGHEmidhook", "cyrillicGHEstroke", "cyrillicGHEupturn", "cyrillicGJE", "cyrillicH", "cyrillicHA", "cyrillicHADC", "cyrillicHRDSN", "cyrillicI", "cyrillicIE", "cyrillicII", "cyrillicISHRT", "cyrillicISHRTtail", "cyrillicIZHITSA", "cyrillicIZHITSAdoublegrave", "cyrillicIdiaeresis", "cyrillicIgrave", "cyrillicImacron", "cyrillicJE", "cyrillicK", "cyrillicKADC", "cyrillicKAbashkir", "cyrillicKAhook", "cyrillicKAstroke", "cyrillicKAvertstroke", "cyrillicKJE", "cyrillicKOPPA", "cyrillicKSI", "cyrillicL", "cyrillicLITTLEYUS", "cyrillicLITTLEYUSiotified", "cyrillicLJE", "cyrillicM", "cyrillicN", "cyrillicNJE", "cyrillicO", "cyrillicOMEGA", "cyrillicOMEGAround", "cyrillicOMEGAtitlo", "cyrillicOT", "cyrillicObarred", "cyrillicObarreddiaeresis", "cyrillicOdiaeresis", "cyrillicP", "cyrillicPALATALIZATION", "cyrillicPALOCHKA", "cyrillicPEmidhook", "cyrillicPSI", "cyrillicPSILIPNEUMATA", "cyrillicR", "cyrillicS", "cyrillicSCHWA", "cyrillicSCHWAdiaeresis", "cyrillicSDSC", "cyrillicSEMISOFT", "cyrillicSFTSN", "cyrillicSH", "cyrillicSHCH", "cyrillicSHHA", "cyrillicT", "cyrillicTEDC", "cyrillicTETSE", "cyrillicTITLO", "cyrillicTSHE", "cyrillicU", "cyrillicUK", "cyrillicUSHRT", "cyrillicUdiaeresis", "cyrillicUdoubleacute", "cyrillicUmacron", "cyrillicV", "cyrillicYA", "cyrillicYAT", "cyrillicYERUdiaeresis", "cyrillicYI", "cyrillicYO", "cyrillicYU", "cyrillicYstr", "cyrillicYstrstroke", "cyrillicZ", "cyrillicZDSC", "cyrillicZEdiaeresis", "cyrillicZH", "cyrillicZHEbreve", "cyrillicZHEdescender", "cyrillicZHEdiaeresis", "cyrillica", "cyrillicabreve", "cyrillicadiaeresis", "cyrillicae", "cyrillicb", "cyrillicbigyus", "cyrillicbigyusiotified", "cyrillicc", "cyrillicch", "cyrilliccheabkhasian", "cyrillicchedc", "cyrillicchedcabkhasian", "cyrillicchediaeresis", "cyrillicchekhakassian", "cyrillicchevertstroke", "cyrillicd", "cyrillicdje", "cyrillicdze", "cyrillicdzeabkhasian", "cyrillicdzhe", "cyrillice", "cyrillicebreve", "cyrillicediaeresis", "cyrillicegrave", "cyrilliceiotified", "cyrilliceltail", "cyrillicemtail", "cyrillicendc", "cyrillicenghe", "cyrillicenhook", "cyrillicentail", "cyrillicerev", "cyrillicertick", "cyrillicery", "cyrillicf", "cyrillicfita", "cyrillicg", "cyrillicghemidhook", "cyrillicghestroke", "cyrillicgheupturn", "cyrillicgje", "cyrillich", "cyrillicha", "cyrillichadc", "cyrillichrdsn", "cyrillici", "cyrillicidiaeresis", "cyrillicie", "cyrillicigrave", "cyrillicii", "cyrillicimacron", "cyrillicishrt", "cyrillicishrttail", "cyrillicizhitsa", "cyrillicizhitsadoublegrave", "cyrillicje", "cyrillick", "cyrillickabashkir", "cyrillickadc", "cyrillickahook", "cyrillickastroke", "cyrillickavertstroke", "cyrillickje", "cyrillickoppa", "cyrillicksi", "cyrillicl", "cyrilliclittleyus", "cyrilliclittleyusiotified", "cyrilliclje", "cyrillicm", "cyrillicn", "cyrillicnje", "cyrillico", "cyrillicobarred", "cyrillicobarreddiaeresis", "cyrillicodiaeresis", "cyrillicomega", "cyrillicomegaround", "cyrillicomegatitlo", "cyrillicot", "cyrillicp", "cyrillicpemidhook", "cyrillicpsi", "cyrillicr", "cyrillics", "cyrillicschwa", "cyrillicschwadiaeresis", "cyrillicsdsc", "cyrillicsemisoft", "cyrillicsftsn", "cyrillicsh", "cyrillicshch", "cyrillicshha", "cyrillict", "cyrillictedc", "cyrillictetse", "cyrillictshe", "cyrillicu", "cyrillicudiaeresis", "cyrillicudoubleacute", "cyrillicuk", "cyrillicumacron", "cyrillicushrt", "cyrillicv", "cyrillicya", "cyrillicyat", "cyrillicyerudiaeresis", "cyrillicyi", "cyrillicyo", "cyrillicystr", "cyrillicystrstroke", "cyrillicyu", "cyrillicz", "cyrilliczdsc", "cyrilliczediaeresis", "cyrilliczh", "cyrilliczhebreve", "cyrilliczhedescender", "cyrilliczhediaeresis", "d", "dag", "dagger", "daleth", "dasharrow", "dashedleftarrow", "dashedrightarrow", "dashv", "datasetvariable", "date", "dayoftheweek", "dayspermonth", "dbinom", "dcaron", "dcurl", "ddag", "ddagger", "dddot", "ddot", "ddots", "decrement", "decrementcounter", "decrementedcounter", "decrementpagenumber", "decrementsubpagenumber", "decrementvalue", "defaultinterface", "defaultobjectpage", "defaultobjectreference", "defcatcodecommand", "defconvertedargument", "defconvertedcommand", "defconvertedvalue", "define", "defineMPinstance", "defineTABLEsetup", "defineaccent", "defineactivecharacter", "definealternativestyle", "defineanchor", "defineattachment", "defineattribute", "definebackground", "definebar", "defineblock", "definebodyfont", "definebodyfontenvironment", "definebodyfontswitch", "definebreakpoint", "definebreakpoints", "definebtx", "definebtxdataset", "definebtxregister", "definebtxrendering", "definebuffer", "definebutton", "definecapitals", "definecharacter", "definecharacterkerning", "definecharacterspacing", "definechemical", "definechemicals", "definechemicalsymbol", "definecollector", "definecolor", "definecolorgroup", "definecolumnbreak", "definecombination", "definecombinedlist", "definecommand", "definecomment", "definecomplexorsimple", "definecomplexorsimpleempty", "defineconversion", "defineconversionset", "definecounter", "definedataset", "definedelimitedtext", "definedeq", "definedescription", "definedfont", "defineeffect", "defineenumeration", "defineexpandable", "defineexternalfigure", "definefallbackfamily", "definefield", "definefieldbody", "definefieldbodyset", "definefieldcategory", "definefieldstack", "definefiguresymbol", "definefileconstant", "definefilefallback", "definefilesynonym", "definefiller", "definefirstline", "definefittingpage", "definefloat", "definefont", "definefontalternative", "definefontfallback", "definefontfamily", "definefontfamilypreset", "definefontfeature", "definefontfile", "definefontsize", "definefontsolution", "definefontstyle", "definefontsynonym", "defineformula", "defineformulaalternative", "defineformulaframed", "defineframed", "defineframedcontent", "defineframedtable", "defineframedtext", "definefrozenfont", "defineglobalcolor", "definegraphictypesynonym", "definegridsnapping", "definehbox", "definehead", "defineheadalternative", "definehelp", "definehigh", "definehighlight", "definehspace", "definehypenationfeatures", "defineindentedtext", "defineindenting", "defineinitial", "defineinsertion", "defineinteraction", "defineinteractionbar", "defineinteractionmenu", "defineinterfaceconstant", "defineinterfaceelement", "defineinterfacevariable", "defineinterlinespace", "defineintermediatecolor", "defineitemgroup", "defineitems", "definelabel", "definelabelclass", "definelayer", "definelayerpreset", "definelayout", "definelinefiller", "definelinenote", "definelinenumbering", "definelines", "definelist", "definelistalternative", "definelistextra", "definelow", "definelowhigh", "definelowmidhigh", "definemakeup", "definemarginblock", "definemargindata", "definemarker", "definemarking", "definemathaccent", "definemathalignment", "definemathcases", "definemathcommand", "definemathdouble", "definemathdoubleextensible", "definemathematics", "definemathextensible", "definemathfence", "definemathfraction", "definemathframed", "definemathmatrix", "definemathornament", "definemathover", "definemathoverextensible", "definemathovertextextensible", "definemathradical", "definemathstackers", "definemathstyle", "definemathtriplet", "definemathunder", "definemathunderextensible", "definemathundertextextensible", "definemathunstacked", "definemeasure", "definemessageconstant", "definemixedcolumns", "definemode", "definemultitonecolor", "definenamedcolor", "definenamespace", "definenarrower", "definenote", "defineornament", "defineoutputroutine", "defineoutputroutinecommand", "defineoverlay", "definepage", "definepagebreak", "definepagechecker", "definepagegrid", "definepagegridarea", "definepagegridspan", "definepageinjection", "definepageinjectionalternative", "definepageshift", "definepagestate", "definepairedbox", "definepalet", "definepapersize", "defineparagraph", "defineparagraphs", "defineparallel", "defineparbuilder", "defineplacement", "definepositioning", "defineprefixset", "defineprocesscolor", "defineprocessor", "defineprofile", "defineprogram", "definepushbutton", "definepushsymbol", "definereference", "definereferenceformat", "defineregister", "definerenderingwindow", "defineresetset", "definescale", "definescript", "definesection", "definesectionblock", "definesectionlevels", "defineselector", "defineseparatorset", "defineshift", "definesidebar", "definesort", "definesorting", "definespotcolor", "definestartstop", "definestyle", "definestyleinstance", "definesubfield", "definesubformula", "definesymbol", "definesynonym", "definesynonyms", "definesystemattribute", "definesystemconstant", "definesystemvariable", "definetabletemplate", "definetabulate", "definetabulation", "definetext", "definetextbackground", "definetextflow", "definetooltip", "definetransparency", "definetwopasslist", "definetype", "definetypeface", "definetypescriptprefix", "definetypescriptsynonym", "definetypesetting", "definetyping", "defineunit", "defineviewerlayer", "definevspace", "definevspacing", "definevspacingamount", "definextable", "delimited", "delimitedtext", "delta", "depthofstring", "depthonlybox", "depthspanningtext", "depthstrut", "determineheadnumber", "determinelistcharacteristics", "determinenoflines", "determineregistercharacteristics", "devanagarinumerals", "dfrac", "dhook", "diameter", "diamond", "diamondsuit", "differentialD", "differentiald", "digamma", "digits", "dimensiontocount", "directboxfromcache", "directcolor", "directcolored", "directconvertedcounter", "directcopyboxfromcache", "directdummyparameter", "directgetboxllx", "directgetboxlly", "directhighlight", "directlocalframed", "directluacode", "directselect", "directsetbar", "directsetup", "directsymbol", "directvspacing", "dis", "disabledirectives", "disableexperiments", "disablemode", "disableoutputstream", "disableparpositions", "disableregime", "disabletrackers", "displaymath", "displaymathematics", "displaymessage", "distributedhsize", "div", "dividedsize", "divideontimes", "divides", "doadaptleftskip", "doadaptrightskip", "doaddfeature", "doassign", "doassignempty", "doboundtext", "docheckassignment", "docheckedpagestate", "docheckedpair", "documentvariable", "dodoubleargument", "dodoubleargumentwithset", "dodoubleempty", "dodoubleemptywithset", "dodoublegroupempty", "doeassign", "doexpandedrecurse", "dofastloopcs", "dogetattribute", "dogetattributeid", "dogetcommacommandelement", "dogobbledoubleempty", "dogobblesingleempty", "doif", "doifMPgraphicelse", "doifallcommon", "doifallcommonelse", "doifalldefinedelse", "doifallmodes", "doifallmodeselse", "doifassignmentelse", "doifblackelse", "doifbothsides", "doifbothsidesoverruled", "doifboxelse", "doifbufferelse", "doifcolor", "doifcolorelse", "doifcommandhandler", "doifcommandhandlerelse", "doifcommon", "doifcommonelse", "doifcontent", "doifconversiondefinedelse", "doifconversionnumberelse", "doifcounter", "doifcounterelse", "doifcurrentfonthasfeatureelse", "doifdefined", "doifdefinedcounter", "doifdefinedcounterelse", "doifdefinedelse", "doifdimensionelse", "doifdimenstringelse", "doifdocumentargument", "doifdocumentargumentelse", "doifdocumentfilename", "doifdocumentfilenameelse", "doifdrawingblackelse", "doifelse", "doifelseMPgraphic", "doifelseallcommon", "doifelsealldefined", "doifelseallmodes", "doifelseassignment", "doifelseblack", "doifelsebox", "doifelseboxincache", "doifelsebuffer", "doifelsecolor", "doifelsecommandhandler", "doifelsecommon", "doifelseconversiondefined", "doifelseconversionnumber", "doifelsecounter", "doifelsecurrentfonthasfeature", "doifelsecurrentsortingused", "doifelsecurrentsynonymshown", "doifelsecurrentsynonymused", "doifelsedefined", "doifelsedefinedcounter", "doifelsedimension", "doifelsedimenstring", "doifelsedocumentargument", "doifelsedocumentfilename", "doifelsedrawingblack", "doifelseempty", "doifelseemptyvalue", "doifelseemptyvariable", "doifelseenv", "doifelsefastoptionalcheck", "doifelsefastoptionalcheckcs", "doifelsefieldbody", "doifelsefieldcategory", "doifelsefigure", "doifelsefile", "doifelsefiledefined", "doifelsefileexists", "doifelsefirstchar", "doifelseflagged", "doifelsefontchar", "doifelsefontpresent", "doifelsefontsynonym", "doifelsehasspace", "doifelsehelp", "doifelseincsname", "doifelseinelement", "doifelseinputfile", "doifelseinsertion", "doifelseinset", "doifelseinstring", "doifelseinsymbolset", "doifelseintoks", "doifelseintwopassdata", "doifelseitalic", "doifelselanguage", "doifelselayerdata", "doifelselayoutdefined", "doifelselayoutsomeline", "doifelselayouttextline", "doifelseleapyear", "doifelselist", "doifelselocation", "doifelselocfile", "doifelsemainfloatbody", "doifelsemarkedpage", "doifelsemarking", "doifelsemeaning", "doifelsemessage", "doifelsemode", "doifelsenextbgroup", "doifelsenextbgroupcs", "doifelsenextchar", "doifelsenextoptional", "doifelsenextoptionalcs", "doifelsenextparenthesis", "doifelsenonzeropositive", "doifelsenoteonsamepage", "doifelsenothing", "doifelsenumber", "doifelseobjectfound", "doifelseobjectreferencefound", "doifelseoddpage", "doifelseoddpagefloat", "doifelseoldercontext", "doifelseolderversion", "doifelseoverlapping", "doifelseoverlay", "doifelseparallel", "doifelseparentfile", "doifelsepath", "doifelsepathexists", "doifelsepatterns", "doifelseposition", "doifelsepositionaction", "doifelsepositiononpage", "doifelsepositionsonsamepage", "doifelsepositionsonthispage", "doifelsepositionsused", "doifelsereferencefound", "doifelserightpagefloat", "doifelserighttoleftinbox", "doifelsesamelinereference", "doifelsesamestring", "doifelsesetups", "doifelsesomebackground", "doifelsesomespace", "doifelsesomething", "doifelsesometoks", "doifelsestringinstring", "doifelsestructurelisthasnumber", "doifelsestructurelisthaspage", "doifelsesymboldefined", "doifelsesymbolset", "doifelsetext", "doifelsetextflow", "doifelsetextflowcollector", "doifelsetopofpage", "doifelsetypingfile", "doifelseundefined", "doifelseurldefined", "doifelsevalue", "doifelsevaluenothing", "doifelsevariable", "doifempty", "doifemptyelse", "doifemptytoks", "doifemptyvalue", "doifemptyvalueelse", "doifemptyvariable", "doifemptyvariableelse", "doifenv", "doifenvelse", "doiffastoptionalcheckcselse", "doiffastoptionalcheckelse", "doiffieldbodyelse", "doiffieldcategoryelse", "doiffigureelse", "doiffile", "doiffiledefinedelse", "doiffileelse", "doiffileexistselse", "doiffirstcharelse", "doifflaggedelse", "doiffontcharelse", "doiffontpresentelse", "doiffontsynonymelse", "doifhasspaceelse", "doifhelpelse", "doifincsnameelse", "doifinelementelse", "doifinputfileelse", "doifinsertionelse", "doifinset", "doifinsetelse", "doifinstring", "doifinstringelse", "doifinsymbolset", "doifinsymbolsetelse", "doifintokselse", "doifintwopassdataelse", "doifitalicelse", "doiflanguageelse", "doiflayerdataelse", "doiflayoutdefinedelse", "doiflayoutsomelineelse", "doiflayouttextlineelse", "doifleapyearelse", "doiflistelse", "doiflocationelse", "doiflocfileelse", "doifmainfloatbodyelse", "doifmarkingelse", "doifmeaningelse", "doifmessageelse", "doifmode", "doifmodeelse", "doifnextbgroupcselse", "doifnextbgroupelse", "doifnextcharelse", "doifnextoptionalcselse", "doifnextoptionalelse", "doifnextparenthesiselse", "doifnonzeropositiveelse", "doifnot", "doifnotallcommon", "doifnotallmodes", "doifnotcommandhandler", "doifnotcommon", "doifnotcounter", "doifnotdocumentargument", "doifnotdocumentfilename", "doifnotempty", "doifnotemptyvalue", "doifnotemptyvariable", "doifnotenv", "doifnoteonsamepageelse", "doifnotescollected", "doifnotfile", "doifnotflagged", "doifnothing", "doifnothingelse", "doifnotinset", "doifnotinsidesplitfloat", "doifnotinstring", "doifnotmode", "doifnotnumber", "doifnotsamestring", "doifnotsetups", "doifnotvalue", "doifnotvariable", "doifnumber", "doifnumberelse", "doifobjectfoundelse", "doifobjectreferencefoundelse", "doifoddpageelse", "doifoddpagefloatelse", "doifoldercontextelse", "doifolderversionelse", "doifoverlappingelse", "doifoverlayelse", "doifparallelelse", "doifparentfileelse", "doifpathelse", "doifpathexistselse", "doifpatternselse", "doifposition", "doifpositionaction", "doifpositionactionelse", "doifpositionelse", "doifpositiononpageelse", "doifpositionsonsamepageelse", "doifpositionsonthispageelse", "doifpositionsusedelse", "doifreferencefoundelse", "doifrightpagefloatelse", "doifrighttoleftinboxelse", "doifsamelinereferenceelse", "doifsamestring", "doifsamestringelse", "doifsetups", "doifsetupselse", "doifsomebackground", "doifsomebackgroundelse", "doifsomespaceelse", "doifsomething", "doifsomethingelse", "doifsometoks", "doifsometokselse", "doifstringinstringelse", "doifstructurelisthasnumberelse", "doifstructurelisthaspageelse", "doifsymboldefinedelse", "doifsymbolsetelse", "doiftext", "doiftextelse", "doiftextflowcollectorelse", "doiftextflowelse", "doiftopofpageelse", "doiftypingfileelse", "doifundefined", "doifundefinedcounter", "doifundefinedelse", "doifurldefinedelse", "doifvalue", "doifvalueelse", "doifvaluenothing", "doifvaluenothingelse", "doifvaluesomething", "doifvariable", "doifvariableelse", "doindentation", "dollar", "doloop", "doloopoverlist", "donothing", "dontconvertfont", "dontleavehmode", "dontpermitspacesbetweengroups", "dopositionaction", "doprocesslocalsetups", "doquadrupleargument", "doquadrupleempty", "doquadruplegroupempty", "doquintupleargument", "doquintupleempty", "doquintuplegroupempty", "dorechecknextindentation", "dorecurse", "dorepeatwithcommand", "doreplacefeature", "doresetandafffeature", "doresetattribute", "dorotatebox", "dosetattribute", "dosetleftskipadaption", "dosetrightskipadaption", "dosetupcheckedinterlinespace", "doseventupleargument", "doseventupleempty", "dosingleargument", "dosingleempty", "dosinglegroupempty", "dosixtupleargument", "dosixtupleempty", "dostepwiserecurse", "dosubtractfeature", "dot", "doteq", "doteqdot", "dotfskip", "dotlessI", "dotlessJ", "dotlessi", "dotlessj", "dotlessjstroke", "dotminus", "dotoks", "dotplus", "dotripleargument", "dotripleargumentwithset", "dotripleempty", "dotripleemptywithset", "dotriplegroupempty", "dots", "dottedrightarrow", "doublebar", "doublebond", "doublebrace", "doublebracket", "doublecap", "doublecup", "doubleparent", "doubleprime", "doubleverticalbar", "dowith", "dowithnextbox", "dowithnextboxcontent", "dowithnextboxcontentcs", "dowithnextboxcs", "dowithpargument", "dowithrange", "dowithwargument", "downarrow", "downdasharrow", "downdownarrows", "downharpoonleft", "downharpoonright", "downuparrows", "downwhitearrow", "downzigzagarrow", "dpofstring", "dstroke", "dtail", "dummydigit", "dummyparameter", "dzcaronligature", "dzligature", "eTeX", "eacute", "ebreve", "ecaron", "ecedilla", "ecircumflex", "ecircumflexacute", "ecircumflexdotbelow", "ecircumflexgrave", "ecircumflexhook", "ecircumflextilde", "edefconvertedargument", "ediaeresis", "edotaccent", "edotbelow", "edoublegrave", "efcmaxheight", "efcmaxwidth", "efcminheight", "efcminwidth", "efcparameter", "effect", "egrave", "ehook", "einvertedbreve", "elapsedseconds", "elapsedtime", "eleftarrowfill", "eleftharpoondownfill", "eleftharpoonupfill", "eleftrightarrowfill", "ell", "em", "emacron", "emdash", "emphasisboldface", "emphasistypeface", "emptylines", "emptyset", "emspace", "enabledirectives", "enableexperiments", "enablemode", "enableoutputstream", "enableparpositions", "enableregime", "enabletrackers", "endash", "endnote", "enskip", "enspace", "env", "environment", "envvar", "eogonek", "eoverbarfill", "eoverbracefill", "eoverbracketfill", "eoverparentfill", "epos", "epsilon", "eq", "eqcirc", "eqeq", "eqeqeq", "eqgtr", "eqless", "eqsim", "eqslantgtr", "eqslantless", "equaldigits", "equalscolon", "equiv", "erightarrowfill", "erightharpoondownfill", "erightharpoonupfill", "eta", "eth", "ethiopic", "etilde", "etwoheadrightarrowfill", "eunderbarfill", "eunderbracefill", "eunderbracketfill", "eunderparentfill", "exclamdown", "executeifdefined", "exists", "exitloop", "exitloopnow", "expandcheckedcsname", "expanded", "expandfontsynonym", "expdoif", "expdoifcommonelse", "expdoifelse", "expdoifelsecommon", "expdoifelseinset", "expdoifinsetelse", "expdoifnot", "exponentiale", "externalfigure", "externalfigurecollectionmaxheight", "externalfigurecollectionmaxwidth", "externalfigurecollectionminheight", "externalfigurecollectionminwidth", "externalfigurecollectionparameter", "fakebox", "fallingdotseq", "fastdecrement", "fastincrement", "fastlocalframed", "fastloopfinal", "fastloopindex", "fastscale", "fastsetup", "fastsetupwithargument", "fastsetupwithargumentswapped", "fastswitchtobodyfont", "fastsxsy", "feature", "fence", "fenced", "fetchallmarkings", "fetchallmarks", "fetchmark", "fetchmarking", "fetchonemark", "fetchonemarking", "fetchruntinecommand", "fetchtwomarkings", "fetchtwomarks", "ffiligature", "ffligature", "fflligature", "fhook", "field", "fieldbody", "fieldstack", "fifthoffivearguments", "fifthofsixarguments", "figurefilename", "figurefilepath", "figurefiletype", "figurefullname", "figureheight", "figurenaturalheight", "figurenaturalwidth", "figurespace", "figuresymbol", "figurewidth", "filename", "filigature", "filledhboxb", "filledhboxc", "filledhboxg", "filledhboxk", "filledhboxm", "filledhboxr", "filledhboxy", "filler", "fillinline", "fillinrules", "fillintext", "filterfromnext", "filterfromvalue", "filterpages", "filterreference", "findtwopassdata", "finishregisterentry", "firstcharacter", "firstcounter", "firstcountervalue", "firstoffivearguments", "firstoffourarguments", "firstofoneargument", "firstofoneunexpanded", "firstofsixarguments", "firstofthreearguments", "firstofthreeunexpanded", "firstoftwoarguments", "firstoftwounexpanded", "firstrealpage", "firstrealpagenumber", "firstsubcountervalue", "firstsubpage", "firstsubpagenumber", "firstuserpage", "firstuserpagenumber", "fitfield", "fitfieldframed", "fittopbaselinegrid", "fiveeighths", "fivesixths", "fixedspace", "fixedspaces", "flag", "flat", "flligature", "floatuserdataparameter", "flushbox", "flushboxregister", "flushcollector", "flushedrightlastline", "flushlayer", "flushlocalfloats", "flushnextbox", "flushnotes", "flushoutputstream", "flushshapebox", "flushtextflow", "flushtokens", "flushtoks", "fontalternative", "fontbody", "fontchar", "fontcharbyindex", "fontclass", "fontclassname", "fontface", "fontfeaturelist", "fontsize", "fontstyle", "footnote", "footnotetext", "forall", "forcecharacterstripping", "forcelocalfloats", "forgeteverypar", "forgetparameters", "forgetragged", "formula", "formulanumber", "foundbox", "fourfifths", "fourperemspace", "fourthoffivearguments", "fourthoffourarguments", "fourthofsixarguments", "frac", "framed", "frameddimension", "framedparameter", "framedtext", "freezedimenmacro", "freezemeasure", "frenchspacing", "from", "fromlinenote", "frown", "frozenhbox", "frule", "gacute", "gamma", "gbreve", "gcaron", "gcircumflex", "gcommaaccent", "gdefconvertedargument", "gdefconvertedcommand", "gdotaccent", "ge", "geq", "geqq", "geqslant", "getMPdrawing", "getMPlayer", "getboxfromcache", "getboxllx", "getboxlly", "getbuffer", "getbufferdata", "getcommacommandsize", "getcommalistsize", "getdayoftheweek", "getdayspermonth", "getdefinedbuffer", "getdocumentargument", "getdocumentargumentdefault", "getdocumentfilename", "getdummyparameters", "getemptyparameters", "geteparameters", "getexpandedparameters", "getfiguredimensions", "getfirstcharacter", "getfirsttwopassdata", "getfromcommacommand", "getfromcommalist", "getfromtwopassdata", "getglyphdirect", "getglyphstyled", "getgparameters", "getlasttwopassdata", "getlocalfloat", "getlocalfloats", "getmarking", "getmessage", "getnamedglyphdirect", "getnamedglyphstyled", "getnamedtwopassdatalist", "getnaturaldimensions", "getnoflines", "getobject", "getobjectdimensions", "getpaletsize", "getparameters", "getprivatechar", "getprivateslot", "getrandomcount", "getrandomdimen", "getrandomfloat", "getrandomnumber", "getrandomseed", "getraweparameters", "getrawgparameters", "getrawnoflines", "getrawparameters", "getrawxparameters", "getreference", "getreferenceentry", "getroundednoflines", "gets", "getsubstring", "gettwopassdata", "gettwopassdatalist", "getuvalue", "getvalue", "getvariable", "getvariabledefault", "getxparameters", "gg", "ggg", "gggtr", "gimel", "globaldisablemode", "globalenablemode", "globalletempty", "globalpopbox", "globalpopmacro", "globalpreventmode", "globalprocesscommalist", "globalpushbox", "globalpushmacro", "globalswapcounts", "globalswapdimens", "globalswapmacros", "globalundefine", "glyphfontfile", "gnapprox", "gneqq", "gnsim", "gobbledoubleempty", "gobbleeightarguments", "gobblefivearguments", "gobblefiveoptionals", "gobblefourarguments", "gobblefouroptionals", "gobbleninearguments", "gobbleoneargument", "gobbleoneoptional", "gobblesevenarguments", "gobblesingleempty", "gobblesixarguments", "gobblespacetokens", "gobbletenarguments", "gobblethreearguments", "gobblethreeoptionals", "gobbletwoarguments", "gobbletwooptionals", "gobbleuntil", "gobbleuntilrelax", "godown", "goto", "gotobox", "gotopage", "grabbufferdata", "grabbufferdatadirect", "grabuntil", "grave", "graycolor", "grayvalue", "greedysplitstring", "greekAlpha", "greekAlphadasia", "greekAlphadasiaperispomeni", "greekAlphadasiatonos", "greekAlphadasiavaria", "greekAlphaiotasub", "greekAlphaiotasubdasia", "greekAlphaiotasubdasiaperispomeni", "greekAlphaiotasubdasiatonos", "greekAlphaiotasubdasiavaria", "greekAlphaiotasubpsili", "greekAlphaiotasubpsiliperispomeni", "greekAlphaiotasubpsilitonos", "greekAlphaiotasubpsilivaria", "greekAlphamacron", "greekAlphapsili", "greekAlphapsiliperispomeni", "greekAlphapsilitonos", "greekAlphapsilivaria", "greekAlphatonos", "greekAlphavaria", "greekAlphavrachy", "greekBeta", "greekChi", "greekCoronis", "greekDelta", "greekEpsilon", "greekEpsilondasia", "greekEpsilondasiatonos", "greekEpsilondasiavaria", "greekEpsilonpsili", "greekEpsilonpsilitonos", "greekEpsilonpsilivaria", "greekEpsilontonos", "greekEpsilonvaria", "greekEta", "greekEtadasia", "greekEtadasiaperispomeni", "greekEtadasiatonos", "greekEtadasiavaria", "greekEtaiotasub", "greekEtaiotasubdasia", "greekEtaiotasubdasiaperispomeni", "greekEtaiotasubdasiatonos", "greekEtaiotasubdasiavaria", "greekEtaiotasubpsili", "greekEtaiotasubpsiliperispomeni", "greekEtaiotasubpsilitonos", "greekEtaiotasubpsilivaria", "greekEtapsili", "greekEtapsiliperispomeni", "greekEtapsilitonos", "greekEtapsilivaria", "greekEtatonos", "greekEtavaria", "greekGamma", "greekIota", "greekIotadasia", "greekIotadasiaperispomeni", "greekIotadasiatonos", "greekIotadasiavaria", "greekIotadialytika", "greekIotamacron", "greekIotapsili", "greekIotapsiliperispomeni", "greekIotapsilitonos", "greekIotapsilivaria", "greekIotatonos", "greekIotavaria", "greekIotavrachy", "greekKappa", "greekLambda", "greekMu", "greekNu", "greekOmega", "greekOmegadasia", "greekOmegadasiaperispomeni", "greekOmegadasiatonos", "greekOmegadasiavaria", "greekOmegaiotasub", "greekOmegaiotasubdasia", "greekOmegaiotasubdasiaperispomeni", "greekOmegaiotasubdasiatonos", "greekOmegaiotasubdasiavaria", "greekOmegaiotasubpsili", "greekOmegaiotasubpsiliperispomeni", "greekOmegaiotasubpsilitonos", "greekOmegaiotasubpsilivaria", "greekOmegapsili", "greekOmegapsiliperispomeni", "greekOmegapsilitonos", "greekOmegapsilivaria", "greekOmegatonos", "greekOmegavaria", "greekOmicron", "greekOmicrondasia", "greekOmicrondasiatonos", "greekOmicrondasiavaria", "greekOmicronpsili", "greekOmicronpsilitonos", "greekOmicronpsilivaria", "greekOmicrontonos", "greekOmicronvaria", "greekPhi", "greekPi", "greekPsi", "greekRho", "greekRhodasia", "greekSigma", "greekSigmalunate", "greekTau", "greekTheta", "greekUpsilon", "greekUpsilondasia", "greekUpsilondasiaperispomeni", "greekUpsilondasiatonos", "greekUpsilondasiavaria", "greekUpsilondialytika", "greekUpsilonmacron", "greekUpsilontonos", "greekUpsilonvaria", "greekUpsilonvrachy", "greekXi", "greekZeta", "greekalpha", "greekalphadasia", "greekalphadasiaperispomeni", "greekalphadasiatonos", "greekalphadasiavaria", "greekalphaiotasub", "greekalphaiotasubdasia", "greekalphaiotasubdasiaperispomeni", "greekalphaiotasubdasiatonos", "greekalphaiotasubdasiavaria", "greekalphaiotasubperispomeni", "greekalphaiotasubpsili", "greekalphaiotasubpsiliperispomeni", "greekalphaiotasubpsilitonos", "greekalphaiotasubpsilivaria", "greekalphaiotasubtonos", "greekalphaiotasubvaria", "greekalphamacron", "greekalphaoxia", "greekalphaperispomeni", "greekalphapsili", "greekalphapsiliperispomeni", "greekalphapsilitonos", "greekalphapsilivaria", "greekalphatonos", "greekalphavaria", "greekalphavrachy", "greekbeta", "greekchi", "greekdasia", "greekdasiaperispomeni", "greekdasiatonos", "greekdasiavaria", "greekdelta", "greekdialytikaperispomeni", "greekdialytikatonos", "greekdialytikavaria", "greekdigamma", "greekepsilon", "greekepsilonalt", "greekepsilondasia", "greekepsilondasiatonos", "greekepsilondasiavaria", "greekepsilonoxia", "greekepsilonpsili", "greekepsilonpsilitonos", "greekepsilonpsilivaria", "greekepsilontonos", "greekepsilonvaria", "greeketa", "greeketadasia", "greeketadasiaperispomeni", "greeketadasiatonos", "greeketadasiavaria", "greeketaiotasub", "greeketaiotasubdasia", "greeketaiotasubdasiaperispomeni", "greeketaiotasubdasiatonos", "greeketaiotasubdasiavaria", "greeketaiotasubperispomeni", "greeketaiotasubpsili", "greeketaiotasubpsiliperispomeni", "greeketaiotasubpsilitonos", "greeketaiotasubpsilivaria", "greeketaiotasubtonos", "greeketaiotasubvaria", "greeketaoxia", "greeketaperispomeni", "greeketapsili", "greeketapsiliperispomeni", "greeketapsilitonos", "greeketapsilivaria", "greeketatonos", "greeketavaria", "greekfinalsigma", "greekgamma", "greekiota", "greekiotadasia", "greekiotadasiaperispomeni", "greekiotadasiatonos", "greekiotadasiavaria", "greekiotadialytika", "greekiotadialytikaperispomeni", "greekiotadialytikatonos", "greekiotadialytikavaria", "greekiotamacron", "greekiotaoxia", "greekiotaperispomeni", "greekiotapsili", "greekiotapsiliperispomeni", "greekiotapsilitonos", "greekiotapsilivaria", "greekiotatonos", "greekiotavaria", "greekiotavrachy", "greekkappa", "greekkoppa", "greeklambda", "greekmu", "greeknu", "greeknumerals", "greeknumkoppa", "greekomega", "greekomegadasia", "greekomegadasiaperispomeni", "greekomegadasiatonos", "greekomegadasiavaria", "greekomegaiotasub", "greekomegaiotasubdasia", "greekomegaiotasubdasiaperispomeni", "greekomegaiotasubdasiatonos", "greekomegaiotasubdasiavaria", "greekomegaiotasubperispomeni", "greekomegaiotasubpsili", "greekomegaiotasubpsiliperispomeni", "greekomegaiotasubpsilitonos", "greekomegaiotasubpsilivaria", "greekomegaiotasubtonos", "greekomegaiotasubvaria", "greekomegaoxia", "greekomegaperispomeni", "greekomegapsili", "greekomegapsiliperispomeni", "greekomegapsilitonos", "greekomegapsilivaria", "greekomegatonos", "greekomegavaria", "greekomicron", "greekomicrondasia", "greekomicrondasiatonos", "greekomicrondasiavaria", "greekomicronoxia", "greekomicronpsili", "greekomicronpsilitonos", "greekomicronpsilivaria", "greekomicrontonos", "greekomicronvaria", "greekoxia", "greekperispomeni", "greekphi", "greekphialt", "greekpi", "greekpialt", "greekprosgegrammeni", "greekpsi", "greekpsili", "greekpsiliperispomeni", "greekpsilitonos", "greekpsilivaria", "greekrho", "greekrhoalt", "greekrhodasia", "greekrhopsili", "greeksampi", "greeksigma", "greeksigmalunate", "greekstigma", "greektau", "greektheta", "greekthetaalt", "greektonos", "greekupsilon", "greekupsilondasia", "greekupsilondasiaperispomeni", "greekupsilondasiatonos", "greekupsilondasiavaria", "greekupsilondiaeresis", "greekupsilondialytikaperispomeni", "greekupsilondialytikatonos", "greekupsilondialytikavaria", "greekupsilonmacron", "greekupsilonoxia", "greekupsilonperispomeni", "greekupsilonpsili", "greekupsilonpsiliperispomeni", "greekupsilonpsilitonos", "greekupsilonpsilivaria", "greekupsilontonos", "greekupsilonvaria", "greekupsilonvrachy", "greekvaria", "greekxi", "greekzeta", "grid", "groupedcommand", "gsetboxllx", "gsetboxlly", "gstroke", "gt", "gtrapprox", "gtrdot", "gtreqless", "gtreqqless", "gtrless", "gtrsim", "guilsingleleft", "guilsingleright", "gujaratinumerals", "gurmurkhinumerals", "hairline", "hairspace", "halflinestrut", "halfstrut", "halfwaybox", "handletokens", "handwritten", "hangul", "hanzi", "hash", "hat", "hbar", "hboxofvbox", "hboxreference", "hcaron", "hcircumflex", "hdofstring", "headhbox", "headlanguage", "headnumber", "headnumbercontent", "headnumberdistance", "headnumberwidth", "headreferenceattributes", "headsetupspacing", "headtext", "headtextcontent", "headtextdistance", "headtexts", "headtextwidth", "headvbox", "headwidth", "heartsuit", "hebrewAlef", "hebrewAyin", "hebrewBet", "hebrewDalet", "hebrewGimel", "hebrewHe", "hebrewHet", "hebrewKaf", "hebrewKaffinal", "hebrewLamed", "hebrewMem", "hebrewMemfinal", "hebrewNun", "hebrewNunfinal", "hebrewPe", "hebrewPefinal", "hebrewQof", "hebrewResh", "hebrewSamekh", "hebrewShin", "hebrewTav", "hebrewTet", "hebrewTsadi", "hebrewTsadifinal", "hebrewVav", "hebrewYod", "hebrewZayin", "heightanddepthofstring", "heightofstring", "heightspanningtext", "helptext", "hglue", "hiddenbar", "hiddencitation", "hiddencite", "hideblocks", "high", "highlight", "highordinalstr", "hilo", "himilo", "hl", "hookleftarrow", "hookrightarrow", "horizontalgrowingbar", "horizontalpositionbar", "hphantom", "hpos", "hsizefraction", "hslash", "hsmash", "hsmashbox", "hsmashed", "hspace", "hstroke", "htdpofstring", "htofstring", "hyphen", "hyphenatedcoloredword", "hyphenatedfile", "hyphenatedfilename", "hyphenatedhbox", "hyphenatedpar", "hyphenatedurl", "hyphenatedword", "iacute", "ibox", "ibreve", "icaron", "icircumflex", "ideographichalffillspace", "ideographicspace", "idiaeresis", "idotaccent", "idotbelow", "idoublegrave", "ifassignment", "iff", "ifinobject", "ifinoutputstream", "ifparameters", "iftrialtypesetting", "ignoreimplicitspaces", "ignorevalue", "igrave", "ihook", "iiiint", "iiiintop", "iiint", "iiintop", "iint", "iintop", "iinvertedbreve", "ijligature", "imacron", "imaginaryi", "imaginaryj", "imath", "immediatesavetwopassdata", "impliedby", "implies", "imply", "in", "includemenu", "includeversioninfo", "increment", "incrementcounter", "incrementedcounter", "incrementpagenumber", "incrementsubpagenumber", "incrementvalue", "indentation", "index", "infofont", "infofontbold", "inframed", "infty", "infull", "inheritparameter", "inhibitblank", "ininner", "ininneredge", "ininnermargin", "initializeboxstack", "inleft", "inleftedge", "inleftmargin", "inline", "inlinebuffer", "inlinedbox", "inlinemath", "inlinemathematics", "inlinemessage", "inlineordisplaymath", "inlineprettyprintbuffer", "inlinerange", "inmargin", "inmframed", "innerflushshapebox", "inother", "inouter", "inouteredge", "inoutermargin", "input", "inputfilebarename", "inputfilename", "inputfilerealsuffix", "inputfilesuffix", "inputgivenfile", "inright", "inrightedge", "inrightmargin", "insertpages", "installactionhandler", "installactivecharacter", "installanddefineactivecharacter", "installattributestack", "installautocommandhandler", "installautosetuphandler", "installbasicautosetuphandler", "installbasicparameterhandler", "installbottomframerenderer", "installcommandhandler", "installcorenamespace", "installdefinehandler", "installdefinitionset", "installdefinitionsetmember", "installdirectcommandhandler", "installdirectparameterhandler", "installdirectparametersethandler", "installdirectsetuphandler", "installdirectstyleandcolorhandler", "installframedautocommandhandler", "installframedcommandhandler", "installlanguage", "installleftframerenderer", "installnamespace", "installoutputroutine", "installpagearrangement", "installparameterhandler", "installparameterhashhandler", "installparametersethandler", "installparentinjector", "installrightframerenderer", "installrootparameterhandler", "installsetuphandler", "installsetuponlycommandhandler", "installshipoutmethod", "installsimplecommandhandler", "installsimpleframedcommandhandler", "installstyleandcolorhandler", "installswitchcommandhandler", "installswitchsetuphandler", "installtexdirective", "installtextracker", "installtopframerenderer", "installunitsseparator", "installunitsspace", "installversioninfo", "int", "intclockwise", "integerrounding", "integers", "interactionbar", "interactionbuttons", "interactionmenu", "intercal", "intertext", "intop", "invisibletimes", "invokepageheandler", "iogonek", "iota", "istltdir", "istrtdir", "italic", "italicbold", "italiccorrection", "italicface", "item", "items", "itemtag", "itilde", "jcaron", "jcircumflex", "jmath", "jobfilename", "jobfilesuffix", "kap", "kappa", "kcaron", "kcommaaccent", "keepblocks", "keeplinestogether", "keepunwantedspaces", "kerncharacters", "khook", "kkra", "koreancirclenumerals", "koreannumerals", "koreannumeralsc", "koreannumeralsp", "koreanparentnumerals", "lVert", "labellanguage", "labeltext", "labeltexts", "lacute", "lambda", "lambdabar", "land", "langle", "language", "languageCharacters", "languagecharacters", "languagecharwidth", "lastcounter", "lastcountervalue", "lastdigit", "lastlinewidth", "lastnaturalboxdp", "lastnaturalboxht", "lastnaturalboxwd", "lastpredefinedsymbol", "lastrealpage", "lastrealpagenumber", "lastsubcountervalue", "lastsubpage", "lastsubpagenumber", "lasttwodigits", "lastuserpage", "lastuserpagenumber", "lateluacode", "latin", "layeredtext", "layerheight", "layerwidth", "lazysavetaggedtwopassdata", "lazysavetwopassdata", "lbar", "lbox", "lbrace", "lbracket", "lcaron", "lceil", "lcommaaccent", "lcurl", "ldotmiddle", "ldotp", "ldots", "le", "leadsto", "left", "leftaligned", "leftarrow", "leftarrowtail", "leftarrowtriangle", "leftbottombox", "leftbox", "leftdasharrow", "leftguillemot", "leftharpoondown", "leftharpoonup", "lefthbox", "leftheadtext", "leftlabeltext", "leftleftarrows", "leftline", "leftmathlabeltext", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "leftrightarrow", "leftrightarrows", "leftrightarrowtriangle", "leftrightharpoons", "leftrightsquigarrow", "leftskipadaption", "leftsquigarrow", "leftsubguillemot", "leftthreetimes", "lefttopbox", "lefttoright", "lefttorighthbox", "lefttorightvbox", "lefttorightvtop", "leftwavearrow", "leftwhitearrow", "leq", "leqq", "leqslant", "lessapprox", "lessdot", "lesseqgtr", "lesseqqgtr", "lessgtr", "lesssim", "letbeundefined", "letcatcodecommand", "letcscsname", "letcsnamecs", "letcsnamecsname", "letdummyparameter", "letempty", "letgvalue", "letgvalueempty", "letgvalurelax", "letterampersand", "letterat", "letterbackslash", "letterbar", "letterbgroup", "letterclosebrace", "lettercolon", "letterdollar", "letterdoublequote", "letteregroup", "letterescape", "letterexclamationmark", "letterhash", "letterhat", "letterleftbrace", "letterleftbracket", "letterleftparenthesis", "letterless", "lettermore", "letteropenbrace", "letterpercent", "letterquestionmark", "letterrightbrace", "letterrightbracket", "letterrightparenthesis", "lettersinglequote", "letterslash", "letterspacing", "lettertilde", "letterunderscore", "letvalue", "letvalueempty", "letvaluerelax", "lfence", "lfloor", "lgroup", "lhbox", "lhooknwarrow", "lhooksearrow", "limitatefirstline", "limitatelines", "limitatetext", "line", "linefeed", "linenote", "linespanningtext", "linethickness", "linterval", "listcitation", "listcite", "listlength", "listnamespaces", "ljligature", "ll", "llangle", "llap", "llbracket", "llcorner", "lll", "llless", "lmoustache", "lnapprox", "lneq", "lneqq", "lnot", "lnsim", "loadanyfile", "loadanyfileonce", "loadbtxdefinitionfile", "loadbtxreplacementfile", "loadcldfile", "loadcldfileonce", "loadfontgoodies", "loadluafile", "loadluafileonce", "loadspellchecklist", "loadtexfile", "loadtexfileonce", "loadtypescriptfile", "localframed", "localframedwithsettings", "localhsize", "localpopbox", "localpopmacro", "localpushbox", "localpushmacro", "localundefine", "locatedfilepath", "locatefilepath", "locfilename", "logo", "lohi", "lointerval", "lomihi", "longleftarrow", "longleftrightarrow", "longmapsfrom", "longmapsto", "longrightarrow", "longrightsquigarrow", "looparrowleft", "looparrowright", "lor", "low", "lowerbox", "lowercased", "lowercasestring", "lowerleftdoubleninequote", "lowerleftsingleninequote", "lowerrightdoubleninequote", "lowerrightsingleninequote", "lozenge", "lparent", "lrcorner", "lrointerval", "lrtbbox", "lstroke", "lt", "ltimes", "ltop", "luaTeX", "luacode", "luaconditional", "luaenvironment", "luaexpanded", "luaexpr", "luafunction", "luajitTeX", "luamajorversion", "luaminorversion", "luaparameterset", "luasetup", "luaversion", "lvert", "m", "mLeftarrow", "mLeftrightarrow", "mRightarrow", "mainlanguage", "makecharacteractive", "makerawcommalist", "makestrutofbox", "maltese", "mapfontsize", "mapsdown", "mapsfrom", "mapsto", "mapsup", "margindata", "margintext", "markcontent", "marking", "markinjector", "markpage", "mat", "math", "mathampersand", "mathbf", "mathbi", "mathblackboard", "mathbs", "mathdefault", "mathdollar", "mathdouble", "mathematics", "mathfraktur", "mathfunction", "mathhash", "mathhyphen", "mathit", "mathitalic", "mathlabellanguage", "mathlabeltext", "mathlabeltexts", "mathop", "mathover", "mathpercent", "mathrm", "mathscript", "mathsl", "mathss", "mathtext", "mathtextbf", "mathtextbi", "mathtextbs", "mathtextit", "mathtextsl", "mathtexttf", "mathtf", "mathtriplet", "mathtt", "mathunder", "mathupright", "mathword", "mathwordbf", "mathwordbi", "mathwordbs", "mathwordit", "mathwordsl", "mathwordtf", "maxaligned", "mbox", "mcframed", "measure", "measured", "measuredangle", "measuredeq", "medskip", "medspace", "menubutton", "mequal", "message", "metaTeX", "mfence", "mframed", "mfunction", "mfunctionlabeltext", "mhbox", "mho", "mhookleftarrow", "mhookrightarrow", "mid", "midaligned", "middle", "middlealigned", "middlebox", "midhbox", "minimalhbox", "minus", "minuscolon", "mirror", "mixedcaps", "mkvibuffer", "mleftarrow", "mleftharpoondown", "mleftharpoonup", "mleftrightarrow", "mleftrightharpoons", "mmapsto", "models", "moduleparameter", "molecule", "mono", "monobold", "mononormal", "month", "monthlong", "monthshort", "mp", "mprandomnumber", "mrel", "mrightarrow", "mrightharpoondown", "mrightharpoonup", "mrightleftharpoons", "mrightoverleftarrow", "mtext", "mtriplerel", "mtwoheadleftarrow", "mtwoheadrightarrow", "mu", "multimap", "nHdownarrow", "nHuparrow", "nLeftarrow", "nLeftrightarrow", "nRightarrow", "nVDash", "nVdash", "nVleftarrow", "nVleftrightarrow", "nVrightarrow", "nabla", "nacute", "namedheadnumber", "namedstructureheadlocation", "namedstructureuservariable", "namedstructurevariable", "namedtaggedlabeltexts", "napostrophe", "napprox", "napproxEq", "narrownobreakspace", "nasymp", "natural", "naturalhbox", "naturalhpack", "naturalnumbers", "naturalvbox", "naturalvcenter", "naturalvpack", "naturalvtop", "naturalwd", "ncaron", "ncommaaccent", "ncong", "ncurl", "ndivides", "ne", "nearrow", "neg", "negatecolorbox", "negated", "negativesign", "negthinspace", "neng", "neq", "nequiv", "neswarrow", "newattribute", "newcatcodetable", "newcounter", "newevery", "newfrenchspacing", "newmode", "newsignal", "newsystemmode", "nexists", "nextbox", "nextboxdp", "nextboxht", "nextboxhtdp", "nextboxwd", "nextcounter", "nextcountervalue", "nextdepth", "nextparagraphs", "nextrealpage", "nextrealpagenumber", "nextsubcountervalue", "nextsubpage", "nextsubpagenumber", "nextuserpage", "nextuserpagenumber", "ngeq", "ngrave", "ngtr", "ngtrless", "ngtrsim", "ni", "nihongo", "nin", "njligature", "nleftarrow", "nleftrightarrow", "nleq", "nless", "nlessgtr", "nlesssim", "nmid", "nni", "nobar", "nobreakspace", "nocap", "nocitation", "nocite", "nodetostring", "noffigurepages", "noflines", "noflocalfloats", "noheaderandfooterlines", "noheightstrut", "noindentation", "noitem", "nonfrenchspacing", "nonmathematics", "normal", "normalboldface", "normalframedwithsettings", "normalitalicface", "normalizebodyfontsize", "normalizedfontsize", "normalizefontdepth", "normalizefontheight", "normalizefontline", "normalizefontwidth", "normalizetextdepth", "normalizetextheight", "normalizetextline", "normalizetextwidth", "normalslantedface", "normaltypeface", "nospace", "not", "note", "notesymbol", "notin", "notopandbottomlines", "notragged", "nowns", "nparallel", "nprec", "npreccurlyeq", "nrightarrow", "nsim", "nsimeq", "nsqsubseteq", "nsqsupseteq", "nsubset", "nsubseteq", "nsucc", "nsucccurlyeq", "nsupset", "nsupseteq", "ntilde", "ntimes", "ntriangleleft", "ntrianglelefteq", "ntriangleright", "ntrianglerighteq", "nu", "numberofpoints", "numbers", "nvDash", "nvdash", "nvleftarrow", "nvleftrightarrow", "nvrightarrow", "nwarrow", "nwsearrow", "oacute", "obeydepth", "objectdepth", "objectheight", "objectmargin", "objectwidth", "obox", "obreve", "ocaron", "ocircumflex", "ocircumflexacute", "ocircumflexdotbelow", "ocircumflexgrave", "ocircumflexhook", "ocircumflextilde", "odiaeresis", "odiaeresismacron", "odot", "odotaccent", "odotaccentmacron", "odotbelow", "odoublegrave", "oeligature", "offset", "offsetbox", "ograve", "ohm", "ohook", "ohorn", "ohornacute", "ohorndotbelow", "ohorngrave", "ohornhook", "ohorntilde", "ohungarumlaut", "oiiint", "oiint", "oint", "ointclockwise", "ointctrclockwise", "oinvertedbreve", "omacron", "omega", "omicron", "ominus", "onedigitrounding", "oneeighth", "onefifth", "onehalf", "onequarter", "onesixth", "onesuperior", "onethird", "oogonek", "oogonekmacron", "operatorlanguage", "operatortext", "oplus", "ordfeminine", "ordinaldaynumber", "ordinalstr", "ordmasculine", "ornamenttext", "oslash", "ostroke", "ostrokeacute", "otilde", "otildemacron", "otimes", "outputfilename", "outputstreambox", "outputstreamcopy", "outputstreamunvbox", "outputstreamunvcopy", "over", "overbar", "overbars", "overbarunderbar", "overbrace", "overbraceunderbrace", "overbracket", "overbracketunderbracket", "overlaybutton", "overlaycolor", "overlaydepth", "overlayfigure", "overlayheight", "overlaylinecolor", "overlaylinewidth", "overlayoffset", "overlayrollbutton", "overlaywidth", "overleftarrow", "overloaderror", "overparent", "overparentunderparent", "overrightarrow", "overset", "overstrike", "overstrikes", "owns", "page", "pagearea", "pagebreak", "pagefigure", "pagegridspanwidth", "pageinjection", "pagenumber", "pagereference", "pagestaterealpage", "paletsize", "paragraphmark", "parallel", "part", "partial", "pdfTeX", "pdfactualtext", "pdfbackendactualtext", "pdfbackendcurrentresources", "pdfbackendsetcatalog", "pdfbackendsetcolorspace", "pdfbackendsetextgstate", "pdfbackendsetinfo", "pdfbackendsetname", "pdfbackendsetpageattribute", "pdfbackendsetpageresource", "pdfbackendsetpagesattribute", "pdfbackendsetpattern", "pdfbackendsetshade", "pdfcolor", "pdfeTeX", "percent", "percentdimen", "periodcentered", "periods", "permitcaretescape", "permitcircumflexescape", "permitspacesbetweengroups", "perp", "persiandecimals", "persiannumerals", "perthousand", "phantom", "phantombox", "phi", "phook", "pi", "pickupgroupedcommand", "pitchfork", "placeattachments", "placebookmarks", "placebtxrendering", "placechemical", "placecitation", "placecombinedlist", "placecomments", "placecontent", "placecurrentformulanumber", "placedbox", "placefigure", "placefloat", "placefloatwithsetups", "placefootnotes", "placeformula", "placeframed", "placegraphic", "placeheadnumber", "placeheadtext", "placehelp", "placeindex", "placeinitial", "placeintermezzo", "placelayer", "placelayeredtext", "placelegend", "placelist", "placelistofabbreviations", "placelistofchemicals", "placelistoffigures", "placelistofgraphics", "placelistofintermezzi", "placelistoflogos", "placelistofpublications", "placelistofsorts", "placelistofsynonyms", "placelistoftables", "placelocalfootnotes", "placelocalnotes", "placement", "placenamedfloat", "placenamedformula", "placenotes", "placeongrid", "placeontopofeachother", "placepagenumber", "placepairedbox", "placeparallel", "placerawlist", "placeregister", "placerenderingwindow", "placesidebyside", "placesubformula", "placetable", "pm", "popattribute", "popmacro", "popmode", "popsystemmode", "position", "positionoverlay", "positionregionoverlay", "positivesign", "postponenotes", "prec", "precapprox", "preccurlyeq", "preceq", "preceqq", "precnapprox", "precneq", "precneqq", "precnsim", "precsim", "predefinedfont", "predefinefont", "predefinesymbol", "prefixedpagenumber", "prefixlanguage", "prefixtext", "prependetoks", "prependgvalue", "prependtocommalist", "prependtoks", "prependtoksonce", "prependvalue", "presetbtxlabeltext", "presetdocument", "presetfieldsymbols", "presetheadtext", "presetlabeltext", "presetmathlabeltext", "presetoperatortext", "presetprefixtext", "presetsuffixtext", "presettaglabeltext", "presetunittext", "pretocommalist", "prettyprintbuffer", "prevcounter", "prevcountervalue", "preventmode", "prevrealpage", "prevrealpagenumber", "prevsubcountervalue", "prevsubpage", "prevsubpagenumber", "prevuserpage", "prevuserpagenumber", "prime", "primes", "procent", "processMPbuffer", "processMPfigurefile", "processaction", "processallactionsinset", "processassignlist", "processassignmentcommand", "processassignmentlist", "processbetween", "processblocks", "processbodyfontenvironmentlist", "processcolorcomponents", "processcommacommand", "processcommalist", "processcommalistwithparameters", "processcontent", "processfile", "processfilemany", "processfilenone", "processfileonce", "processfirstactioninset", "processisolatedchars", "processisolatedwords", "processlinetablebuffer", "processlinetablefile", "processlist", "processmonth", "processranges", "processseparatedlist", "processtexbuffer", "processtokens", "processuntil", "processxtablebuffer", "processyear", "prod", "product", "profiledbox", "profilegivenbox", "program", "project", "propto", "pseudoMixedCapped", "pseudoSmallCapped", "pseudoSmallcapped", "pseudosmallcapped", "psi", "punctuationspace", "purenumber", "pushattribute", "pushbutton", "pushmacro", "pushmode", "pushoutputstream", "pushsystemmode", "putboxincache", "putnextboxincache", "qquad", "quad", "quadrupleprime", "quads", "quarterstrut", "questiondown", "questionedeq", "quitcommalist", "quitprevcommalist", "quittypescriptscanning", "quotation", "quote", "quotedbl", "quotedblbase", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "quotesingle", "quotesinglebase", "rVert", "racute", "raggedbottom", "raggedcenter", "raggedleft", "raggedright", "raggedwidecenter", "raisebox", "randomizetext", "randomnumber", "rangle", "rationals", "rawcounter", "rawcountervalue", "rawdate", "rawdoifelseinset", "rawdoifinset", "rawdoifinsetelse", "rawgetparameters", "rawprocessaction", "rawprocesscommacommand", "rawprocesscommalist", "rawstructurelistuservariable", "rawsubcountervalue", "rbox", "rbrace", "rbracket", "rcaron", "rceil", "rcommaaccent", "rdoublegrave", "readfile", "readfixfile", "readjobfile", "readlocfile", "readsetfile", "readsysfile", "readtexfile", "readxmlfile", "realSmallCapped", "realSmallcapped", "realpagenumber", "reals", "realsmallcapped", "recursedepth", "recurselevel", "recursestring", "redoconvertfont", "ref", "reference", "referenceprefix", "referring", "registerattachment", "registerctxluafile", "registered", "registerexternalfigure", "registerfontclass", "registerhyphenationexception", "registerhyphenationpattern", "registermenubuttons", "registersort", "registersynonym", "registerunit", "regular", "relatemarking", "relateparameterhandlers", "relaxvalueifundefined", "relbar", "remainingcharacters", "remark", "removebottomthings", "removedepth", "removefromcommalist", "removelastskip", "removelastspace", "removemarkedcontent", "removepunctuation", "removesubstring", "removetoks", "removeunwantedspaces", "replacefeature", "replaceincommalist", "replaceword", "rescan", "rescanwithsetup", "resetMPdrawing", "resetMPenvironment", "resetMPinstance", "resetallattributes", "resetandaddfeature", "resetbar", "resetboxesincache", "resetbreakpoints", "resetbuffer", "resetcharacteralign", "resetcharacterkerning", "resetcharacterspacing", "resetcharacterstripping", "resetcollector", "resetcounter", "resetdigitsmanipulation", "resetdirection", "resetfeature", "resetflag", "resetfontcolorsheme", "resetfontfallback", "resetfontsolution", "resethyphenationfeatures", "resetinjector", "resetinteractionmenu", "resetitaliccorrection", "resetlayer", "resetlocalfloats", "resetmarker", "resetmarking", "resetmode", "resetpagenumber", "resetparallel", "resetpath", "resetpenalties", "resetprofile", "resetrecurselevel", "resetreference", "resetreplacement", "resetscript", "resetsetups", "resetshownsynonyms", "resetsubpagenumber", "resetsymbolset", "resetsystemmode", "resettimer", "resettrackers", "resettrialtypesetting", "resetusedsortings", "resetusedsynonyms", "resetuserpagenumber", "resetvalue", "resetvisualizers", "reshapebox", "resolvedglyphdirect", "resolvedglyphstyled", "restartcounter", "restorebox", "restorecatcodes", "restorecounter", "restorecurrentattributes", "restoreendofline", "restoreglobalbodyfont", "restriction", "reusableMPgraphic", "reuseMPgraphic", "reuserandomseed", "reverseddoubleprime", "reversedprime", "reversedtripleprime", "revivefeature", "rfence", "rfloor", "rgroup", "rhbox", "rho", "rhooknearrow", "rhookswarrow", "right", "rightaligned", "rightangle", "rightarrow", "rightarrowbar", "rightarrowtail", "rightarrowtriangle", "rightbottombox", "rightbox", "rightdasharrow", "rightguillemot", "rightharpoondown", "rightharpoonup", "righthbox", "rightheadtext", "rightlabeltext", "rightleftarrows", "rightleftharpoons", "rightline", "rightmathlabeltext", "rightorleftpageaction", "rightrightarrows", "rightskipadaption", "rightsquigarrow", "rightsubguillemot", "rightthreearrows", "rightthreetimes", "righttoleft", "righttolefthbox", "righttoleftvbox", "righttoleftvtop", "righttopbox", "rightwavearrow", "rightwhitearrow", "ring", "rinterval", "rinvertedbreve", "risingdotseq", "rlap", "rlointerval", "rmoustache", "rneq", "robustaddtocommalist", "robustdoifelseinset", "robustdoifinsetelse", "robustpretocommalist", "rointerval", "rollbutton", "roman", "romanC", "romanD", "romanI", "romanII", "romanIII", "romanIV", "romanIX", "romanL", "romanM", "romanV", "romanVI", "romanVII", "romanVIII", "romanX", "romanXI", "romanXII", "romanc", "romand", "romani", "romanii", "romaniii", "romaniv", "romanix", "romanl", "romanm", "romannumerals", "romanv", "romanvi", "romanvii", "romanviii", "romanx", "romanxi", "romanxii", "rootradical", "rotate", "rparent", "rrangle", "rrbracket", "rrointerval", "rtimes", "rtop", "ruledhbox", "ruledhpack", "ruledmbox", "ruledtopv", "ruledtpack", "ruledvbox", "ruledvpack", "ruledvtop", "runMPbuffer", "runninghbox", "rvert", "sacute", "safechar", "samplefile", "sans", "sansbold", "sansnormal", "sansserif", "savebox", "savebtxdataset", "savebuffer", "savecounter", "savecurrentattributes", "savenormalmeaning", "savetaggedtwopassdata", "savetwopassdata", "sbox", "scale", "scaron", "scedilla", "schwa", "schwahook", "scircumflex", "scommaaccent", "screen", "searrow", "secondoffivearguments", "secondoffourarguments", "secondofsixarguments", "secondofthreearguments", "secondofthreeunexpanded", "secondoftwoarguments", "secondoftwounexpanded", "section", "sectionmark", "seeindex", "select", "selectblocks", "serializecommalist", "serializedcommalist", "serif", "serifbold", "serifnormal", "setJSpreamble", "setMPlayer", "setMPpositiongraphic", "setMPpositiongraphicrange", "setMPtext", "setMPvariable", "setMPvariables", "setbar", "setbigbodyfont", "setboxllx", "setboxlly", "setbreakpoints", "setcapstrut", "setcatcodetable", "setcharacteralign", "setcharactercasing", "setcharactercleaning", "setcharacterkerning", "setcharacterspacing", "setcharacterstripping", "setcharstrut", "setcollector", "setcolormodell", "setcounter", "setcounterown", "setcurrentfontclass", "setdataset", "setdefaultpenalties", "setdigitsmanipulation", "setdirection", "setdocumentargument", "setdocumentargumentdefault", "setdocumentfilename", "setdummyparameter", "setelementexporttag", "setemeasure", "setevalue", "setevariable", "setevariables", "setfirstline", "setflag", "setfont", "setfontcolorsheme", "setfontfeature", "setfontsolution", "setfontstrut", "setgmeasure", "setgvalue", "setgvariable", "setgvariables", "sethboxregister", "sethyphenatedurlafter", "sethyphenatedurlbefore", "sethyphenatedurlnormal", "sethyphenationfeatures", "setinitial", "setinjector", "setinteraction", "setinterfacecommand", "setinterfaceconstant", "setinterfaceelement", "setinterfacemessage", "setinterfacevariable", "setinternalrendering", "setitaliccorrection", "setlayer", "setlayerframed", "setlayertext", "setlinefiller", "setlocalhsize", "setmainbodyfont", "setmainparbuilder", "setmarker", "setmarking", "setmathstyle", "setmeasure", "setmessagetext", "setminus", "setmode", "setnostrut", "setnote", "setnotetext", "setobject", "setoldstyle", "setpagegrid", "setpagereference", "setpagestate", "setpagestaterealpageno", "setpenalties", "setpercentdimen", "setposition", "setpositionbox", "setpositiondata", "setpositiondataplus", "setpositiononly", "setpositionplus", "setpositionstrut", "setprofile", "setrandomseed", "setreference", "setreferencedobject", "setregisterentry", "setreplacement", "setrigidcolumnbalance", "setrigidcolumnhsize", "setscript", "setsectionblock", "setsimplecolumnhsize", "setsmallbodyfont", "setsmallcaps", "setstackbox", "setstructurepageregister", "setstrut", "setsuperiors", "setsystemmode", "settabular", "settaggedmetadata", "settextcontent", "settightobject", "settightreferencedobject", "settightunreferencedobject", "settrialtypesetting", "setuevalue", "setugvalue", "setunreferencedobject", "setup", "setupMPgraphics", "setupMPinstance", "setupMPpage", "setupMPvariables", "setupTABLE", "setupTEXpage", "setupalign", "setupalternativestyles", "setuparranging", "setupattachment", "setupattachments", "setupbackend", "setupbackground", "setupbackgrounds", "setupbar", "setupbars", "setupblackrules", "setupblank", "setupbleeding", "setupblock", "setupbodyfont", "setupbookmark", "setupbottom", "setupbottomtexts", "setupbtx", "setupbtxdataset", "setupbtxlabeltext", "setupbtxlist", "setupbtxregister", "setupbtxrendering", "setupbuffer", "setupbutton", "setupcapitals", "setupcaption", "setupcaptions", "setupcharacterkerning", "setupcharacterspacing", "setupchemical", "setupchemicalframed", "setupclipping", "setupcollector", "setupcolor", "setupcolors", "setupcolumns", "setupcolumnspan", "setupcombination", "setupcombinedlist", "setupcomment", "setupcontent", "setupcounter", "setupdataset", "setupdelimitedtext", "setupdescription", "setupdirections", "setupdocument", "setupeffect", "setupenumeration", "setupenumerations", "setupenv", "setupexport", "setupexternalfigure", "setupexternalsoundtracks", "setupfield", "setupfieldbody", "setupfieldcategory", "setupfieldcontentframed", "setupfieldlabelframed", "setupfields", "setupfieldtotalframed", "setupfiller", "setupfillinlines", "setupfillinrules", "setupfirstline", "setupfittingpage", "setupfloat", "setupfloatcaption", "setupfloats", "setupfloatsplitting", "setupfontexpansion", "setupfontprotrusion", "setupfonts", "setupfontsolution", "setupfooter", "setupfootertexts", "setupforms", "setupformula", "setupformulae", "setupformulaframed", "setupframed", "setupframedcontent", "setupframedtable", "setupframedtablecolumn", "setupframedtablerow", "setupframedtext", "setupframedtexts", "setupglobalreferenceprefix", "setuphead", "setupheadalternative", "setupheader", "setupheadertexts", "setupheadnumber", "setupheads", "setupheadtext", "setuphelp", "setuphigh", "setuphighlight", "setuphyphenation", "setuphyphenmark", "setupindentedtext", "setupindenting", "setupindex", "setupinitial", "setupinsertion", "setupinteraction", "setupinteractionbar", "setupinteractionmenu", "setupinteractionscreen", "setupinterlinespace", "setupitaliccorrection", "setupitemgroup", "setupitemizations", "setupitemize", "setupitems", "setuplabel", "setuplabeltext", "setuplanguage", "setuplayer", "setuplayeredtext", "setuplayout", "setuplayouttext", "setuplegend", "setuplinefiller", "setuplinefillers", "setuplinenote", "setuplinenumbering", "setuplines", "setuplinetable", "setuplinewidth", "setuplist", "setuplistalternative", "setuplistextra", "setuplocalfloats", "setuplocalinterlinespace", "setuplow", "setuplowhigh", "setuplowmidhigh", "setupmakeup", "setupmarginblock", "setupmargindata", "setupmarginframed", "setupmarginrule", "setupmarginrules", "setupmarking", "setupmathalignment", "setupmathcases", "setupmathematics", "setupmathfence", "setupmathfraction", "setupmathfractions", "setupmathframed", "setupmathlabeltext", "setupmathmatrix", "setupmathornament", "setupmathradical", "setupmathstackers", "setupmathstyle", "setupmixedcolumns", "setupmodule", "setupnarrower", "setupnotation", "setupnotations", "setupnote", "setupnotes", "setupoffset", "setupoffsetbox", "setupoperatortext", "setupoppositeplacing", "setupoutputroutine", "setuppagechecker", "setuppagecomment", "setuppagegrid", "setuppagegridarea", "setuppagegridareatext", "setuppagegridlines", "setuppagegridspan", "setuppagegridstart", "setuppageinjection", "setuppageinjectionalternative", "setuppagenumber", "setuppagenumbering", "setuppageshift", "setuppagestate", "setuppagetransitions", "setuppairedbox", "setuppalet", "setuppaper", "setuppapersize", "setupparagraph", "setupparagraphintro", "setupparagraphnumbering", "setupparagraphs", "setupparallel", "setupperiods", "setupplacement", "setuppositionbar", "setuppositioning", "setupprefixtext", "setupprocessor", "setupprofile", "setupprograms", "setupquotation", "setupquote", "setuprealpagenumber", "setupreferenceformat", "setupreferenceprefix", "setupreferencestructureprefix", "setupreferencing", "setupregister", "setupregisters", "setuprenderingwindow", "setuprotate", "setups", "setupscale", "setupscript", "setupscripts", "setupsectionblock", "setupselector", "setupshift", "setupsidebar", "setupsorting", "setupspacing", "setupspellchecking", "setupstartstop", "setupstretched", "setupstruts", "setupstyle", "setupsubformula", "setupsubformulas", "setupsubpagenumber", "setupsuffixtext", "setupsymbolset", "setupsynctex", "setupsynonyms", "setuptables", "setuptabulate", "setuptabulation", "setuptagging", "setuptaglabeltext", "setuptext", "setuptextbackground", "setuptextflow", "setuptextrules", "setuptexttexts", "setupthinrules", "setuptolerance", "setuptooltip", "setuptop", "setuptoptexts", "setuptype", "setuptyping", "setupunit", "setupunittext", "setupurl", "setupuserpagenumber", "setupversion", "setupviewerlayer", "setupvspacing", "setupwhitespace", "setupwithargument", "setupwithargumentswapped", "setupxml", "setupxtable", "setuvalue", "setuxvalue", "setvalue", "setvariable", "setvariables", "setvboxregister", "setvisualizerfont", "setvtopregister", "setwidthof", "setxmeasure", "setxvalue", "setxvariable", "setxvariables", "seveneighths", "sfrac", "shapedhbox", "sharp", "shiftdown", "shiftup", "showallmakeup", "showattributes", "showbodyfont", "showbodyfontenvironment", "showboxes", "showbtxdatasetauthors", "showbtxdatasetcompleteness", "showbtxdatasetfields", "showbtxfields", "showbtxhashedauthors", "showbtxtables", "showchardata", "showcharratio", "showcolor", "showcolorbar", "showcolorcomponents", "showcolorgroup", "showcolorset", "showcolorstruts", "showcounter", "showdirectives", "showdirsinmargin", "showedebuginfo", "showexperiments", "showfont", "showfontdata", "showfontitalics", "showfontkerns", "showfontparameters", "showfontstrip", "showfontstyle", "showframe", "showglyphs", "showgrid", "showgridsnapping", "showhelp", "showhyphenationtrace", "showhyphens", "showinjector", "showjustification", "showkerning", "showlayout", "showlayoutcomponents", "showligature", "showligatures", "showlogcategories", "showmakeup", "showmargins", "showmessage", "showminimalbaseline", "shownextbox", "showotfcomposition", "showpalet", "showparentchain", "showprint", "showsetups", "showsetupsdefinition", "showstruts", "showsymbolset", "showtimer", "showtokens", "showtrackers", "showvalue", "showvariable", "showwarning", "sigma", "sim", "simeq", "simplealignedbox", "simplealignedboxplus", "simplealignedspreadbox", "simplegroupedcommand", "simplereversealignedbox", "simplereversealignedboxplus", "singalcharacteralign", "singlebond", "singleverticalbar", "sixperemspace", "sixthofsixarguments", "slanted", "slantedbold", "slantedface", "slash", "slicepages", "slong", "slovenianNumerals", "sloveniannumerals", "small", "smallbodyfont", "smallbold", "smallbolditalic", "smallboldslanted", "smallcappedcharacters", "smallcappedromannumerals", "smaller", "smallitalicbold", "smallnormal", "smallskip", "smallslanted", "smallslantedbold", "smalltype", "smash", "smashbox", "smashboxed", "smashedhbox", "smashedvbox", "smile", "snaptogrid", "softhyphen", "solidus", "someheadnumber", "somekindoftab", "someline", "somelocalfloat", "somenamedheadnumber", "someplace", "somewhere", "space", "spadesuit", "spanishNumerals", "spanishnumerals", "speech", "sphericalangle", "splitatasterisk", "splitatcolon", "splitatcolons", "splitatcomma", "splitatperiod", "splitdfrac", "splitfilename", "splitfloat", "splitfrac", "splitoffbase", "splitofffull", "splitoffkind", "splitoffname", "splitoffpath", "splitoffroot", "splitofftokens", "splitofftype", "splitstring", "spreadhbox", "sqcap", "sqcup", "sqrt", "sqsubset", "sqsubseteq", "sqsubsetneq", "sqsupset", "sqsupseteq", "sqsupsetneq", "square", "squaredots", "ssharp", "stackrel", "star", "stareq", "startJScode", "startJSpreamble", "startLUA", "startMP", "startMPclip", "startMPcode", "startMPdefinitions", "startMPdrawing", "startMPenvironment", "startMPextensions", "startMPinclusions", "startMPinitializations", "startMPpage", "startMPpositiongraphic", "startMPpositionmethod", "startMPrun", "startPARSEDXML", "startTABLE", "startTABLEbody", "startTABLEfoot", "startTABLEhead", "startTABLEnext", "startTC", "startTD", "startTDs", "startTEX", "startTEXpage", "startTH", "startTN", "startTR", "startTRs", "startTX", "startTY", "startXML", "startalign", "startalignment", "startallmodes", "startappendices", "startarrangedpages", "startaside", "startattachment", "startbackground", "startbackmatter", "startbar", "startbbordermatrix", "startbitmapimage", "startblockquote", "startbodymatter", "startbordermatrix", "startboxedcolumns", "startbtxlabeltext", "startbtxrenderingdefinitions", "startbuffer", "startcases", "startcatcodetable", "startcenteraligned", "startchapter", "startcharacteralign", "startcheckedfences", "startchemical", "startchemicaltext", "startcollect", "startcollecting", "startcolor", "startcolorintent", "startcoloronly", "startcolorset", "startcolumns", "startcolumnspan", "startcombination", "startcomment", "startcomponent", "startcontextcode", "startcontextdefinitioncode", "startctxfunction", "startctxfunctiondefinition", "startcurrentcolor", "startcurrentlistentrywrapper", "startdelimited", "startdelimitedtext", "startdisplaymath", "startdmath", "startdocument", "starteffect", "startelement", "startembeddedxtable", "startendnote", "startendofline", "startenvironment", "startexceptions", "startexpanded", "startexpandedcollect", "startextendedcatcodetable", "startexternalfigurecollection", "startfact", "startfigure", "startfiguretext", "startfittingpage", "startfixed", "startfloatcombination", "startfont", "startfontclass", "startfontsolution", "startfootnote", "startformula", "startformulas", "startframed", "startframedcell", "startframedcontent", "startframedrow", "startframedtable", "startframedtext", "startfrontmatter", "startgoto", "startgraphictext", "startgridsnapping", "starthanging", "starthbox", "starthboxestohbox", "starthboxregister", "starthead", "startheadtext", "starthelptext", "starthiding", "starthighlight", "starthyphenation", "startimath", "startindentation", "startindentedtext", "startinteraction", "startinteractionmenu", "startinterface", "startintermezzotext", "startintertext", "startitem", "startitemgroup", "startitemgroupcolumns", "startitemize", "startknockout", "startlabeltext", "startlayout", "startleftaligned", "startlegend", "startline", "startlinealignment", "startlinecorrection", "startlinefiller", "startlinenote", "startlinenumbering", "startlines", "startlinetable", "startlinetablebody", "startlinetablecell", "startlinetablehead", "startlocalfootnotes", "startlocalheadsetup", "startlocallinecorrection", "startlocalnotes", "startlocalsetups", "startlua", "startluacode", "startluaparameterset", "startluasetups", "startmakeup", "startmarginblock", "startmarginrule", "startmarkedcontent", "startmathalignment", "startmathcases", "startmathlabeltext", "startmathmatrix", "startmathmode", "startmathstyle", "startmatrices", "startmatrix", "startmaxaligned", "startmdformula", "startmidaligned", "startmiddlealigned", "startmiddlemakeup", "startmixedcolumns", "startmode", "startmodeset", "startmodule", "startmoduletestsection", "startmpformula", "startnamedsection", "startnamedsubformulas", "startnarrow", "startnarrower", "startnegative", "startnicelyfilledbox", "startnointerference", "startnotallmodes", "startnotext", "startnotmode", "startoperatortext", "startopposite", "startoutputstream", "startoverlay", "startoverprint", "startpacked", "startpagecomment", "startpagefigure", "startpagegrid", "startpagegridspan", "startpagelayout", "startpagemakeup", "startpar", "startparagraph", "startparagraphs", "startparagraphscell", "startparbuilder", "startpart", "startpath", "startplacechemical", "startplacefigure", "startplacefloat", "startplaceformula", "startplacegraphic", "startplaceintermezzo", "startplacelegend", "startplacepairedbox", "startplacetable", "startpositioning", "startpositionoverlay", "startpositive", "startpostponing", "startprefixtext", "startprocessassignmentcommand", "startprocessassignmentlist", "startprocesscommacommand", "startprocesscommalist", "startproduct", "startproject", "startprotect", "startprotectedcolors", "startpublication", "startpunctuation", "startquotation", "startquote", "startrandomized", "startrandomseed", "startrawsetups", "startreadingfile", "startreferenceprefix", "startregime", "startregister", "startreusableMPgraphic", "startrightaligned", "startscript", "startsdformula", "startsection", "startsectionblock", "startsectionblockenvironment", "startsectionlevel", "startsetups", "startshapebox", "startshift", "startsidebar", "startsimplecolumns", "startspecialitem", "startspeech", "startspformula", "startspread", "startstandardmakeup", "startstartstop", "startstaticMPfigure", "startstaticMPgraphic", "startstrictinspectnextcharacter", "startstructurepageregister", "startstrut", "startstyle", "startsubformulas", "startsubject", "startsubjectlevel", "startsubsection", "startsubsentence", "startsubstack", "startsubsubject", "startsubsubsection", "startsubsubsubject", "startsubsubsubsection", "startsubsubsubsubject", "startsubsubsubsubsection", "startsubsubsubsubsubject", "startsuffixtext", "startsymbolset", "starttable", "starttablehead", "starttables", "starttabletail", "starttabletext", "starttabulate", "starttabulatehead", "starttabulatetail", "starttagged", "starttaglabeltext", "starttexcode", "starttexdefinition", "starttext", "starttextbackground", "starttextbackgroundmanual", "starttextcolor", "starttextcolorintent", "starttextflow", "starttextmakeup", "starttextrule", "starttitle", "starttokens", "starttransparent", "starttypescript", "starttypescriptcollection", "starttyping", "startuniqueMPgraphic", "startuniqueMPpagegraphic", "startunittext", "startunpacked", "startusableMPgraphic", "startuseMPgraphic", "startusemathstyleparameter", "startusingbtxspecification", "startvbox", "startvboxregister", "startvboxtohbox", "startvboxtohboxseparator", "startviewerlayer", "startvtop", "startvtopregister", "startxcell", "startxcellgroup", "startxgroup", "startxmldisplayverbatim", "startxmlinlineverbatim", "startxmlraw", "startxmlsetups", "startxrow", "startxrowgroup", "startxtable", "startxtablebody", "startxtablefoot", "startxtablehead", "startxtablenext", "stligature", "stopJScode", "stopJSpreamble", "stopLUA", "stopMP", "stopMPclip", "stopMPcode", "stopMPdefinitions", "stopMPdrawing", "stopMPenvironment", "stopMPextensions", "stopMPinclusions", "stopMPinitializations", "stopMPpage", "stopMPpositiongraphic", "stopMPpositionmethod", "stopMPrun", "stopPARSEDXML", "stopTABLE", "stopTABLEbody", "stopTABLEfoot", "stopTABLEhead", "stopTABLEnext", "stopTC", "stopTD", "stopTDs", "stopTEX", "stopTEXpage", "stopTH", "stopTN", "stopTR", "stopTRs", "stopTX", "stopTY", "stopXML", "stopalign", "stopalignment", "stopallmodes", "stopappendices", "stoparrangedpages", "stopaside", "stopattachment", "stopbackground", "stopbackmatter", "stopbar", "stopbbordermatrix", "stopbitmapimage", "stopblockquote", "stopbodymatter", "stopbordermatrix", "stopboxedcolumns", "stopbtxlabeltext", "stopbtxrenderingdefinitions", "stopbuffer", "stopcases", "stopcatcodetable", "stopcenteraligned", "stopchapter", "stopcharacteralign", "stopcheckedfences", "stopchemical", "stopchemicaltext", "stopcollect", "stopcollecting", "stopcolor", "stopcolorintent", "stopcoloronly", "stopcolorset", "stopcolumns", "stopcolumnspan", "stopcombination", "stopcomment", "stopcomponent", "stopcontextcode", "stopcontextdefinitioncode", "stopctxfunction", "stopctxfunctiondefinition", "stopcurrentcolor", "stopcurrentlistentrywrapper", "stopdelimited", "stopdelimitedtext", "stopdisplaymath", "stopdmath", "stopdocument", "stopeffect", "stopelement", "stopembeddedxtable", "stopendnote", "stopendofline", "stopenvironment", "stopexceptions", "stopexpanded", "stopexpandedcollect", "stopextendedcatcodetable", "stopexternalfigurecollection", "stopfact", "stopfigure", "stopfiguretext", "stopfittingpage", "stopfixed", "stopfloatcombination", "stopfont", "stopfontclass", "stopfontsolution", "stopfootnote", "stopformula", "stopformulas", "stopframed", "stopframedcell", "stopframedcontent", "stopframedrow", "stopframedtable", "stopframedtext", "stopfrontmatter", "stopgoto", "stopgraphictext", "stopgridsnapping", "stophanging", "stophbox", "stophboxestohbox", "stophboxregister", "stophead", "stopheadtext", "stophelptext", "stophiding", "stophighlight", "stophyphenation", "stopimath", "stopindentation", "stopindentedtext", "stopinteraction", "stopinteractionmenu", "stopinterface", "stopintermezzotext", "stopintertext", "stopitem", "stopitemgroup", "stopitemgroupcolumns", "stopitemize", "stopknockout", "stoplabeltext", "stoplayout", "stopleftaligned", "stoplegend", "stopline", "stoplinealignment", "stoplinecorrection", "stoplinefiller", "stoplinenote", "stoplinenumbering", "stoplines", "stoplinetable", "stoplinetablebody", "stoplinetablecell", "stoplinetablehead", "stoplocalfootnotes", "stoplocalheadsetup", "stoplocallinecorrection", "stoplocalnotes", "stoplocalsetups", "stoplua", "stopluacode", "stopluaparameterset", "stopluasetups", "stopmakeup", "stopmarginblock", "stopmarginrule", "stopmarkedcontent", "stopmathalignment", "stopmathcases", "stopmathlabeltext", "stopmathmatrix", "stopmathmode", "stopmathstyle", "stopmatrices", "stopmatrix", "stopmaxaligned", "stopmdformula", "stopmidaligned", "stopmiddlealigned", "stopmiddlemakeup", "stopmixedcolumns", "stopmode", "stopmodeset", "stopmodule", "stopmoduletestsection", "stopmpformula", "stopnamedsection", "stopnamedsubformulas", "stopnarrow", "stopnarrower", "stopnegative", "stopnicelyfilledbox", "stopnointerference", "stopnotallmodes", "stopnotext", "stopnotmode", "stopoperatortext", "stopopposite", "stopoutputstream", "stopoverlay", "stopoverprint", "stoppacked", "stoppagecomment", "stoppagefigure", "stoppagegrid", "stoppagegridspan", "stoppagelayout", "stoppagemakeup", "stoppar", "stopparagraph", "stopparagraphs", "stopparagraphscell", "stopparbuilder", "stoppart", "stoppath", "stopplacechemical", "stopplacefigure", "stopplacefloat", "stopplaceformula", "stopplacegraphic", "stopplaceintermezzo", "stopplacelegend", "stopplacepairedbox", "stopplacetable", "stoppositioning", "stoppositionoverlay", "stoppositive", "stoppostponing", "stopprefixtext", "stopprocessassignmentcommand", "stopprocessassignmentlist", "stopprocesscommacommand", "stopprocesscommalist", "stopproduct", "stopproject", "stopprotect", "stopprotectedcolors", "stoppublication", "stoppunctuation", "stopquotation", "stopquote", "stoprandomized", "stoprandomseed", "stoprawsetups", "stopreadingfile", "stopreferenceprefix", "stopregime", "stopregister", "stopreusableMPgraphic", "stoprightaligned", "stopscript", "stopsdformula", "stopsection", "stopsectionblock", "stopsectionblockenvironment", "stopsectionlevel", "stopsetups", "stopshapebox", "stopshift", "stopsidebar", "stopsimplecolumns", "stopspecialitem", "stopspeech", "stopspformula", "stopspread", "stopstandardmakeup", "stopstartstop", "stopstaticMPfigure", "stopstaticMPgraphic", "stopstrictinspectnextcharacter", "stopstructurepageregister", "stopstrut", "stopstyle", "stopsubformulas", "stopsubject", "stopsubjectlevel", "stopsubsection", "stopsubsentence", "stopsubstack", "stopsubsubject", "stopsubsubsection", "stopsubsubsubject", "stopsubsubsubsection", "stopsubsubsubsubject", "stopsubsubsubsubsection", "stopsubsubsubsubsubject", "stopsuffixtext", "stopsymbolset", "stoptable", "stoptablehead", "stoptables", "stoptabletail", "stoptabletext", "stoptabulate", "stoptabulatehead", "stoptabulatetail", "stoptagged", "stoptaglabeltext", "stoptexcode", "stoptexdefinition", "stoptext", "stoptextbackground", "stoptextbackgroundmanual", "stoptextcolor", "stoptextcolorintent", "stoptextflow", "stoptextmakeup", "stoptextrule", "stoptitle", "stoptokens", "stoptransparent", "stoptypescript", "stoptypescriptcollection", "stoptyping", "stopuniqueMPgraphic", "stopuniqueMPpagegraphic", "stopunittext", "stopunpacked", "stopusableMPgraphic", "stopuseMPgraphic", "stopusemathstyleparameter", "stopusingbtxspecification", "stopvbox", "stopvboxregister", "stopvboxtohbox", "stopvboxtohboxseparator", "stopviewerlayer", "stopvtop", "stopvtopregister", "stopxcell", "stopxcellgroup", "stopxgroup", "stopxmldisplayverbatim", "stopxmlinlineverbatim", "stopxmlraw", "stopxmlsetups", "stopxrow", "stopxrowgroup", "stopxtable", "stopxtablebody", "stopxtablefoot", "stopxtablehead", "stopxtablenext", "stretched", "strictdoifelsenextoptional", "strictdoifnextoptionalelse", "stripcharacter", "strippedcsname", "stripspaces", "structurelistuservariable", "structurenumber", "structuretitle", "structureuservariable", "structurevariable", "strut", "strutdp", "strutht", "struthtdp", "struttedbox", "strutwd", "style", "styleinstance", "subject", "subpagenumber", "subsection", "subsentence", "subset", "subseteq", "subseteqq", "subsetneq", "subsetneqq", "substituteincommalist", "subsubject", "subsubsection", "subsubsubject", "subsubsubsection", "subsubsubsubject", "subsubsubsubsection", "subsubsubsubsubject", "subtractfeature", "succ", "succapprox", "succcurlyeq", "succeq", "succeqq", "succnapprox", "succneq", "succneqq", "succnsim", "succsim", "suffixlanguage", "suffixtext", "sum", "supset", "supseteq", "supseteqq", "supsetneq", "supsetneqq", "surd", "surdradical", "swapcounts", "swapdimens", "swapface", "swapmacros", "swaptypeface", "swarrow", "switchstyleonly", "switchtobodyfont", "switchtocolor", "switchtointerlinespace", "symbol", "symbolreference", "synchronizeblank", "synchronizeindenting", "synchronizemarking", "synchronizeoutputstreams", "synchronizestrut", "synchronizewhitespace", "synctexblockfilename", "synctexresetfilename", "synctexsetfilename", "systemlog", "systemlogfirst", "systemloglast", "systemsetups", "tLeftarrow", "tLeftrightarrow", "tRightarrow", "tabulateautoline", "tabulateautorule", "tabulateline", "tabulaterule", "taggedctxcommand", "taggedlabeltexts", "taglabellanguage", "taglabeltext", "tau", "tbinom", "tbox", "tcaron", "tcedilla", "tcommaaccent", "tcurl", "tequal", "test", "testandsplitstring", "testcolumn", "testfeature", "testfeatureonce", "testpage", "testpageonly", "testpagesync", "testtokens", "tex", "texdefinition", "texsetup", "textAngstrom", "textacute", "textampersand", "textasciicircum", "textasciitilde", "textat", "textbackslash", "textbar", "textbottomcomma", "textbottomdot", "textbraceleft", "textbraceright", "textbreve", "textbrokenbar", "textbullet", "textcaron", "textcedilla", "textcelsius", "textcent", "textcircledP", "textcircumflex", "textcitation", "textcite", "textcomma", "textcontrolspace", "textcurrency", "textdag", "textddag", "textdegree", "textdiaeresis", "textdiv", "textdollar", "textdong", "textdotaccent", "textellipsis", "texteuro", "textflowcollector", "textfraction", "textgrave", "texthash", "texthorizontalbar", "texthungarumlaut", "texthyphen", "textkelvin", "textlognot", "textmacron", "textmath", "textmho", "textminus", "textmu", "textmultiply", "textnumero", "textogonek", "textohm", "textormathchar", "textounce", "textpercent", "textperiod", "textplus", "textpm", "textreference", "textring", "textrule", "textslash", "textsterling", "texttilde", "textunderscore", "textvisiblespace", "textyen", "thai", "thainumerals", "thefirstcharacter", "thenormalizedbodyfontsize", "therefore", "theremainingcharacters", "theta", "thickspace", "thinrule", "thinrules", "thinspace", "thirdoffivearguments", "thirdoffourarguments", "thirdofsixarguments", "thirdofthreearguments", "thirdofthreeunexpanded", "thook", "thookleftarrow", "thookrightarrow", "thorn", "threedigitrounding", "threeeighths", "threefifths", "threeperemspace", "threequarter", "threesuperior", "tibetannumerals", "tightlayer", "tilde", "times", "tinyfont", "title", "tlap", "tleftarrow", "tleftharpoondown", "tleftharpoonup", "tleftrightarrow", "tleftrightharpoons", "tmapsto", "to", "tochar", "tolinenote", "tooltip", "top", "topbox", "topleftbox", "toplinebox", "toprightbox", "topskippedbox", "tracecatcodetables", "tracedfontname", "traceoutputroutines", "tracepositions", "trademark", "translate", "transparencycomponents", "transparent", "trel", "triangle", "triangledown", "triangleleft", "triangleq", "triangleright", "trightarrow", "trightharpoondown", "trightharpoonup", "trightleftharpoons", "trightoverleftarrow", "triplebond", "tripleprime", "tripleverticalbar", "truefilename", "truefontname", "tstroke", "ttraggedright", "ttriplerel", "ttwoheadleftarrow", "ttwoheadrightarrow", "turnediota", "twodigitrounding", "twofifths", "twoheaddownarrow", "twoheadleftarrow", "twoheadrightarrow", "twoheadrightarrowtail", "twoheaduparrow", "twosuperior", "twothirds", "tx", "txx", "typ", "type", "typebuffer", "typedefinedbuffer", "typeface", "typefile", "typeinlinebuffer", "typescriptone", "typescriptprefix", "typescriptthree", "typescripttwo", "typesetbuffer", "typesetfile", "uacute", "ubreve", "ucaron", "ucircumflex", "uconvertnumber", "udiaeresis", "udiaeresisacute", "udiaeresiscaron", "udiaeresisgrave", "udiaeresismacron", "udotbelow", "udots", "udoublegrave", "uedcatcodecommand", "ugrave", "uhook", "uhorn", "uhornacute", "uhorndotbelow", "uhorngrave", "uhornhook", "uhorntilde", "uhungarumlaut", "uinvertedbreve", "ulcorner", "umacron", "undefinevalue", "undepthed", "underbar", "underbars", "underbrace", "underbracket", "underdash", "underdashes", "underdot", "underdots", "underleftarrow", "underparent", "underrandom", "underrandoms", "underrightarrow", "underset", "understrike", "understrikes", "undoassign", "unexpandeddocumentvariable", "unframed", "unhhbox", "unihex", "uniqueMPgraphic", "uniqueMPpagegraphic", "unit", "unitlanguage", "unitshigh", "unitslow", "unittext", "unknown", "unprotected", "unregisterhyphenationpattern", "unspaceafter", "unspaceargument", "unspaced", "unspacestring", "untexargument", "untexcommand", "uogonek", "upand", "uparrow", "updasharrow", "updownarrow", "updownarrowbar", "updownarrows", "upharpoonleft", "upharpoonright", "uplus", "uppercased", "uppercasestring", "upperleftdoubleninequote", "upperleftdoublesixquote", "upperleftsingleninequote", "upperleftsinglesixquote", "upperrightdoubleninequote", "upperrightdoublesixquote", "upperrightsingleninequote", "upperrightsinglesixquote", "upsilon", "upuparrows", "upwhitearrow", "urcorner", "uring", "url", "useJSscripts", "useMPenvironmentbuffer", "useMPgraphic", "useMPlibrary", "useMPrun", "useMPvariables", "useURL", "usealignparameter", "useblankparameter", "useblocks", "usebodyfont", "usebodyfontparameter", "usebtxdataset", "usebtxdefinitions", "usecitation", "usecolors", "usecomponent", "usedirectory", "usedummycolorparameter", "usedummystyleandcolor", "usedummystyleparameter", "useenvironment", "useexternaldocument", "useexternalfigure", "useexternalrendering", "useexternalsoundtrack", "usefigurebase", "usefile", "usegridparameter", "useindentingparameter", "useindentnextparameter", "useinterlinespaceparameter", "uselanguageparameter", "useluamodule", "usemathstyleparameter", "usemodule", "useproduct", "useprofileparameter", "useproject", "usereferenceparameter", "userpagenumber", "usesetupsparameter", "usestaticMPfigure", "usesubpath", "usesymbols", "usetexmodule", "usetypescript", "usetypescriptfile", "useurl", "usezipfile", "utfchar", "utflower", "utfupper", "utilde", "utilityregisterlength", "vDash", "varTheta", "varepsilon", "varkappa", "varnothing", "varphi", "varpi", "varrho", "varsigma", "vartheta", "vboxreference", "vdash", "vdots", "vec", "vee", "veebar", "veeeq", "verbatim", "verbatimstring", "verbosenumber", "version", "vert", "verticalgrowingbar", "verticalpositionbar", "veryraggedcenter", "veryraggedleft", "veryraggedright", "vglue", "viewerlayer", "vl", "vphantom", "vpos", "vsmash", "vsmashbox", "vsmashed", "vspace", "vspacing", "wcircumflex", "wdofstring", "wedge", "wedgeeq", "weekday", "whitearrowupfrombar", "widehat", "widetilde", "widthofstring", "widthspanningtext", "withoutpt", "word", "wordright", "words", "wordtonumber", "wp", "wr", "writebetweenlist", "writedatatolist", "writestatus", "writetolist", "xLeftarrow", "xLeftrightarrow", "xRightarrow", "xdefconvertedargument", "xequal", "xfrac", "xhookleftarrow", "xhookrightarrow", "xi", "xleftarrow", "xleftharpoondown", "xleftharpoonup", "xleftrightarrow", "xleftrightharpoons", "xmapsto", "xmladdindex", "xmlafterdocumentsetup", "xmlaftersetup", "xmlall", "xmlappenddocumentsetup", "xmlappendsetup", "xmlapplyselectors", "xmlatt", "xmlattdef", "xmlattribute", "xmlattributedef", "xmlbadinclusions", "xmlbeforedocumentsetup", "xmlbeforesetup", "xmlchainatt", "xmlchainattdef", "xmlchecknamespace", "xmlcommand", "xmlconcat", "xmlconcatrange", "xmlcontext", "xmlcount", "xmldefaulttotext", "xmldirectives", "xmldirectivesafter", "xmldirectivesbefore", "xmldisplayverbatim", "xmldoif", "xmldoifelse", "xmldoifelseempty", "xmldoifelseselfempty", "xmldoifelsetext", "xmldoifelsevalue", "xmldoifnot", "xmldoifnotselfempty", "xmldoifnottext", "xmldoifselfempty", "xmldoiftext", "xmlelement", "xmlfilter", "xmlfirst", "xmlflush", "xmlflushcontext", "xmlflushdocumentsetups", "xmlflushlinewise", "xmlflushpure", "xmlflushspacewise", "xmlflushtext", "xmlinclude", "xmlinclusion", "xmlinclusions", "xmlinfo", "xmlinjector", "xmlinlineprettyprint", "xmlinlineprettyprinttext", "xmlinlineverbatim", "xmlinstalldirective", "xmllast", "xmllastatt", "xmllastmatch", "xmlloadbuffer", "xmlloaddata", "xmlloaddirectives", "xmlloadfile", "xmlloadonly", "xmlmain", "xmlmapvalue", "xmlname", "xmlnamespace", "xmlnonspace", "xmlpath", "xmlpos", "xmlposition", "xmlprependdocumentsetup", "xmlprependsetup", "xmlprettyprint", "xmlprettyprinttext", "xmlprocessbuffer", "xmlprocessdata", "xmlprocessfile", "xmlpure", "xmlraw", "xmlrefatt", "xmlregistereddocumentsetups", "xmlregisteredsetups", "xmlregisterns", "xmlremapname", "xmlremapnamespace", "xmlremovedocumentsetup", "xmlremovesetup", "xmlresetdocumentsetups", "xmlresetinjectors", "xmlresetsetups", "xmlsave", "xmlsetentity", "xmlsetfunction", "xmlsetinjectors", "xmlsetsetup", "xmlsetup", "xmlshow", "xmlsnippet", "xmlstrip", "xmlstripnolines", "xmlstripped", "xmlstrippednolines", "xmltag", "xmltexentity", "xmltext", "xmltobuffer", "xmltobufferverbose", "xmltofile", "xmlvalue", "xmlverbatim", "xrel", "xrightarrow", "xrightharpoondown", "xrightharpoonup", "xrightleftharpoons", "xrightoverleftarrow", "xsplitstring", "xtriplerel", "xtwoheadleftarrow", "xtwoheadrightarrow", "xxfrac", "xypos", "yacute", "ycircumflex", "ydiaeresis", "ydotbelow", "yen", "ygrave", "yhook", "ymacron", "ytilde", "zacute", "zcaron", "zdotaccent", "zerowidthnobreakspace", "zerowidthspace", "zeta", "zhook", "zstroke", "zwj", "zwnj" },
+ ["common"]={ "AEacute", "AEligature", "AEmacron", "AMSTEX", "Aacute", "Abreve", "Abreveacute", "Abrevedotbelow", "Abrevegrave", "Abrevehook", "Abrevetilde", "Acaron", "Acircumflex", "Acircumflexacute", "Acircumflexdotbelow", "Acircumflexgrave", "Acircumflexhook", "Acircumflextilde", "Adiaeresis", "Adiaeresismacron", "Adotaccent", "Adotaccentmacron", "Adotbelow", "Adoublegrave", "AfterPar", "Agrave", "Ahook", "Ainvertedbreve", "Alpha", "Alphabeticnumerals", "AmSTeX", "Amacron", "And", "Angstrom", "Aogonek", "Aring", "Aringacute", "Arrowvert", "Astroke", "Atilde", "BeforePar", "Beta", "Bhook", "Big", "Bigg", "Biggl", "Biggm", "Biggr", "Bigl", "Bigm", "Bigr", "Box", "Bumpeq", "CONTEXT", "Cacute", "Cap", "Caps", "Ccaron", "Ccedilla", "Ccircumflex", "Cdotaccent", "Character", "Characters", "Chi", "Chook", "ConTeXt", "Context", "ConvertConstantAfter", "ConvertToConstant", "Cstroke", "Cup", "DZcaronligature", "DZligature", "Dafrican", "Dcaron", "Ddownarrow", "Delta", "Dhook", "Doteq", "Downarrow", "Dstroke", "Dzcaronligature", "Dzligature", "ETEX", "Eacute", "Ebreve", "Ecaron", "Ecedilla", "Ecircumflex", "Ecircumflexacute", "Ecircumflexdotbelow", "Ecircumflexgrave", "Ecircumflexhook", "Ecircumflextilde", "Ediaeresis", "Edotaccent", "Edotbelow", "Edoublegrave", "Egrave", "Ehook", "Einvertedbreve", "Emacron", "Eogonek", "Epsilon", "Eta", "Eth", "Etilde", "Eulerconst", "EveryLine", "EveryPar", "Fhook", "Finv", "Gacute", "Game", "Gamma", "Gbreve", "Gcaron", "Gcircumflex", "Gcommaaccent", "Gdotaccent", "GetPar", "Ghook", "GotoPar", "Greeknumerals", "Gstroke", "Hat", "Hcaron", "Hcircumflex", "Hstroke", "IJligature", "INRSTEX", "Iacute", "Ibreve", "Icaron", "Icircumflex", "Idiaeresis", "Idotaccent", "Idotbelow", "Idoublegrave", "Igrave", "Ihook", "Iinvertedbreve", "Im", "Imacron", "Iogonek", "Iota", "Istroke", "Itilde", "Jcircumflex", "Join", "Kappa", "Kcaron", "Kcommaaccent", "Khook", "LAMSTEX", "LATEX", "LJligature", "LUAJITTEX", "LUATEX", "LaTeX", "Lacute", "LamSTeX", "Lambda", "Lbar", "Lcaron", "Lcommaaccent", "Ldotmiddle", "Ldsh", "Leftarrow", "Leftrightarrow", "Ljligature", "Lleftarrow", "Longleftarrow", "Longleftrightarrow", "Longmapsfrom", "Longmapsto", "Longrightarrow", "Lsh", "Lstroke", "Lua", "LuaTeX", "LuajitTeX", "METAFONT", "METAFUN", "METAPOST", "MKII", "MKIV", "MKIX", "MKVI", "MKXI", "MONTH", "MONTHLONG", "MONTHSHORT", "MPII", "MPIV", "MPVI", "MPanchor", "MPbetex", "MPc", "MPcode", "MPcolor", "MPcoloronly", "MPcolumn", "MPd", "MPdrawing", "MPfontsizehskip", "MPgetmultipars", "MPgetmultishape", "MPgetposboxes", "MPh", "MPinclusions", "MPleftskip", "MPll", "MPlr", "MPls", "MPmenubuttons", "MPn", "MPoptions", "MPoverlayanchor", "MPp", "MPpage", "MPpardata", "MPplus", "MPpos", "MPpositiongraphic", "MPposset", "MPr", "MPrawvar", "MPregion", "MPrest", "MPrightskip", "MPrs", "MPstring", "MPtext", "MPtransparency", "MPul", "MPur", "MPv", "MPvar", "MPvariable", "MPvv", "MPw", "MPwhd", "MPx", "MPxy", "MPxywhd", "MPy", "Mapsfrom", "Mapsto", "MetaFont", "MetaFun", "MetaPost", "Mu", "NJligature", "Nacute", "Ncaron", "Ncommaaccent", "Nearrow", "Neng", "Ngrave", "Njligature", "NormalizeFontHeight", "NormalizeFontWidth", "NormalizeTextHeight", "NormalizeTextWidth", "Ntilde", "Nu", "Numbers", "Nwarrow", "OEligature", "Oacute", "Obreve", "Ocaron", "Ocircumflex", "Ocircumflexacute", "Ocircumflexdotbelow", "Ocircumflexgrave", "Ocircumflexhook", "Ocircumflextilde", "Odiaeresis", "Odiaeresismacron", "Odotaccent", "Odotaccentmacron", "Odotbelow", "Odoublegrave", "Ograve", "Ohook", "Ohorn", "Ohornacute", "Ohorndotbelow", "Ohorngrave", "Ohornhook", "Ohorntilde", "Ohungarumlaut", "Oinvertedbreve", "Omacron", "Omega", "Omicron", "Oogonek", "Oogonekmacron", "Ostroke", "Ostrokeacute", "Otilde", "Otildemacron", "P", "PDFETEX", "PDFTEX", "PDFcolor", "PICTEX", "PPCHTEX", "PPCHTeX", "PRAGMA", "Phi", "Phook", "Pi", "PiCTeX", "Plankconst", "PointsToBigPoints", "PointsToReal", "PointsToWholeBigPoints", "PropertyLine", "Psi", "PtToCm", "Racute", "Rcaron", "Rcommaaccent", "Rdoublegrave", "Rdsh", "Re", "ReadFile", "Relbar", "Rho", "Rightarrow", "Rinvertedbreve", "Romannumerals", "Rrightarrow", "Rsh", "S", "Sacute", "ScaledPointsToBigPoints", "ScaledPointsToWholeBigPoints", "Scaron", "Scedilla", "Schwa", "Scircumflex", "Scommaaccent", "Searrow", "Sigma", "Smallcapped", "Subset", "Supset", "Swarrow", "TABLE", "TEX", "TaBlE", "Tau", "Tcaron", "Tcedilla", "Tcommaaccent", "TeX", "TheNormalizedFontSize", "Theta", "Thook", "Thorn", "TransparencyHack", "Tstroke", "Uacute", "Ubreve", "Ucaron", "Ucircumflex", "Udiaeresis", "Udiaeresisacute", "Udiaeresiscaron", "Udiaeresisgrave", "Udiaeresismacron", "Udotbelow", "Udoublegrave", "Ugrave", "Uhook", "Uhorn", "Uhornacute", "Uhorndotbelow", "Uhorngrave", "Uhornhook", "Uhorntilde", "Uhungarumlaut", "Uinvertedbreve", "Umacron", "Uogonek", "Uparrow", "Updownarrow", "Upsilon", "Uring", "Utilde", "Uuparrow", "VDash", "Vdash", "VerboseNumber", "Vert", "Vvdash", "WEEKDAY", "WORD", "WORDS", "Wcircumflex", "WidthSpanningText", "Word", "Words", "XETEX", "XeTeX", "Xi", "Yacute", "Ycircumflex", "Ydiaeresis", "Ydotbelow", "Ygrave", "Yhook", "Ymacron", "Ytilde", "Zacute", "Zcaron", "Zdotaccent", "Zeta", "Zhook", "Zstroke", "aacute", "abbreviation", "abjadnaivenumerals", "abjadnodotnumerals", "abjadnumerals", "about", "abreve", "abreveacute", "abrevedotbelow", "abrevegrave", "abrevehook", "abrevetilde", "acaron", "acircumflex", "acircumflexacute", "acircumflexdotbelow", "acircumflexgrave", "acircumflexhook", "acircumflextilde", "activatespacehandler", "actuarial", "acute", "acwopencirclearrow", "adaptcollector", "adaptfontfeature", "adaptlayout", "adaptpapersize", "addfeature", "addtoJSpreamble", "addtocommalist", "addvalue", "adiaeresis", "adiaeresismacron", "adotaccent", "adotaccentmacron", "adotbelow", "adoublegrave", "aeacute", "aeligature", "aemacron", "aftersplitstring", "aftertestandsplitstring", "agrave", "ahook", "ainvertedbreve", "aleph", "alignbottom", "aligned", "alignedbox", "alignedline", "alignhere", "alignmentcharacter", "allinputpaths", "alpha", "alphabeticnumerals", "alwayscitation", "alwayscite", "amacron", "amalg", "ampersand", "anchor", "angle", "aogonek", "appendetoks", "appendgvalue", "appendtocommalist", "appendtoks", "appendtoksonce", "appendvalue", "apply", "applyalternativestyle", "applyprocessor", "applytocharacters", "applytofirstcharacter", "applytosplitstringchar", "applytosplitstringcharspaced", "applytosplitstringline", "applytosplitstringlinespaced", "applytosplitstringword", "applytosplitstringwordspaced", "applytowords", "approx", "approxEq", "approxeq", "approxnEq", "arabicdecimals", "arabicexnumerals", "arabicnumerals", "arg", "aring", "aringacute", "arrowvert", "asciistr", "aside", "assignalfadimension", "assigndimen", "assigndimension", "assignifempty", "assigntranslation", "assignvalue", "assignwidth", "assumelongusagecs", "ast", "astype", "asymp", "at", "atilde", "atleftmargin", "atpage", "atrightmargin", "attachment", "autocap", "autodirhbox", "autodirvbox", "autodirvtop", "autoinsertnextspace", "autointegral", "automathematics", "autosetups", "availablehsize", "averagecharwidth", "backepsilon", "background", "backgroundimage", "backgroundimagefill", "backgroundline", "backprime", "backsim", "backslash", "bar", "barleftarrow", "barleftarrowrightarrowbar", "barovernorthwestarrow", "barwedge", "basegrid", "baselinebottom", "baselineleftbox", "baselinemiddlebox", "baselinerightbox", "bbordermatrix", "bbox", "because", "beforesplitstring", "beforetestandsplitstring", "beta", "beth", "between", "bhook", "big", "bigbodyfont", "bigcap", "bigcirc", "bigcircle", "bigcup", "bigdiamond", "bigg", "bigger", "biggl", "biggm", "biggr", "bigl", "bigm", "bigodot", "bigoplus", "bigotimes", "bigr", "bigskip", "bigsqcap", "bigsqcup", "bigsquare", "bigstar", "bigtimes", "bigtriangledown", "bigtriangleup", "bigudot", "biguplus", "bigvee", "bigwedge", "binom", "bitmapimage", "blacklozenge", "blackrule", "blackrules", "blacksquare", "blacktriangle", "blacktriangledown", "blacktriangleleft", "blacktriangleright", "blank", "blap", "bleed", "bleedheight", "bleedwidth", "blockligatures", "blockquote", "blocksynctexfile", "bodyfontenvironmentlist", "bodyfontsize", "bold", "boldface", "bolditalic", "boldslanted", "bookmark", "booleanmodevalue", "bordermatrix", "bot", "bottombox", "bottomleftbox", "bottomrightbox", "bowtie", "boxcursor", "boxdot", "boxmarker", "boxminus", "boxofsize", "boxplus", "boxreference", "boxtimes", "bpos", "breakablethinspace", "breakhere", "breve", "bstroke", "btxabbreviatedjournal", "btxaddjournal", "btxalwayscitation", "btxauthorfield", "btxdetail", "btxdirect", "btxdoif", "btxdoifcombiinlistelse", "btxdoifelse", "btxdoifelsecombiinlist", "btxdoifelsesameasprevious", "btxdoifelsesameaspreviouschecked", "btxdoifelseuservariable", "btxdoifnot", "btxdoifsameaspreviouscheckedelse", "btxdoifsameaspreviouselse", "btxdoifuservariableelse", "btxexpandedjournal", "btxfield", "btxfieldname", "btxfieldtype", "btxfirstofrange", "btxflush", "btxflushauthor", "btxflushauthorinverted", "btxflushauthorinvertedshort", "btxflushauthorname", "btxflushauthornormal", "btxflushauthornormalshort", "btxflushsuffix", "btxfoundname", "btxfoundtype", "btxhiddencitation", "btxhybridcite", "btxlabellanguage", "btxlabeltext", "btxlistcitation", "btxloadjournalist", "btxoneorrange", "btxremapauthor", "btxsavejournalist", "btxsetup", "btxsingularorplural", "btxsingularplural", "btxtextcitation", "buildmathaccent", "buildtextaccent", "buildtextbottomcomma", "buildtextbottomdot", "buildtextcedilla", "buildtextgrave", "buildtextmacron", "buildtextognek", "bullet", "button", "cacute", "calligraphic", "camel", "cap", "carriagereturn", "catcodetablename", "cbox", "ccaron", "ccedilla", "ccircumflex", "ccurl", "cdot", "cdotaccent", "cdotp", "cdots", "centeraligned", "centerbox", "centerdot", "centeredbox", "centeredlastline", "centerednextbox", "centerline", "cfrac", "chapter", "character", "characters", "chardescription", "charwidthlanguage", "check", "checkcharacteralign", "checkedchar", "checkedfiller", "checkedstrippedcsname", "checkinjector", "checkmark", "checknextindentation", "checknextinjector", "checkpage", "checkparameters", "checkpreviousinjector", "checksoundtrack", "checktwopassdata", "checkvariables", "chem", "chemical", "chemicalbottext", "chemicalmidtext", "chemicalsymbol", "chemicaltext", "chemicaltoptext", "chi", "chineseallnumerals", "chinesecapnumerals", "chinesenumerals", "chook", "circ", "circeq", "circlearrowleft", "circlearrowright", "circledR", "circledS", "circledast", "circledcirc", "circleddash", "circledequals", "circleonrightarrow", "citation", "cite", "clap", "classfont", "cldcommand", "cldcontext", "cldloadfile", "cldprocessfile", "cleftarrow", "clip", "clonefield", "clubsuit", "collect", "collectedtext", "collectexpanded", "colon", "coloncolonequals", "colonequals", "color", "colorbar", "colorcomponents", "colored", "coloronly", "colorvalue", "column", "columnbreak", "combinepages", "commalistelement", "commalistsentence", "commalistsize", "comment", "comparecolorgroup", "comparedimension", "comparedimensioneps", "comparepalet", "complement", "completebtxrendering", "completecontent", "completeindex", "completelist", "completelistofabbreviations", "completelistofchemicals", "completelistoffigures", "completelistofgraphics", "completelistofintermezzi", "completelistoflogos", "completelistofpublications", "completelistofsorts", "completelistofsynonyms", "completelistoftables", "completepagenumber", "completeregister", "complexes", "complexorsimple", "complexorsimpleempty", "component", "composedcollector", "composedlayer", "compresult", "cong", "constantdimen", "constantdimenargument", "constantemptyargument", "constantnumber", "constantnumberargument", "contentreference", "continuednumber", "continueifinputfile", "convertargument", "convertcommand", "convertedcounter", "converteddimen", "convertedsubcounter", "convertmonth", "convertnumber", "convertvalue", "convertvboxtohbox", "coprod", "copyboxfromcache", "copybtxlabeltext", "copyfield", "copyheadtext", "copylabeltext", "copymathlabeltext", "copyoperatortext", "copypages", "copyparameters", "copyposition", "copyprefixtext", "copyright", "copysuffixtext", "copytaglabeltext", "copyunittext", "correctwhitespace", "countersubs", "counttoken", "counttokens", "cramped", "crampedclap", "crampedllap", "crampedrlap", "crightarrow", "crightoverleftarrow", "cstroke", "ctop", "ctxcommand", "ctxdirectcommand", "ctxdirectlua", "ctxfunction", "ctxlatecommand", "ctxlatelua", "ctxloadluafile", "ctxlua", "ctxluabuffer", "ctxluacode", "ctxreport", "ctxsprint", "cup", "curlyeqprec", "curlyeqsucc", "curlyvee", "curlywedge", "currentassignmentlistkey", "currentassignmentlistvalue", "currentbtxuservariable", "currentcommalistitem", "currentcomponent", "currentdate", "currentenvironment", "currentfeaturetest", "currentheadnumber", "currentinterface", "currentlanguage", "currentlistentrydestinationattribute", "currentlistentrylimitedtext", "currentlistentrynumber", "currentlistentrypagenumber", "currentlistentryreferenceattribute", "currentlistentrytitle", "currentlistentrytitlerendered", "currentlistsymbol", "currentmainlanguage", "currentmessagetext", "currentmoduleparameter", "currentoutputstream", "currentproduct", "currentproject", "currentregime", "currentregisterpageuserdata", "currentresponses", "currenttime", "currentvalue", "currentxtablecolumn", "currentxtablerow", "curvearrowleft", "curvearrowright", "cwopencirclearrow", "cyrillicA", "cyrillicAE", "cyrillicAbreve", "cyrillicAdiaeresis", "cyrillicB", "cyrillicBIGYUS", "cyrillicBIGYUSiotified", "cyrillicC", "cyrillicCH", "cyrillicCHEDC", "cyrillicCHEDCabkhasian", "cyrillicCHEabkhasian", "cyrillicCHEdiaeresis", "cyrillicCHEkhakassian", "cyrillicCHEvertstroke", "cyrillicD", "cyrillicDASIAPNEUMATA", "cyrillicDJE", "cyrillicDZE", "cyrillicDZEabkhasian", "cyrillicDZHE", "cyrillicE", "cyrillicELtail", "cyrillicEMtail", "cyrillicENDC", "cyrillicENGHE", "cyrillicENhook", "cyrillicENtail", "cyrillicEREV", "cyrillicERY", "cyrillicERtick", "cyrillicEbreve", "cyrillicEdiaeresis", "cyrillicEgrave", "cyrillicEiotified", "cyrillicF", "cyrillicFITA", "cyrillicG", "cyrillicGHEmidhook", "cyrillicGHEstroke", "cyrillicGHEupturn", "cyrillicGJE", "cyrillicH", "cyrillicHA", "cyrillicHADC", "cyrillicHRDSN", "cyrillicI", "cyrillicIE", "cyrillicII", "cyrillicISHRT", "cyrillicISHRTtail", "cyrillicIZHITSA", "cyrillicIZHITSAdoublegrave", "cyrillicIdiaeresis", "cyrillicIgrave", "cyrillicImacron", "cyrillicJE", "cyrillicK", "cyrillicKADC", "cyrillicKAbashkir", "cyrillicKAhook", "cyrillicKAstroke", "cyrillicKAvertstroke", "cyrillicKJE", "cyrillicKOPPA", "cyrillicKSI", "cyrillicL", "cyrillicLITTLEYUS", "cyrillicLITTLEYUSiotified", "cyrillicLJE", "cyrillicM", "cyrillicN", "cyrillicNJE", "cyrillicO", "cyrillicOMEGA", "cyrillicOMEGAround", "cyrillicOMEGAtitlo", "cyrillicOT", "cyrillicObarred", "cyrillicObarreddiaeresis", "cyrillicOdiaeresis", "cyrillicP", "cyrillicPALATALIZATION", "cyrillicPALOCHKA", "cyrillicPEmidhook", "cyrillicPSI", "cyrillicPSILIPNEUMATA", "cyrillicR", "cyrillicS", "cyrillicSCHWA", "cyrillicSCHWAdiaeresis", "cyrillicSDSC", "cyrillicSEMISOFT", "cyrillicSFTSN", "cyrillicSH", "cyrillicSHCH", "cyrillicSHHA", "cyrillicT", "cyrillicTEDC", "cyrillicTETSE", "cyrillicTITLO", "cyrillicTSHE", "cyrillicU", "cyrillicUK", "cyrillicUSHRT", "cyrillicUdiaeresis", "cyrillicUdoubleacute", "cyrillicUmacron", "cyrillicV", "cyrillicYA", "cyrillicYAT", "cyrillicYERUdiaeresis", "cyrillicYI", "cyrillicYO", "cyrillicYU", "cyrillicYstr", "cyrillicYstrstroke", "cyrillicZ", "cyrillicZDSC", "cyrillicZEdiaeresis", "cyrillicZH", "cyrillicZHEbreve", "cyrillicZHEdescender", "cyrillicZHEdiaeresis", "cyrillica", "cyrillicabreve", "cyrillicadiaeresis", "cyrillicae", "cyrillicb", "cyrillicbigyus", "cyrillicbigyusiotified", "cyrillicc", "cyrillicch", "cyrilliccheabkhasian", "cyrillicchedc", "cyrillicchedcabkhasian", "cyrillicchediaeresis", "cyrillicchekhakassian", "cyrillicchevertstroke", "cyrillicd", "cyrillicdje", "cyrillicdze", "cyrillicdzeabkhasian", "cyrillicdzhe", "cyrillice", "cyrillicebreve", "cyrillicediaeresis", "cyrillicegrave", "cyrilliceiotified", "cyrilliceltail", "cyrillicemtail", "cyrillicendc", "cyrillicenghe", "cyrillicenhook", "cyrillicentail", "cyrillicerev", "cyrillicertick", "cyrillicery", "cyrillicf", "cyrillicfita", "cyrillicg", "cyrillicghemidhook", "cyrillicghestroke", "cyrillicgheupturn", "cyrillicgje", "cyrillich", "cyrillicha", "cyrillichadc", "cyrillichrdsn", "cyrillici", "cyrillicidiaeresis", "cyrillicie", "cyrillicigrave", "cyrillicii", "cyrillicimacron", "cyrillicishrt", "cyrillicishrttail", "cyrillicizhitsa", "cyrillicizhitsadoublegrave", "cyrillicje", "cyrillick", "cyrillickabashkir", "cyrillickadc", "cyrillickahook", "cyrillickastroke", "cyrillickavertstroke", "cyrillickje", "cyrillickoppa", "cyrillicksi", "cyrillicl", "cyrilliclittleyus", "cyrilliclittleyusiotified", "cyrilliclje", "cyrillicm", "cyrillicn", "cyrillicnje", "cyrillico", "cyrillicobarred", "cyrillicobarreddiaeresis", "cyrillicodiaeresis", "cyrillicomega", "cyrillicomegaround", "cyrillicomegatitlo", "cyrillicot", "cyrillicp", "cyrillicpemidhook", "cyrillicpsi", "cyrillicr", "cyrillics", "cyrillicschwa", "cyrillicschwadiaeresis", "cyrillicsdsc", "cyrillicsemisoft", "cyrillicsftsn", "cyrillicsh", "cyrillicshch", "cyrillicshha", "cyrillict", "cyrillictedc", "cyrillictetse", "cyrillictshe", "cyrillicu", "cyrillicudiaeresis", "cyrillicudoubleacute", "cyrillicuk", "cyrillicumacron", "cyrillicushrt", "cyrillicv", "cyrillicya", "cyrillicyat", "cyrillicyerudiaeresis", "cyrillicyi", "cyrillicyo", "cyrillicystr", "cyrillicystrstroke", "cyrillicyu", "cyrillicz", "cyrilliczdsc", "cyrilliczediaeresis", "cyrilliczh", "cyrilliczhebreve", "cyrilliczhedescender", "cyrilliczhediaeresis", "d", "dag", "dagger", "daleth", "dasharrow", "dashedleftarrow", "dashedrightarrow", "dashv", "datasetvariable", "date", "dayoftheweek", "dayspermonth", "dbinom", "dcaron", "dcurl", "ddag", "ddagger", "dddot", "ddot", "ddots", "decrement", "decrementcounter", "decrementedcounter", "decrementpagenumber", "decrementsubpagenumber", "decrementvalue", "defaultinterface", "defaultobjectpage", "defaultobjectreference", "defcatcodecommand", "defconvertedargument", "defconvertedcommand", "defconvertedvalue", "define", "defineMPinstance", "defineTABLEsetup", "defineaccent", "defineactivecharacter", "definealternativestyle", "defineanchor", "defineattachment", "defineattribute", "definebackground", "definebar", "defineblock", "definebodyfont", "definebodyfontenvironment", "definebodyfontswitch", "definebreakpoint", "definebreakpoints", "definebtx", "definebtxdataset", "definebtxregister", "definebtxrendering", "definebuffer", "definebutton", "definecapitals", "definecharacter", "definecharacterkerning", "definecharacterspacing", "definechemical", "definechemicals", "definechemicalsymbol", "definecollector", "definecolor", "definecolorgroup", "definecolumnbreak", "definecombination", "definecombinedlist", "definecommand", "definecomment", "definecomplexorsimple", "definecomplexorsimpleempty", "defineconversion", "defineconversionset", "definecounter", "definedataset", "definedelimitedtext", "definedeq", "definedescription", "definedfont", "defineeffect", "defineenumeration", "defineexpandable", "defineexternalfigure", "definefallbackfamily", "definefield", "definefieldbody", "definefieldbodyset", "definefieldcategory", "definefieldstack", "definefiguresymbol", "definefileconstant", "definefilefallback", "definefilesynonym", "definefiller", "definefirstline", "definefittingpage", "definefloat", "definefont", "definefontalternative", "definefontfallback", "definefontfamily", "definefontfamilypreset", "definefontfeature", "definefontfile", "definefontsize", "definefontsolution", "definefontstyle", "definefontsynonym", "defineformula", "defineformulaalternative", "defineformulaframed", "defineframed", "defineframedcontent", "defineframedtable", "defineframedtext", "definefrozenfont", "defineglobalcolor", "definegraphictypesynonym", "definegridsnapping", "definehbox", "definehead", "defineheadalternative", "definehelp", "definehigh", "definehighlight", "definehspace", "definehypenationfeatures", "defineindentedtext", "defineindenting", "defineinitial", "defineinsertion", "defineinteraction", "defineinteractionbar", "defineinteractionmenu", "defineinterfaceconstant", "defineinterfaceelement", "defineinterfacevariable", "defineinterlinespace", "defineintermediatecolor", "defineitemgroup", "defineitems", "definelabel", "definelabelclass", "definelayer", "definelayerpreset", "definelayout", "definelinefiller", "definelinenote", "definelinenumbering", "definelines", "definelist", "definelistalternative", "definelistextra", "definelow", "definelowhigh", "definelowmidhigh", "definemakeup", "definemarginblock", "definemargindata", "definemarker", "definemarking", "definemathaccent", "definemathalignment", "definemathcases", "definemathcommand", "definemathdouble", "definemathdoubleextensible", "definemathematics", "definemathextensible", "definemathfence", "definemathfraction", "definemathframed", "definemathmatrix", "definemathornament", "definemathover", "definemathoverextensible", "definemathovertextextensible", "definemathradical", "definemathstackers", "definemathstyle", "definemathtriplet", "definemathunder", "definemathunderextensible", "definemathundertextextensible", "definemathunstacked", "definemeasure", "definemessageconstant", "definemixedcolumns", "definemode", "definemultitonecolor", "definenamedcolor", "definenamespace", "definenarrower", "definenote", "defineornament", "defineoutputroutine", "defineoutputroutinecommand", "defineoverlay", "definepage", "definepagebreak", "definepagechecker", "definepagegrid", "definepagegridarea", "definepagegridspan", "definepageinjection", "definepageinjectionalternative", "definepageshift", "definepagestate", "definepairedbox", "definepalet", "definepapersize", "defineparagraph", "defineparagraphs", "defineparallel", "defineparbuilder", "defineplacement", "definepositioning", "defineprefixset", "defineprocesscolor", "defineprocessor", "defineprofile", "defineprogram", "definepushbutton", "definepushsymbol", "definereference", "definereferenceformat", "defineregister", "definerenderingwindow", "defineresetset", "definescale", "definescript", "definesection", "definesectionblock", "definesectionlevels", "defineselector", "defineseparatorset", "defineshift", "definesidebar", "definesort", "definesorting", "definespotcolor", "definestartstop", "definestyle", "definestyleinstance", "definesubfield", "definesubformula", "definesymbol", "definesynonym", "definesynonyms", "definesystemattribute", "definesystemconstant", "definesystemvariable", "definetabletemplate", "definetabulate", "definetabulation", "definetext", "definetextbackground", "definetextflow", "definetooltip", "definetransparency", "definetwopasslist", "definetype", "definetypeface", "definetypescriptprefix", "definetypescriptsynonym", "definetypesetting", "definetyping", "defineunit", "defineviewerlayer", "definevspace", "definevspacing", "definevspacingamount", "definextable", "delimited", "delimitedtext", "delta", "depthofstring", "depthonlybox", "depthspanningtext", "depthstrut", "determineheadnumber", "determinelistcharacteristics", "determinenoflines", "determineregistercharacteristics", "devanagarinumerals", "dfrac", "dhook", "diameter", "diamond", "diamondsuit", "differentialD", "differentiald", "digamma", "digits", "dimensiontocount", "directboxfromcache", "directcolor", "directcolored", "directconvertedcounter", "directcopyboxfromcache", "directdummyparameter", "directgetboxllx", "directgetboxlly", "directhighlight", "directlocalframed", "directluacode", "directselect", "directsetbar", "directsetup", "directsymbol", "directvspacing", "dis", "disabledirectives", "disableexperiments", "disablemode", "disableoutputstream", "disableparpositions", "disableregime", "disabletrackers", "displaymath", "displaymathematics", "displaymessage", "distributedhsize", "div", "dividedsize", "divideontimes", "divides", "doadaptleftskip", "doadaptrightskip", "doaddfeature", "doassign", "doassignempty", "doboundtext", "docheckassignment", "docheckedpagestate", "docheckedpair", "documentvariable", "dodoubleargument", "dodoubleargumentwithset", "dodoubleempty", "dodoubleemptywithset", "dodoublegroupempty", "doeassign", "doexpandedrecurse", "dofastloopcs", "dogetattribute", "dogetattributeid", "dogetcommacommandelement", "dogobbledoubleempty", "dogobblesingleempty", "doif", "doifMPgraphicelse", "doifallcommon", "doifallcommonelse", "doifalldefinedelse", "doifallmodes", "doifallmodeselse", "doifassignmentelse", "doifblackelse", "doifbothsides", "doifbothsidesoverruled", "doifboxelse", "doifbufferelse", "doifcolor", "doifcolorelse", "doifcommandhandler", "doifcommandhandlerelse", "doifcommon", "doifcommonelse", "doifcontent", "doifconversiondefinedelse", "doifconversionnumberelse", "doifcounter", "doifcounterelse", "doifcurrentfonthasfeatureelse", "doifdefined", "doifdefinedcounter", "doifdefinedcounterelse", "doifdefinedelse", "doifdimensionelse", "doifdimenstringelse", "doifdocumentargument", "doifdocumentargumentelse", "doifdocumentfilename", "doifdocumentfilenameelse", "doifdrawingblackelse", "doifelse", "doifelseMPgraphic", "doifelseallcommon", "doifelsealldefined", "doifelseallmodes", "doifelseassignment", "doifelseblack", "doifelsebox", "doifelseboxincache", "doifelsebuffer", "doifelsecolor", "doifelsecommandhandler", "doifelsecommon", "doifelseconversiondefined", "doifelseconversionnumber", "doifelsecounter", "doifelsecurrentfonthasfeature", "doifelsecurrentsortingused", "doifelsecurrentsynonymshown", "doifelsecurrentsynonymused", "doifelsedefined", "doifelsedefinedcounter", "doifelsedimension", "doifelsedimenstring", "doifelsedocumentargument", "doifelsedocumentfilename", "doifelsedrawingblack", "doifelseempty", "doifelseemptyvalue", "doifelseemptyvariable", "doifelseenv", "doifelsefastoptionalcheck", "doifelsefastoptionalcheckcs", "doifelsefieldbody", "doifelsefieldcategory", "doifelsefigure", "doifelsefile", "doifelsefiledefined", "doifelsefileexists", "doifelsefirstchar", "doifelseflagged", "doifelsefontchar", "doifelsefontpresent", "doifelsefontsynonym", "doifelsehasspace", "doifelsehelp", "doifelseincsname", "doifelseinelement", "doifelseinputfile", "doifelseinsertion", "doifelseinset", "doifelseinstring", "doifelseinsymbolset", "doifelseintoks", "doifelseintwopassdata", "doifelseitalic", "doifelselanguage", "doifelselayerdata", "doifelselayoutdefined", "doifelselayoutsomeline", "doifelselayouttextline", "doifelseleapyear", "doifelselist", "doifelselocation", "doifelselocfile", "doifelsemainfloatbody", "doifelsemarkedpage", "doifelsemarking", "doifelsemeaning", "doifelsemessage", "doifelsemode", "doifelsenextbgroup", "doifelsenextbgroupcs", "doifelsenextchar", "doifelsenextoptional", "doifelsenextoptionalcs", "doifelsenextparenthesis", "doifelsenonzeropositive", "doifelsenoteonsamepage", "doifelsenothing", "doifelsenumber", "doifelseobjectfound", "doifelseobjectreferencefound", "doifelseoddpage", "doifelseoddpagefloat", "doifelseoldercontext", "doifelseolderversion", "doifelseoverlapping", "doifelseoverlay", "doifelseparallel", "doifelseparentfile", "doifelsepath", "doifelsepathexists", "doifelsepatterns", "doifelseposition", "doifelsepositionaction", "doifelsepositiononpage", "doifelsepositionsonsamepage", "doifelsepositionsonthispage", "doifelsepositionsused", "doifelsereferencefound", "doifelserightpagefloat", "doifelserighttoleftinbox", "doifelsesamelinereference", "doifelsesamestring", "doifelsesetups", "doifelsesomebackground", "doifelsesomespace", "doifelsesomething", "doifelsesometoks", "doifelsestringinstring", "doifelsestructurelisthasnumber", "doifelsestructurelisthaspage", "doifelsesymboldefined", "doifelsesymbolset", "doifelsetext", "doifelsetextflow", "doifelsetextflowcollector", "doifelsetopofpage", "doifelsetypingfile", "doifelseundefined", "doifelseurldefined", "doifelsevalue", "doifelsevaluenothing", "doifelsevariable", "doifempty", "doifemptyelse", "doifemptytoks", "doifemptyvalue", "doifemptyvalueelse", "doifemptyvariable", "doifemptyvariableelse", "doifenv", "doifenvelse", "doiffastoptionalcheckcselse", "doiffastoptionalcheckelse", "doiffieldbodyelse", "doiffieldcategoryelse", "doiffigureelse", "doiffile", "doiffiledefinedelse", "doiffileelse", "doiffileexistselse", "doiffirstcharelse", "doifflaggedelse", "doiffontcharelse", "doiffontpresentelse", "doiffontsynonymelse", "doifhasspaceelse", "doifhelpelse", "doifincsnameelse", "doifinelementelse", "doifinputfileelse", "doifinsertionelse", "doifinset", "doifinsetelse", "doifinstring", "doifinstringelse", "doifinsymbolset", "doifinsymbolsetelse", "doifintokselse", "doifintwopassdataelse", "doifitalicelse", "doiflanguageelse", "doiflayerdataelse", "doiflayoutdefinedelse", "doiflayoutsomelineelse", "doiflayouttextlineelse", "doifleapyearelse", "doiflistelse", "doiflocationelse", "doiflocfileelse", "doifmainfloatbodyelse", "doifmarkingelse", "doifmeaningelse", "doifmessageelse", "doifmode", "doifmodeelse", "doifnextbgroupcselse", "doifnextbgroupelse", "doifnextcharelse", "doifnextoptionalcselse", "doifnextoptionalelse", "doifnextparenthesiselse", "doifnonzeropositiveelse", "doifnot", "doifnotallcommon", "doifnotallmodes", "doifnotcommandhandler", "doifnotcommon", "doifnotcounter", "doifnotdocumentargument", "doifnotdocumentfilename", "doifnotempty", "doifnotemptyvalue", "doifnotemptyvariable", "doifnotenv", "doifnoteonsamepageelse", "doifnotescollected", "doifnotfile", "doifnotflagged", "doifnothing", "doifnothingelse", "doifnotinset", "doifnotinsidesplitfloat", "doifnotinstring", "doifnotmode", "doifnotnumber", "doifnotsamestring", "doifnotsetups", "doifnotvalue", "doifnotvariable", "doifnumber", "doifnumberelse", "doifobjectfoundelse", "doifobjectreferencefoundelse", "doifoddpageelse", "doifoddpagefloatelse", "doifoldercontextelse", "doifolderversionelse", "doifoverlappingelse", "doifoverlayelse", "doifparallelelse", "doifparentfileelse", "doifpathelse", "doifpathexistselse", "doifpatternselse", "doifposition", "doifpositionaction", "doifpositionactionelse", "doifpositionelse", "doifpositiononpageelse", "doifpositionsonsamepageelse", "doifpositionsonthispageelse", "doifpositionsusedelse", "doifreferencefoundelse", "doifrightpagefloatelse", "doifrighttoleftinboxelse", "doifsamelinereferenceelse", "doifsamestring", "doifsamestringelse", "doifsetups", "doifsetupselse", "doifsomebackground", "doifsomebackgroundelse", "doifsomespaceelse", "doifsomething", "doifsomethingelse", "doifsometoks", "doifsometokselse", "doifstringinstringelse", "doifstructurelisthasnumberelse", "doifstructurelisthaspageelse", "doifsymboldefinedelse", "doifsymbolsetelse", "doiftext", "doiftextelse", "doiftextflowcollectorelse", "doiftextflowelse", "doiftopofpageelse", "doiftypingfileelse", "doifundefined", "doifundefinedcounter", "doifundefinedelse", "doifurldefinedelse", "doifvalue", "doifvalueelse", "doifvaluenothing", "doifvaluenothingelse", "doifvaluesomething", "doifvariable", "doifvariableelse", "doindentation", "dollar", "doloop", "doloopoverlist", "donothing", "dontconvertfont", "dontleavehmode", "dontpermitspacesbetweengroups", "dopositionaction", "doprocesslocalsetups", "doquadrupleargument", "doquadrupleempty", "doquadruplegroupempty", "doquintupleargument", "doquintupleempty", "doquintuplegroupempty", "dorechecknextindentation", "dorecurse", "dorepeatwithcommand", "doreplacefeature", "doresetandafffeature", "doresetattribute", "dorotatebox", "dosetattribute", "dosetleftskipadaption", "dosetrightskipadaption", "dosetupcheckedinterlinespace", "doseventupleargument", "doseventupleempty", "dosingleargument", "dosingleempty", "dosinglegroupempty", "dosixtupleargument", "dosixtupleempty", "dostepwiserecurse", "dosubtractfeature", "dot", "doteq", "doteqdot", "dotfskip", "dotlessI", "dotlessJ", "dotlessi", "dotlessj", "dotlessjstroke", "dotminus", "dotoks", "dotplus", "dotripleargument", "dotripleargumentwithset", "dotripleempty", "dotripleemptywithset", "dotriplegroupempty", "dots", "dottedrightarrow", "doublebar", "doublebond", "doublebrace", "doublebracket", "doublecap", "doublecup", "doubleparent", "doubleprime", "doubleverticalbar", "dowith", "dowithnextbox", "dowithnextboxcontent", "dowithnextboxcontentcs", "dowithnextboxcs", "dowithpargument", "dowithrange", "dowithwargument", "downarrow", "downdasharrow", "downdownarrows", "downharpoonleft", "downharpoonright", "downuparrows", "downwhitearrow", "downzigzagarrow", "dpofstring", "dstroke", "dtail", "dummydigit", "dummyparameter", "dzcaronligature", "dzligature", "eTeX", "eacute", "ebreve", "ecaron", "ecedilla", "ecircumflex", "ecircumflexacute", "ecircumflexdotbelow", "ecircumflexgrave", "ecircumflexhook", "ecircumflextilde", "edefconvertedargument", "ediaeresis", "edotaccent", "edotbelow", "edoublegrave", "efcmaxheight", "efcmaxwidth", "efcminheight", "efcminwidth", "efcparameter", "effect", "egrave", "ehook", "einvertedbreve", "elapsedseconds", "elapsedtime", "eleftarrowfill", "eleftharpoondownfill", "eleftharpoonupfill", "eleftrightarrowfill", "ell", "em", "emacron", "emdash", "emphasisboldface", "emphasistypeface", "emptylines", "emptyset", "emspace", "enabledirectives", "enableexperiments", "enablemode", "enableoutputstream", "enableparpositions", "enableregime", "enabletrackers", "endash", "endnote", "enskip", "enspace", "env", "environment", "envvar", "eogonek", "eoverbarfill", "eoverbracefill", "eoverbracketfill", "eoverparentfill", "epos", "epsilon", "eq", "eqcirc", "eqeq", "eqeqeq", "eqgtr", "eqless", "eqsim", "eqslantgtr", "eqslantless", "equaldigits", "equalscolon", "equiv", "erightarrowfill", "erightharpoondownfill", "erightharpoonupfill", "eta", "eth", "ethiopic", "etilde", "etwoheadrightarrowfill", "eunderbarfill", "eunderbracefill", "eunderbracketfill", "eunderparentfill", "exclamdown", "executeifdefined", "exists", "exitloop", "exitloopnow", "expandcheckedcsname", "expanded", "expandfontsynonym", "expdoif", "expdoifcommonelse", "expdoifelse", "expdoifelsecommon", "expdoifelseinset", "expdoifinsetelse", "expdoifnot", "exponentiale", "externalfigure", "externalfigurecollectionmaxheight", "externalfigurecollectionmaxwidth", "externalfigurecollectionminheight", "externalfigurecollectionminwidth", "externalfigurecollectionparameter", "fakebox", "fallingdotseq", "fastdecrement", "fastincrement", "fastlocalframed", "fastloopfinal", "fastloopindex", "fastscale", "fastsetup", "fastsetupwithargument", "fastsetupwithargumentswapped", "fastswitchtobodyfont", "fastsxsy", "feature", "fence", "fenced", "fetchallmarkings", "fetchallmarks", "fetchmark", "fetchmarking", "fetchonemark", "fetchonemarking", "fetchruntinecommand", "fetchtwomarkings", "fetchtwomarks", "ffiligature", "ffligature", "fflligature", "fhook", "field", "fieldbody", "fieldstack", "fifthoffivearguments", "fifthofsixarguments", "figurefilename", "figurefilepath", "figurefiletype", "figurefullname", "figureheight", "figurenaturalheight", "figurenaturalwidth", "figurespace", "figuresymbol", "figurewidth", "filename", "filigature", "filledhboxb", "filledhboxc", "filledhboxg", "filledhboxk", "filledhboxm", "filledhboxr", "filledhboxy", "filler", "fillinline", "fillinrules", "fillintext", "filterfromnext", "filterfromvalue", "filterpages", "filterreference", "findtwopassdata", "finishregisterentry", "firstcharacter", "firstcounter", "firstcountervalue", "firstoffivearguments", "firstoffourarguments", "firstofoneargument", "firstofoneunexpanded", "firstofsixarguments", "firstofthreearguments", "firstofthreeunexpanded", "firstoftwoarguments", "firstoftwounexpanded", "firstrealpage", "firstrealpagenumber", "firstsubcountervalue", "firstsubpage", "firstsubpagenumber", "firstuserpage", "firstuserpagenumber", "fitfield", "fitfieldframed", "fittopbaselinegrid", "fiveeighths", "fivesixths", "fixedspace", "fixedspaces", "flag", "flat", "flligature", "floatuserdataparameter", "flushbox", "flushboxregister", "flushcollector", "flushedrightlastline", "flushlayer", "flushlocalfloats", "flushnextbox", "flushnotes", "flushoutputstream", "flushshapebox", "flushtextflow", "flushtokens", "flushtoks", "fontalternative", "fontbody", "fontchar", "fontcharbyindex", "fontclass", "fontclassname", "fontface", "fontfeaturelist", "fontsize", "fontstyle", "footnote", "footnotetext", "forall", "forcecharacterstripping", "forcelocalfloats", "forgeteverypar", "forgetparameters", "forgetragged", "formula", "formulanumber", "foundbox", "fourfifths", "fourperemspace", "fourthoffivearguments", "fourthoffourarguments", "fourthofsixarguments", "frac", "framed", "frameddimension", "framedparameter", "framedtext", "freezedimenmacro", "freezemeasure", "frenchspacing", "from", "fromlinenote", "frown", "frozenhbox", "frule", "gacute", "gamma", "gbreve", "gcaron", "gcircumflex", "gcommaaccent", "gdefconvertedargument", "gdefconvertedcommand", "gdotaccent", "ge", "geq", "geqq", "geqslant", "getMPdrawing", "getMPlayer", "getboxfromcache", "getboxllx", "getboxlly", "getbuffer", "getbufferdata", "getcommacommandsize", "getcommalistsize", "getdayoftheweek", "getdayspermonth", "getdefinedbuffer", "getdocumentargument", "getdocumentargumentdefault", "getdocumentfilename", "getdummyparameters", "getemptyparameters", "geteparameters", "getexpandedparameters", "getfiguredimensions", "getfirstcharacter", "getfirsttwopassdata", "getfromcommacommand", "getfromcommalist", "getfromtwopassdata", "getglyphdirect", "getglyphstyled", "getgparameters", "getlasttwopassdata", "getlocalfloat", "getlocalfloats", "getmarking", "getmessage", "getnamedglyphdirect", "getnamedglyphstyled", "getnamedtwopassdatalist", "getnaturaldimensions", "getnoflines", "getobject", "getobjectdimensions", "getpaletsize", "getparameters", "getprivatechar", "getprivateslot", "getrandomcount", "getrandomdimen", "getrandomfloat", "getrandomnumber", "getrandomseed", "getraweparameters", "getrawgparameters", "getrawnoflines", "getrawparameters", "getrawxparameters", "getreference", "getreferenceentry", "getroundednoflines", "gets", "getsubstring", "gettwopassdata", "gettwopassdatalist", "getuvalue", "getvalue", "getvariable", "getvariabledefault", "getxparameters", "gg", "ggg", "gggtr", "gimel", "globaldisablemode", "globalenablemode", "globalletempty", "globalpopbox", "globalpopmacro", "globalpreventmode", "globalprocesscommalist", "globalpushbox", "globalpushmacro", "globalswapcounts", "globalswapdimens", "globalswapmacros", "globalundefine", "glyphfontfile", "gnapprox", "gneqq", "gnsim", "gobbledoubleempty", "gobbleeightarguments", "gobblefivearguments", "gobblefiveoptionals", "gobblefourarguments", "gobblefouroptionals", "gobbleninearguments", "gobbleoneargument", "gobbleoneoptional", "gobblesevenarguments", "gobblesingleempty", "gobblesixarguments", "gobblespacetokens", "gobbletenarguments", "gobblethreearguments", "gobblethreeoptionals", "gobbletwoarguments", "gobbletwooptionals", "gobbleuntil", "gobbleuntilrelax", "godown", "goto", "gotobox", "gotopage", "grabbufferdata", "grabbufferdatadirect", "grabuntil", "grave", "graycolor", "grayvalue", "greedysplitstring", "greekAlpha", "greekAlphadasia", "greekAlphadasiaperispomeni", "greekAlphadasiatonos", "greekAlphadasiavaria", "greekAlphaiotasub", "greekAlphaiotasubdasia", "greekAlphaiotasubdasiaperispomeni", "greekAlphaiotasubdasiatonos", "greekAlphaiotasubdasiavaria", "greekAlphaiotasubpsili", "greekAlphaiotasubpsiliperispomeni", "greekAlphaiotasubpsilitonos", "greekAlphaiotasubpsilivaria", "greekAlphamacron", "greekAlphapsili", "greekAlphapsiliperispomeni", "greekAlphapsilitonos", "greekAlphapsilivaria", "greekAlphatonos", "greekAlphavaria", "greekAlphavrachy", "greekBeta", "greekChi", "greekCoronis", "greekDelta", "greekEpsilon", "greekEpsilondasia", "greekEpsilondasiatonos", "greekEpsilondasiavaria", "greekEpsilonpsili", "greekEpsilonpsilitonos", "greekEpsilonpsilivaria", "greekEpsilontonos", "greekEpsilonvaria", "greekEta", "greekEtadasia", "greekEtadasiaperispomeni", "greekEtadasiatonos", "greekEtadasiavaria", "greekEtaiotasub", "greekEtaiotasubdasia", "greekEtaiotasubdasiaperispomeni", "greekEtaiotasubdasiatonos", "greekEtaiotasubdasiavaria", "greekEtaiotasubpsili", "greekEtaiotasubpsiliperispomeni", "greekEtaiotasubpsilitonos", "greekEtaiotasubpsilivaria", "greekEtapsili", "greekEtapsiliperispomeni", "greekEtapsilitonos", "greekEtapsilivaria", "greekEtatonos", "greekEtavaria", "greekGamma", "greekIota", "greekIotadasia", "greekIotadasiaperispomeni", "greekIotadasiatonos", "greekIotadasiavaria", "greekIotadialytika", "greekIotamacron", "greekIotapsili", "greekIotapsiliperispomeni", "greekIotapsilitonos", "greekIotapsilivaria", "greekIotatonos", "greekIotavaria", "greekIotavrachy", "greekKappa", "greekLambda", "greekMu", "greekNu", "greekOmega", "greekOmegadasia", "greekOmegadasiaperispomeni", "greekOmegadasiatonos", "greekOmegadasiavaria", "greekOmegaiotasub", "greekOmegaiotasubdasia", "greekOmegaiotasubdasiaperispomeni", "greekOmegaiotasubdasiatonos", "greekOmegaiotasubdasiavaria", "greekOmegaiotasubpsili", "greekOmegaiotasubpsiliperispomeni", "greekOmegaiotasubpsilitonos", "greekOmegaiotasubpsilivaria", "greekOmegapsili", "greekOmegapsiliperispomeni", "greekOmegapsilitonos", "greekOmegapsilivaria", "greekOmegatonos", "greekOmegavaria", "greekOmicron", "greekOmicrondasia", "greekOmicrondasiatonos", "greekOmicrondasiavaria", "greekOmicronpsili", "greekOmicronpsilitonos", "greekOmicronpsilivaria", "greekOmicrontonos", "greekOmicronvaria", "greekPhi", "greekPi", "greekPsi", "greekRho", "greekRhodasia", "greekSigma", "greekSigmalunate", "greekTau", "greekTheta", "greekUpsilon", "greekUpsilondasia", "greekUpsilondasiaperispomeni", "greekUpsilondasiatonos", "greekUpsilondasiavaria", "greekUpsilondialytika", "greekUpsilonmacron", "greekUpsilontonos", "greekUpsilonvaria", "greekUpsilonvrachy", "greekXi", "greekZeta", "greekalpha", "greekalphadasia", "greekalphadasiaperispomeni", "greekalphadasiatonos", "greekalphadasiavaria", "greekalphaiotasub", "greekalphaiotasubdasia", "greekalphaiotasubdasiaperispomeni", "greekalphaiotasubdasiatonos", "greekalphaiotasubdasiavaria", "greekalphaiotasubperispomeni", "greekalphaiotasubpsili", "greekalphaiotasubpsiliperispomeni", "greekalphaiotasubpsilitonos", "greekalphaiotasubpsilivaria", "greekalphaiotasubtonos", "greekalphaiotasubvaria", "greekalphamacron", "greekalphaoxia", "greekalphaperispomeni", "greekalphapsili", "greekalphapsiliperispomeni", "greekalphapsilitonos", "greekalphapsilivaria", "greekalphatonos", "greekalphavaria", "greekalphavrachy", "greekbeta", "greekchi", "greekdasia", "greekdasiaperispomeni", "greekdasiatonos", "greekdasiavaria", "greekdelta", "greekdialytikaperispomeni", "greekdialytikatonos", "greekdialytikavaria", "greekdigamma", "greekepsilon", "greekepsilonalt", "greekepsilondasia", "greekepsilondasiatonos", "greekepsilondasiavaria", "greekepsilonoxia", "greekepsilonpsili", "greekepsilonpsilitonos", "greekepsilonpsilivaria", "greekepsilontonos", "greekepsilonvaria", "greeketa", "greeketadasia", "greeketadasiaperispomeni", "greeketadasiatonos", "greeketadasiavaria", "greeketaiotasub", "greeketaiotasubdasia", "greeketaiotasubdasiaperispomeni", "greeketaiotasubdasiatonos", "greeketaiotasubdasiavaria", "greeketaiotasubperispomeni", "greeketaiotasubpsili", "greeketaiotasubpsiliperispomeni", "greeketaiotasubpsilitonos", "greeketaiotasubpsilivaria", "greeketaiotasubtonos", "greeketaiotasubvaria", "greeketaoxia", "greeketaperispomeni", "greeketapsili", "greeketapsiliperispomeni", "greeketapsilitonos", "greeketapsilivaria", "greeketatonos", "greeketavaria", "greekfinalsigma", "greekgamma", "greekiota", "greekiotadasia", "greekiotadasiaperispomeni", "greekiotadasiatonos", "greekiotadasiavaria", "greekiotadialytika", "greekiotadialytikaperispomeni", "greekiotadialytikatonos", "greekiotadialytikavaria", "greekiotamacron", "greekiotaoxia", "greekiotaperispomeni", "greekiotapsili", "greekiotapsiliperispomeni", "greekiotapsilitonos", "greekiotapsilivaria", "greekiotatonos", "greekiotavaria", "greekiotavrachy", "greekkappa", "greekkoppa", "greeklambda", "greekmu", "greeknu", "greeknumerals", "greeknumkoppa", "greekomega", "greekomegadasia", "greekomegadasiaperispomeni", "greekomegadasiatonos", "greekomegadasiavaria", "greekomegaiotasub", "greekomegaiotasubdasia", "greekomegaiotasubdasiaperispomeni", "greekomegaiotasubdasiatonos", "greekomegaiotasubdasiavaria", "greekomegaiotasubperispomeni", "greekomegaiotasubpsili", "greekomegaiotasubpsiliperispomeni", "greekomegaiotasubpsilitonos", "greekomegaiotasubpsilivaria", "greekomegaiotasubtonos", "greekomegaiotasubvaria", "greekomegaoxia", "greekomegaperispomeni", "greekomegapsili", "greekomegapsiliperispomeni", "greekomegapsilitonos", "greekomegapsilivaria", "greekomegatonos", "greekomegavaria", "greekomicron", "greekomicrondasia", "greekomicrondasiatonos", "greekomicrondasiavaria", "greekomicronoxia", "greekomicronpsili", "greekomicronpsilitonos", "greekomicronpsilivaria", "greekomicrontonos", "greekomicronvaria", "greekoxia", "greekperispomeni", "greekphi", "greekphialt", "greekpi", "greekpialt", "greekprosgegrammeni", "greekpsi", "greekpsili", "greekpsiliperispomeni", "greekpsilitonos", "greekpsilivaria", "greekrho", "greekrhoalt", "greekrhodasia", "greekrhopsili", "greeksampi", "greeksigma", "greeksigmalunate", "greekstigma", "greektau", "greektheta", "greekthetaalt", "greektonos", "greekupsilon", "greekupsilondasia", "greekupsilondasiaperispomeni", "greekupsilondasiatonos", "greekupsilondasiavaria", "greekupsilondiaeresis", "greekupsilondialytikaperispomeni", "greekupsilondialytikatonos", "greekupsilondialytikavaria", "greekupsilonmacron", "greekupsilonoxia", "greekupsilonperispomeni", "greekupsilonpsili", "greekupsilonpsiliperispomeni", "greekupsilonpsilitonos", "greekupsilonpsilivaria", "greekupsilontonos", "greekupsilonvaria", "greekupsilonvrachy", "greekvaria", "greekxi", "greekzeta", "grid", "groupedcommand", "gsetboxllx", "gsetboxlly", "gstroke", "gt", "gtrapprox", "gtrdot", "gtreqless", "gtreqqless", "gtrless", "gtrsim", "guilsingleleft", "guilsingleright", "gujaratinumerals", "gurmurkhinumerals", "hairline", "hairspace", "halflinestrut", "halfstrut", "halfwaybox", "handletokens", "handwritten", "hangul", "hanzi", "hash", "hat", "hbar", "hboxofvbox", "hboxreference", "hcaron", "hcircumflex", "hdofstring", "headhbox", "headlanguage", "headnumber", "headnumbercontent", "headnumberdistance", "headnumberwidth", "headreferenceattributes", "headsetupspacing", "headtext", "headtextcontent", "headtextdistance", "headtexts", "headtextwidth", "headvbox", "headwidth", "heartsuit", "hebrewAlef", "hebrewAyin", "hebrewBet", "hebrewDalet", "hebrewGimel", "hebrewHe", "hebrewHet", "hebrewKaf", "hebrewKaffinal", "hebrewLamed", "hebrewMem", "hebrewMemfinal", "hebrewNun", "hebrewNunfinal", "hebrewPe", "hebrewPefinal", "hebrewQof", "hebrewResh", "hebrewSamekh", "hebrewShin", "hebrewTav", "hebrewTet", "hebrewTsadi", "hebrewTsadifinal", "hebrewVav", "hebrewYod", "hebrewZayin", "heightanddepthofstring", "heightofstring", "heightspanningtext", "helptext", "hglue", "hiddenbar", "hiddencitation", "hiddencite", "hideblocks", "high", "highlight", "highordinalstr", "hilo", "himilo", "hl", "hookleftarrow", "hookrightarrow", "horizontalgrowingbar", "horizontalpositionbar", "hphantom", "hpos", "hsizefraction", "hslash", "hsmash", "hsmashbox", "hsmashed", "hspace", "hstroke", "htdpofstring", "htofstring", "hyphen", "hyphenatedcoloredword", "hyphenatedfile", "hyphenatedfilename", "hyphenatedhbox", "hyphenatedpar", "hyphenatedurl", "hyphenatedword", "iacute", "ibox", "ibreve", "icaron", "icircumflex", "ideographichalffillspace", "ideographicspace", "idiaeresis", "idotaccent", "idotbelow", "idoublegrave", "ifassignment", "iff", "ifinobject", "ifinoutputstream", "ifparameters", "iftrialtypesetting", "ignoreimplicitspaces", "ignorevalue", "igrave", "ihook", "iiiint", "iiiintop", "iiint", "iiintop", "iint", "iintop", "iinvertedbreve", "ijligature", "imacron", "imaginaryi", "imaginaryj", "imath", "immediatesavetwopassdata", "impliedby", "implies", "imply", "in", "includemenu", "includeversioninfo", "increment", "incrementcounter", "incrementedcounter", "incrementpagenumber", "incrementsubpagenumber", "incrementvalue", "indentation", "index", "infofont", "infofontbold", "inframed", "infty", "infull", "inheritparameter", "inhibitblank", "ininner", "ininneredge", "ininnermargin", "initializeboxstack", "inleft", "inleftedge", "inleftmargin", "inline", "inlinebuffer", "inlinedbox", "inlinemath", "inlinemathematics", "inlinemessage", "inlineordisplaymath", "inlineprettyprintbuffer", "inlinerange", "inmargin", "inmframed", "innerflushshapebox", "inother", "inouter", "inouteredge", "inoutermargin", "input", "inputfilebarename", "inputfilename", "inputfilerealsuffix", "inputfilesuffix", "inputgivenfile", "inright", "inrightedge", "inrightmargin", "insertpages", "installactionhandler", "installactivecharacter", "installanddefineactivecharacter", "installattributestack", "installautocommandhandler", "installautosetuphandler", "installbasicautosetuphandler", "installbasicparameterhandler", "installbottomframerenderer", "installcommandhandler", "installcorenamespace", "installdefinehandler", "installdefinitionset", "installdefinitionsetmember", "installdirectcommandhandler", "installdirectparameterhandler", "installdirectparametersethandler", "installdirectsetuphandler", "installdirectstyleandcolorhandler", "installframedautocommandhandler", "installframedcommandhandler", "installlanguage", "installleftframerenderer", "installnamespace", "installoutputroutine", "installpagearrangement", "installparameterhandler", "installparameterhashhandler", "installparametersethandler", "installparentinjector", "installrightframerenderer", "installrootparameterhandler", "installsetuphandler", "installsetuponlycommandhandler", "installshipoutmethod", "installsimplecommandhandler", "installsimpleframedcommandhandler", "installstyleandcolorhandler", "installswitchcommandhandler", "installswitchsetuphandler", "installtexdirective", "installtextracker", "installtopframerenderer", "installunitsseparator", "installunitsspace", "installversioninfo", "int", "intclockwise", "integerrounding", "integers", "interactionbar", "interactionbuttons", "interactionmenu", "intercal", "intertext", "intop", "invisibletimes", "invokepageheandler", "iogonek", "iota", "istltdir", "istrtdir", "italic", "italicbold", "italiccorrection", "italicface", "item", "items", "itemtag", "itilde", "jcaron", "jcircumflex", "jmath", "jobfilename", "jobfilesuffix", "kap", "kappa", "kcaron", "kcommaaccent", "keepblocks", "keeplinestogether", "keepunwantedspaces", "kerncharacters", "khook", "kkra", "koreancirclenumerals", "koreannumerals", "koreannumeralsc", "koreannumeralsp", "koreanparentnumerals", "lVert", "labellanguage", "labeltext", "labeltexts", "lacute", "lambda", "lambdabar", "land", "langle", "language", "languageCharacters", "languagecharacters", "languagecharwidth", "lastcounter", "lastcountervalue", "lastdigit", "lastlinewidth", "lastnaturalboxdp", "lastnaturalboxht", "lastnaturalboxwd", "lastpredefinedsymbol", "lastrealpage", "lastrealpagenumber", "lastsubcountervalue", "lastsubpage", "lastsubpagenumber", "lasttwodigits", "lastuserpage", "lastuserpagenumber", "lateluacode", "latin", "layeredtext", "layerheight", "layerwidth", "lazysavetaggedtwopassdata", "lazysavetwopassdata", "lbar", "lbox", "lbrace", "lbracket", "lcaron", "lceil", "lcommaaccent", "lcurl", "ldotmiddle", "ldotp", "ldots", "le", "leadsto", "left", "leftaligned", "leftarrow", "leftarrowtail", "leftarrowtriangle", "leftbottombox", "leftbox", "leftdasharrow", "leftguillemot", "leftharpoondown", "leftharpoonup", "lefthbox", "leftheadtext", "leftlabeltext", "leftleftarrows", "leftline", "leftmathlabeltext", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "leftrightarrow", "leftrightarrows", "leftrightarrowtriangle", "leftrightharpoons", "leftrightsquigarrow", "leftskipadaption", "leftsquigarrow", "leftsubguillemot", "leftthreetimes", "lefttopbox", "lefttoright", "lefttorighthbox", "lefttorightvbox", "lefttorightvtop", "leftwavearrow", "leftwhitearrow", "leq", "leqq", "leqslant", "lessapprox", "lessdot", "lesseqgtr", "lesseqqgtr", "lessgtr", "lesssim", "letbeundefined", "letcatcodecommand", "letcscsname", "letcsnamecs", "letcsnamecsname", "letdummyparameter", "letempty", "letgvalue", "letgvalueempty", "letgvalurelax", "letterampersand", "letterat", "letterbackslash", "letterbar", "letterbgroup", "letterclosebrace", "lettercolon", "letterdollar", "letterdoublequote", "letteregroup", "letterescape", "letterexclamationmark", "letterhash", "letterhat", "letterleftbrace", "letterleftbracket", "letterleftparenthesis", "letterless", "lettermore", "letteropenbrace", "letterpercent", "letterquestionmark", "letterrightbrace", "letterrightbracket", "letterrightparenthesis", "lettersinglequote", "letterslash", "letterspacing", "lettertilde", "letterunderscore", "letvalue", "letvalueempty", "letvaluerelax", "lfence", "lfloor", "lgroup", "lhbox", "lhooknwarrow", "lhooksearrow", "limitatefirstline", "limitatelines", "limitatetext", "line", "linefeed", "linenote", "linespanningtext", "linethickness", "linterval", "listcitation", "listcite", "listlength", "listnamespaces", "ljligature", "ll", "llangle", "llap", "llbracket", "llcorner", "lll", "llless", "lmoustache", "lnapprox", "lneq", "lneqq", "lnot", "lnsim", "loadanyfile", "loadanyfileonce", "loadbtxdefinitionfile", "loadbtxreplacementfile", "loadcldfile", "loadcldfileonce", "loadfontgoodies", "loadluafile", "loadluafileonce", "loadspellchecklist", "loadtexfile", "loadtexfileonce", "loadtypescriptfile", "localframed", "localframedwithsettings", "localhsize", "localpopbox", "localpopmacro", "localpushbox", "localpushmacro", "localundefine", "locatedfilepath", "locatefilepath", "locfilename", "logo", "lohi", "lointerval", "lomihi", "longleftarrow", "longleftrightarrow", "longmapsfrom", "longmapsto", "longrightarrow", "longrightsquigarrow", "looparrowleft", "looparrowright", "lor", "low", "lowerbox", "lowercased", "lowercasestring", "lowerleftdoubleninequote", "lowerleftsingleninequote", "lowerrightdoubleninequote", "lowerrightsingleninequote", "lozenge", "lparent", "lrcorner", "lrointerval", "lrtbbox", "lstroke", "lt", "ltimes", "ltop", "luaTeX", "luacode", "luaconditional", "luaenvironment", "luaexpanded", "luaexpr", "luafunction", "luajitTeX", "luamajorversion", "luaminorversion", "luaparameterset", "luasetup", "luaversion", "lvert", "m", "mLeftarrow", "mLeftrightarrow", "mRightarrow", "mainlanguage", "makecharacteractive", "makerawcommalist", "makestrutofbox", "maltese", "mapfontsize", "mapsdown", "mapsfrom", "mapsto", "mapsup", "margindata", "margintext", "markcontent", "marking", "markinjector", "markpage", "mat", "math", "mathampersand", "mathbf", "mathbi", "mathblackboard", "mathbs", "mathdefault", "mathdollar", "mathdouble", "mathematics", "mathfraktur", "mathfunction", "mathhash", "mathhyphen", "mathit", "mathitalic", "mathlabellanguage", "mathlabeltext", "mathlabeltexts", "mathop", "mathover", "mathpercent", "mathrm", "mathscript", "mathsl", "mathss", "mathtext", "mathtextbf", "mathtextbi", "mathtextbs", "mathtextit", "mathtextsl", "mathtexttf", "mathtf", "mathtriplet", "mathtt", "mathunder", "mathupright", "mathword", "mathwordbf", "mathwordbi", "mathwordbs", "mathwordit", "mathwordsl", "mathwordtf", "maxaligned", "mbox", "mcframed", "measure", "measured", "measuredangle", "measuredeq", "medskip", "medspace", "menubutton", "mequal", "message", "metaTeX", "mfence", "mframed", "mfunction", "mfunctionlabeltext", "mhbox", "mho", "mhookleftarrow", "mhookrightarrow", "mid", "midaligned", "middle", "middlealigned", "middlebox", "midhbox", "minimalhbox", "minus", "minuscolon", "mirror", "mixedcaps", "mkvibuffer", "mleftarrow", "mleftharpoondown", "mleftharpoonup", "mleftrightarrow", "mleftrightharpoons", "mmapsto", "models", "moduleparameter", "molecule", "mono", "monobold", "mononormal", "month", "monthlong", "monthshort", "mp", "mprandomnumber", "mrel", "mrightarrow", "mrightharpoondown", "mrightharpoonup", "mrightleftharpoons", "mrightoverleftarrow", "mtext", "mtriplerel", "mtwoheadleftarrow", "mtwoheadrightarrow", "mu", "multimap", "nHdownarrow", "nHuparrow", "nLeftarrow", "nLeftrightarrow", "nRightarrow", "nVDash", "nVdash", "nVleftarrow", "nVleftrightarrow", "nVrightarrow", "nabla", "nacute", "namedheadnumber", "namedstructureheadlocation", "namedstructureuservariable", "namedstructurevariable", "namedtaggedlabeltexts", "napostrophe", "napprox", "napproxEq", "narrownobreakspace", "nasymp", "natural", "naturalhbox", "naturalhpack", "naturalnumbers", "naturalvbox", "naturalvcenter", "naturalvpack", "naturalvtop", "naturalwd", "ncaron", "ncommaaccent", "ncong", "ncurl", "ndivides", "ne", "nearrow", "neg", "negatecolorbox", "negated", "negativesign", "negthinspace", "neng", "neq", "nequiv", "neswarrow", "newattribute", "newcatcodetable", "newcounter", "newevery", "newfrenchspacing", "newmode", "newsignal", "newsystemmode", "nexists", "nextbox", "nextboxdp", "nextboxht", "nextboxhtdp", "nextboxwd", "nextcounter", "nextcountervalue", "nextdepth", "nextparagraphs", "nextrealpage", "nextrealpagenumber", "nextsubcountervalue", "nextsubpage", "nextsubpagenumber", "nextuserpage", "nextuserpagenumber", "ngeq", "ngrave", "ngtr", "ngtrless", "ngtrsim", "ni", "nihongo", "nin", "njligature", "nleftarrow", "nleftrightarrow", "nleq", "nless", "nlessgtr", "nlesssim", "nmid", "nni", "nobar", "nobreakspace", "nocap", "nocitation", "nocite", "nodetostring", "noffigurepages", "noflines", "noflocalfloats", "noheaderandfooterlines", "noheightstrut", "noindentation", "noitem", "nonfrenchspacing", "nonmathematics", "normal", "normalboldface", "normalframedwithsettings", "normalitalicface", "normalizebodyfontsize", "normalizedfontsize", "normalizefontdepth", "normalizefontheight", "normalizefontline", "normalizefontwidth", "normalizetextdepth", "normalizetextheight", "normalizetextline", "normalizetextwidth", "normalslantedface", "normaltypeface", "nospace", "not", "note", "notesymbol", "notin", "notopandbottomlines", "notragged", "nowns", "nparallel", "nprec", "npreccurlyeq", "nrightarrow", "nsim", "nsimeq", "nsqsubseteq", "nsqsupseteq", "nsubset", "nsubseteq", "nsucc", "nsucccurlyeq", "nsupset", "nsupseteq", "ntilde", "ntimes", "ntriangleleft", "ntrianglelefteq", "ntriangleright", "ntrianglerighteq", "nu", "numberofpoints", "numbers", "nvDash", "nvdash", "nvleftarrow", "nvleftrightarrow", "nvrightarrow", "nwarrow", "nwsearrow", "oacute", "obeydepth", "objectdepth", "objectheight", "objectmargin", "objectwidth", "obox", "obreve", "ocaron", "ocircumflex", "ocircumflexacute", "ocircumflexdotbelow", "ocircumflexgrave", "ocircumflexhook", "ocircumflextilde", "odiaeresis", "odiaeresismacron", "odot", "odotaccent", "odotaccentmacron", "odotbelow", "odoublegrave", "oeligature", "offset", "offsetbox", "ograve", "ohm", "ohook", "ohorn", "ohornacute", "ohorndotbelow", "ohorngrave", "ohornhook", "ohorntilde", "ohungarumlaut", "oiiint", "oiint", "oint", "ointclockwise", "ointctrclockwise", "oinvertedbreve", "omacron", "omega", "omicron", "ominus", "onedigitrounding", "oneeighth", "onefifth", "onehalf", "onequarter", "onesixth", "onesuperior", "onethird", "oogonek", "oogonekmacron", "operatorlanguage", "operatortext", "oplus", "ordfeminine", "ordinaldaynumber", "ordinalstr", "ordmasculine", "ornamenttext", "oslash", "ostroke", "ostrokeacute", "otilde", "otildemacron", "otimes", "outputfilename", "outputstreambox", "outputstreamcopy", "outputstreamunvbox", "outputstreamunvcopy", "over", "overbar", "overbars", "overbarunderbar", "overbrace", "overbraceunderbrace", "overbracket", "overbracketunderbracket", "overlaybutton", "overlaycolor", "overlaydepth", "overlayfigure", "overlayheight", "overlaylinecolor", "overlaylinewidth", "overlayoffset", "overlayrollbutton", "overlaywidth", "overleftarrow", "overloaderror", "overparent", "overparentunderparent", "overrightarrow", "overset", "overstrike", "overstrikes", "owns", "page", "pagearea", "pagebreak", "pagefigure", "pagegridspanwidth", "pageinjection", "pagenumber", "pagereference", "pagestaterealpage", "paletsize", "paragraphmark", "parallel", "part", "partial", "pdfTeX", "pdfactualtext", "pdfbackendactualtext", "pdfbackendcurrentresources", "pdfbackendsetcatalog", "pdfbackendsetcolorspace", "pdfbackendsetextgstate", "pdfbackendsetinfo", "pdfbackendsetname", "pdfbackendsetpageattribute", "pdfbackendsetpageresource", "pdfbackendsetpagesattribute", "pdfbackendsetpattern", "pdfbackendsetshade", "pdfcolor", "pdfeTeX", "percent", "percentdimen", "periodcentered", "periods", "permitcaretescape", "permitcircumflexescape", "permitspacesbetweengroups", "perp", "persiandecimals", "persiannumerals", "perthousand", "phantom", "phantombox", "phi", "phook", "pi", "pickupgroupedcommand", "pitchfork", "placeattachments", "placebookmarks", "placebtxrendering", "placechemical", "placecitation", "placecombinedlist", "placecomments", "placecontent", "placecurrentformulanumber", "placedbox", "placefigure", "placefloat", "placefloatwithsetups", "placefootnotes", "placeformula", "placeframed", "placegraphic", "placeheadnumber", "placeheadtext", "placehelp", "placeindex", "placeinitial", "placeintermezzo", "placelayer", "placelayeredtext", "placelegend", "placelist", "placelistofabbreviations", "placelistofchemicals", "placelistoffigures", "placelistofgraphics", "placelistofintermezzi", "placelistoflogos", "placelistofpublications", "placelistofsorts", "placelistofsynonyms", "placelistoftables", "placelocalfootnotes", "placelocalnotes", "placement", "placenamedfloat", "placenamedformula", "placenotes", "placeongrid", "placeontopofeachother", "placepagenumber", "placepairedbox", "placeparallel", "placerawlist", "placeregister", "placerenderingwindow", "placesidebyside", "placesubformula", "placetable", "pm", "popattribute", "popmacro", "popmode", "popsystemmode", "position", "positionoverlay", "positionregionoverlay", "positivesign", "postponenotes", "prec", "precapprox", "preccurlyeq", "preceq", "preceqq", "precnapprox", "precneq", "precneqq", "precnsim", "precsim", "predefinedfont", "predefinefont", "predefinesymbol", "prefixedpagenumber", "prefixlanguage", "prefixtext", "prependetoks", "prependgvalue", "prependtocommalist", "prependtoks", "prependtoksonce", "prependvalue", "presetbtxlabeltext", "presetdocument", "presetfieldsymbols", "presetheadtext", "presetlabeltext", "presetmathlabeltext", "presetoperatortext", "presetprefixtext", "presetsuffixtext", "presettaglabeltext", "presetunittext", "pretocommalist", "prettyprintbuffer", "prevcounter", "prevcountervalue", "preventmode", "prevrealpage", "prevrealpagenumber", "prevsubcountervalue", "prevsubpage", "prevsubpagenumber", "prevuserpage", "prevuserpagenumber", "prime", "primes", "procent", "processMPbuffer", "processMPfigurefile", "processaction", "processallactionsinset", "processassignlist", "processassignmentcommand", "processassignmentlist", "processbetween", "processblocks", "processbodyfontenvironmentlist", "processcolorcomponents", "processcommacommand", "processcommalist", "processcommalistwithparameters", "processcontent", "processfile", "processfilemany", "processfilenone", "processfileonce", "processfirstactioninset", "processisolatedchars", "processisolatedwords", "processlinetablebuffer", "processlinetablefile", "processlist", "processmonth", "processranges", "processseparatedlist", "processtexbuffer", "processtokens", "processuntil", "processxtablebuffer", "processyear", "prod", "product", "profiledbox", "profilegivenbox", "program", "project", "propto", "pseudoMixedCapped", "pseudoSmallCapped", "pseudoSmallcapped", "pseudosmallcapped", "psi", "punctuationspace", "purenumber", "pushattribute", "pushbutton", "pushmacro", "pushmode", "pushoutputstream", "pushsystemmode", "putboxincache", "putnextboxincache", "qquad", "quad", "quadrupleprime", "quads", "quarterstrut", "questiondown", "questionedeq", "quitcommalist", "quitprevcommalist", "quittypescriptscanning", "quotation", "quote", "quotedbl", "quotedblbase", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "quotesingle", "quotesinglebase", "rVert", "racute", "raggedbottom", "raggedcenter", "raggedleft", "raggedright", "raggedwidecenter", "raisebox", "randomizetext", "randomnumber", "rangle", "rationals", "rawcounter", "rawcountervalue", "rawdate", "rawdoifelseinset", "rawdoifinset", "rawdoifinsetelse", "rawgetparameters", "rawprocessaction", "rawprocesscommacommand", "rawprocesscommalist", "rawstructurelistuservariable", "rawsubcountervalue", "rbox", "rbrace", "rbracket", "rcaron", "rceil", "rcommaaccent", "rdoublegrave", "readfile", "readfixfile", "readjobfile", "readlocfile", "readsetfile", "readsysfile", "readtexfile", "readxmlfile", "realSmallCapped", "realSmallcapped", "realpagenumber", "reals", "realsmallcapped", "recursedepth", "recurselevel", "recursestring", "redoconvertfont", "ref", "reference", "referenceprefix", "referring", "registerattachment", "registerctxluafile", "registered", "registerexternalfigure", "registerfontclass", "registerhyphenationexception", "registerhyphenationpattern", "registermenubuttons", "registersort", "registersynonym", "registerunit", "regular", "relatemarking", "relateparameterhandlers", "relaxvalueifundefined", "relbar", "remainingcharacters", "remark", "removebottomthings", "removedepth", "removefromcommalist", "removelastskip", "removelastspace", "removemarkedcontent", "removepunctuation", "removesubstring", "removetoks", "removeunwantedspaces", "replacefeature", "replaceincommalist", "replaceword", "rescan", "rescanwithsetup", "resetMPdrawing", "resetMPenvironment", "resetMPinstance", "resetallattributes", "resetandaddfeature", "resetbar", "resetboxesincache", "resetbreakpoints", "resetbuffer", "resetcharacteralign", "resetcharacterkerning", "resetcharacterspacing", "resetcharacterstripping", "resetcollector", "resetcounter", "resetdigitsmanipulation", "resetdirection", "resetfeature", "resetflag", "resetfontcolorsheme", "resetfontfallback", "resetfontsolution", "resethyphenationfeatures", "resetinjector", "resetinteractionmenu", "resetitaliccorrection", "resetlayer", "resetlocalfloats", "resetmarker", "resetmarking", "resetmode", "resetpagenumber", "resetparallel", "resetpath", "resetpenalties", "resetprofile", "resetrecurselevel", "resetreference", "resetreplacement", "resetscript", "resetsetups", "resetshownsynonyms", "resetsubpagenumber", "resetsymbolset", "resetsystemmode", "resettimer", "resettrackers", "resettrialtypesetting", "resetusedsortings", "resetusedsynonyms", "resetuserpagenumber", "resetvalue", "resetvisualizers", "reshapebox", "resolvedglyphdirect", "resolvedglyphstyled", "restartcounter", "restorebox", "restorecatcodes", "restorecounter", "restorecurrentattributes", "restoreendofline", "restoreglobalbodyfont", "restriction", "reusableMPgraphic", "reuseMPgraphic", "reuserandomseed", "reverseddoubleprime", "reversedprime", "reversedtripleprime", "revivefeature", "rfence", "rfloor", "rgroup", "rhbox", "rho", "rhooknearrow", "rhookswarrow", "right", "rightaligned", "rightangle", "rightarrow", "rightarrowbar", "rightarrowtail", "rightarrowtriangle", "rightbottombox", "rightbox", "rightdasharrow", "rightguillemot", "rightharpoondown", "rightharpoonup", "righthbox", "rightheadtext", "rightlabeltext", "rightleftarrows", "rightleftharpoons", "rightline", "rightmathlabeltext", "rightorleftpageaction", "rightrightarrows", "rightskipadaption", "rightsquigarrow", "rightsubguillemot", "rightthreearrows", "rightthreetimes", "righttoleft", "righttolefthbox", "righttoleftvbox", "righttoleftvtop", "righttopbox", "rightwavearrow", "rightwhitearrow", "ring", "rinterval", "rinvertedbreve", "risingdotseq", "rlap", "rlointerval", "rmoustache", "rneq", "robustaddtocommalist", "robustdoifelseinset", "robustdoifinsetelse", "robustpretocommalist", "rointerval", "rollbutton", "roman", "romanC", "romanD", "romanI", "romanII", "romanIII", "romanIV", "romanIX", "romanL", "romanM", "romanV", "romanVI", "romanVII", "romanVIII", "romanX", "romanXI", "romanXII", "romanc", "romand", "romani", "romanii", "romaniii", "romaniv", "romanix", "romanl", "romanm", "romannumerals", "romanv", "romanvi", "romanvii", "romanviii", "romanx", "romanxi", "romanxii", "rootradical", "rotate", "rparent", "rrangle", "rrbracket", "rrointerval", "rtimes", "rtop", "ruledhbox", "ruledhpack", "ruledmbox", "ruledtopv", "ruledtpack", "ruledvbox", "ruledvpack", "ruledvtop", "runMPbuffer", "runninghbox", "rvert", "sacute", "safechar", "samplefile", "sans", "sansbold", "sansnormal", "sansserif", "savebox", "savebtxdataset", "savebuffer", "savecounter", "savecurrentattributes", "savenormalmeaning", "savetaggedtwopassdata", "savetwopassdata", "sbox", "scale", "scaron", "scedilla", "schwa", "schwahook", "scircumflex", "scommaaccent", "screen", "searrow", "secondoffivearguments", "secondoffourarguments", "secondofsixarguments", "secondofthreearguments", "secondofthreeunexpanded", "secondoftwoarguments", "secondoftwounexpanded", "section", "sectionmark", "seeindex", "select", "selectblocks", "serializecommalist", "serializedcommalist", "serif", "serifbold", "serifnormal", "setJSpreamble", "setMPlayer", "setMPpositiongraphic", "setMPpositiongraphicrange", "setMPtext", "setMPvariable", "setMPvariables", "setbar", "setbigbodyfont", "setboxllx", "setboxlly", "setbreakpoints", "setcapstrut", "setcatcodetable", "setcharacteralign", "setcharactercasing", "setcharactercleaning", "setcharacterkerning", "setcharacterspacing", "setcharacterstripping", "setcharstrut", "setcollector", "setcolormodell", "setcounter", "setcounterown", "setcurrentfontclass", "setdataset", "setdefaultpenalties", "setdigitsmanipulation", "setdirection", "setdocumentargument", "setdocumentargumentdefault", "setdocumentfilename", "setdummyparameter", "setelementexporttag", "setemeasure", "setevalue", "setevariable", "setevariables", "setfirstline", "setflag", "setfont", "setfontcolorsheme", "setfontfeature", "setfontsolution", "setfontstrut", "setgmeasure", "setgvalue", "setgvariable", "setgvariables", "sethboxregister", "sethyphenatedurlafter", "sethyphenatedurlbefore", "sethyphenatedurlnormal", "sethyphenationfeatures", "setinitial", "setinjector", "setinteraction", "setinterfacecommand", "setinterfaceconstant", "setinterfaceelement", "setinterfacemessage", "setinterfacevariable", "setinternalrendering", "setitaliccorrection", "setlayer", "setlayerframed", "setlayertext", "setlinefiller", "setlocalhsize", "setmainbodyfont", "setmainparbuilder", "setmarker", "setmarking", "setmathstyle", "setmeasure", "setmessagetext", "setminus", "setmode", "setnostrut", "setnote", "setnotetext", "setobject", "setoldstyle", "setpagegrid", "setpagereference", "setpagestate", "setpagestaterealpageno", "setpenalties", "setpercentdimen", "setposition", "setpositionbox", "setpositiondata", "setpositiondataplus", "setpositiononly", "setpositionplus", "setpositionstrut", "setprofile", "setrandomseed", "setreference", "setreferencedobject", "setregisterentry", "setreplacement", "setrigidcolumnbalance", "setrigidcolumnhsize", "setscript", "setsectionblock", "setsimplecolumnhsize", "setsmallbodyfont", "setsmallcaps", "setstackbox", "setstructurepageregister", "setstrut", "setsuperiors", "setsystemmode", "settabular", "settaggedmetadata", "settextcontent", "settightobject", "settightreferencedobject", "settightunreferencedobject", "settrialtypesetting", "setuevalue", "setugvalue", "setunreferencedobject", "setup", "setupMPgraphics", "setupMPinstance", "setupMPpage", "setupMPvariables", "setupTABLE", "setupTEXpage", "setupalign", "setupalternativestyles", "setuparranging", "setupattachment", "setupattachments", "setupbackend", "setupbackground", "setupbackgrounds", "setupbar", "setupbars", "setupblackrules", "setupblank", "setupbleeding", "setupblock", "setupbodyfont", "setupbookmark", "setupbottom", "setupbottomtexts", "setupbtx", "setupbtxdataset", "setupbtxlabeltext", "setupbtxlist", "setupbtxregister", "setupbtxrendering", "setupbuffer", "setupbutton", "setupcapitals", "setupcaption", "setupcaptions", "setupcharacterkerning", "setupcharacterspacing", "setupchemical", "setupchemicalframed", "setupclipping", "setupcollector", "setupcolor", "setupcolors", "setupcolumns", "setupcolumnspan", "setupcombination", "setupcombinedlist", "setupcomment", "setupcontent", "setupcounter", "setupdataset", "setupdelimitedtext", "setupdescription", "setupdirections", "setupdocument", "setupeffect", "setupenumeration", "setupenumerations", "setupenv", "setupexport", "setupexternalfigure", "setupexternalsoundtracks", "setupfield", "setupfieldbody", "setupfieldcategory", "setupfieldcontentframed", "setupfieldlabelframed", "setupfields", "setupfieldtotalframed", "setupfiller", "setupfillinlines", "setupfillinrules", "setupfirstline", "setupfittingpage", "setupfloat", "setupfloatcaption", "setupfloats", "setupfloatsplitting", "setupfontexpansion", "setupfontprotrusion", "setupfonts", "setupfontsolution", "setupfooter", "setupfootertexts", "setupforms", "setupformula", "setupformulae", "setupformulaframed", "setupframed", "setupframedcontent", "setupframedtable", "setupframedtablecolumn", "setupframedtablerow", "setupframedtext", "setupframedtexts", "setupglobalreferenceprefix", "setuphead", "setupheadalternative", "setupheader", "setupheadertexts", "setupheadnumber", "setupheads", "setupheadtext", "setuphelp", "setuphigh", "setuphighlight", "setuphyphenation", "setuphyphenmark", "setupindentedtext", "setupindenting", "setupindex", "setupinitial", "setupinsertion", "setupinteraction", "setupinteractionbar", "setupinteractionmenu", "setupinteractionscreen", "setupinterlinespace", "setupitaliccorrection", "setupitemgroup", "setupitemizations", "setupitemize", "setupitems", "setuplabel", "setuplabeltext", "setuplanguage", "setuplayer", "setuplayeredtext", "setuplayout", "setuplayouttext", "setuplegend", "setuplinefiller", "setuplinefillers", "setuplinenote", "setuplinenumbering", "setuplines", "setuplinetable", "setuplinewidth", "setuplist", "setuplistalternative", "setuplistextra", "setuplocalfloats", "setuplocalinterlinespace", "setuplow", "setuplowhigh", "setuplowmidhigh", "setupmakeup", "setupmarginblock", "setupmargindata", "setupmarginframed", "setupmarginrule", "setupmarginrules", "setupmarking", "setupmathalignment", "setupmathcases", "setupmathematics", "setupmathfence", "setupmathfraction", "setupmathfractions", "setupmathframed", "setupmathlabeltext", "setupmathmatrix", "setupmathornament", "setupmathradical", "setupmathstackers", "setupmathstyle", "setupmixedcolumns", "setupmodule", "setupnarrower", "setupnotation", "setupnotations", "setupnote", "setupnotes", "setupoffset", "setupoffsetbox", "setupoperatortext", "setupoppositeplacing", "setupoutputroutine", "setuppagechecker", "setuppagecomment", "setuppagegrid", "setuppagegridarea", "setuppagegridareatext", "setuppagegridlines", "setuppagegridspan", "setuppagegridstart", "setuppageinjection", "setuppageinjectionalternative", "setuppagenumber", "setuppagenumbering", "setuppageshift", "setuppagestate", "setuppagetransitions", "setuppairedbox", "setuppalet", "setuppaper", "setuppapersize", "setupparagraph", "setupparagraphintro", "setupparagraphnumbering", "setupparagraphs", "setupparallel", "setupperiods", "setupplacement", "setuppositionbar", "setuppositioning", "setupprefixtext", "setupprocessor", "setupprofile", "setupprograms", "setupquotation", "setupquote", "setuprealpagenumber", "setupreferenceformat", "setupreferenceprefix", "setupreferencestructureprefix", "setupreferencing", "setupregister", "setupregisters", "setuprenderingwindow", "setuprotate", "setups", "setupscale", "setupscript", "setupscripts", "setupsectionblock", "setupselector", "setupshift", "setupsidebar", "setupsorting", "setupspacing", "setupspellchecking", "setupstartstop", "setupstretched", "setupstruts", "setupstyle", "setupsubformula", "setupsubformulas", "setupsubpagenumber", "setupsuffixtext", "setupsymbolset", "setupsynctex", "setupsynonyms", "setuptables", "setuptabulate", "setuptabulation", "setuptagging", "setuptaglabeltext", "setuptext", "setuptextbackground", "setuptextflow", "setuptextrules", "setuptexttexts", "setupthinrules", "setuptolerance", "setuptooltip", "setuptop", "setuptoptexts", "setuptype", "setuptyping", "setupunit", "setupunittext", "setupurl", "setupuserpagenumber", "setupversion", "setupviewerlayer", "setupvspacing", "setupwhitespace", "setupwithargument", "setupwithargumentswapped", "setupxml", "setupxtable", "setuvalue", "setuxvalue", "setvalue", "setvariable", "setvariables", "setvboxregister", "setvisualizerfont", "setvtopregister", "setwidthof", "setxmeasure", "setxvalue", "setxvariable", "setxvariables", "seveneighths", "sfrac", "shapedhbox", "sharp", "shiftdown", "shiftup", "showallmakeup", "showattributes", "showbodyfont", "showbodyfontenvironment", "showboxes", "showbtxdatasetauthors", "showbtxdatasetcompleteness", "showbtxdatasetfields", "showbtxfields", "showbtxhashedauthors", "showbtxtables", "showchardata", "showcharratio", "showcolor", "showcolorbar", "showcolorcomponents", "showcolorgroup", "showcolorset", "showcolorstruts", "showcounter", "showdirectives", "showdirsinmargin", "showedebuginfo", "showexperiments", "showfont", "showfontdata", "showfontitalics", "showfontkerns", "showfontparameters", "showfontstrip", "showfontstyle", "showframe", "showglyphs", "showgrid", "showgridsnapping", "showhelp", "showhyphenationtrace", "showhyphens", "showinjector", "showjustification", "showkerning", "showlayout", "showlayoutcomponents", "showligature", "showligatures", "showlogcategories", "showmakeup", "showmargins", "showmessage", "showminimalbaseline", "shownextbox", "showotfcomposition", "showpalet", "showparentchain", "showprint", "showsetups", "showsetupsdefinition", "showstruts", "showsymbolset", "showtimer", "showtokens", "showtrackers", "showvalue", "showvariable", "showwarning", "sigma", "sim", "simeq", "simplealignedbox", "simplealignedboxplus", "simplealignedspreadbox", "simplegroupedcommand", "simplereversealignedbox", "simplereversealignedboxplus", "singalcharacteralign", "singlebond", "singleverticalbar", "sixperemspace", "sixthofsixarguments", "slanted", "slantedbold", "slantedface", "slash", "slicepages", "slong", "slovenianNumerals", "sloveniannumerals", "small", "smallbodyfont", "smallbold", "smallbolditalic", "smallboldslanted", "smallcappedcharacters", "smallcappedromannumerals", "smaller", "smallitalicbold", "smallnormal", "smallskip", "smallslanted", "smallslantedbold", "smalltype", "smash", "smashbox", "smashboxed", "smashedhbox", "smashedvbox", "smile", "snaptogrid", "softhyphen", "solidus", "someheadnumber", "somekindoftab", "someline", "somelocalfloat", "somenamedheadnumber", "someplace", "somewhere", "space", "spadesuit", "spanishNumerals", "spanishnumerals", "speech", "sphericalangle", "splitatasterisk", "splitatcolon", "splitatcolons", "splitatcomma", "splitatperiod", "splitdfrac", "splitfilename", "splitfloat", "splitfrac", "splitoffbase", "splitofffull", "splitoffkind", "splitoffname", "splitoffpath", "splitoffroot", "splitofftokens", "splitofftype", "splitstring", "spreadhbox", "sqcap", "sqcup", "sqrt", "sqsubset", "sqsubseteq", "sqsubsetneq", "sqsupset", "sqsupseteq", "sqsupsetneq", "square", "squaredots", "ssharp", "stackrel", "star", "stareq", "startJScode", "startJSpreamble", "startLUA", "startMP", "startMPclip", "startMPcode", "startMPdefinitions", "startMPdrawing", "startMPenvironment", "startMPextensions", "startMPinclusions", "startMPinitializations", "startMPpage", "startMPpositiongraphic", "startMPpositionmethod", "startMPrun", "startPARSEDXML", "startTABLE", "startTABLEbody", "startTABLEfoot", "startTABLEhead", "startTABLEnext", "startTC", "startTD", "startTDs", "startTEX", "startTEXpage", "startTH", "startTN", "startTR", "startTRs", "startTX", "startTY", "startXML", "startalign", "startalignment", "startallmodes", "startappendices", "startarrangedpages", "startaside", "startattachment", "startbackground", "startbackmatter", "startbar", "startbbordermatrix", "startbitmapimage", "startblockquote", "startbodymatter", "startbordermatrix", "startboxedcolumns", "startbtxlabeltext", "startbtxrenderingdefinitions", "startbuffer", "startcases", "startcatcodetable", "startcenteraligned", "startchapter", "startcharacteralign", "startcheckedfences", "startchemical", "startchemicaltext", "startcollect", "startcollecting", "startcolor", "startcolorintent", "startcoloronly", "startcolorset", "startcolumns", "startcolumnspan", "startcombination", "startcomment", "startcomponent", "startcontextcode", "startcontextdefinitioncode", "startctxfunction", "startctxfunctiondefinition", "startcurrentcolor", "startcurrentlistentrywrapper", "startdelimited", "startdelimitedtext", "startdisplaymath", "startdmath", "startdocument", "starteffect", "startelement", "startembeddedxtable", "startendnote", "startendofline", "startenvironment", "startexceptions", "startexpanded", "startexpandedcollect", "startextendedcatcodetable", "startexternalfigurecollection", "startfact", "startfigure", "startfiguretext", "startfittingpage", "startfixed", "startfloatcombination", "startfont", "startfontclass", "startfontsolution", "startfootnote", "startformula", "startformulas", "startframed", "startframedcell", "startframedcontent", "startframedrow", "startframedtable", "startframedtext", "startfrontmatter", "startgoto", "startgraphictext", "startgridsnapping", "starthanging", "starthbox", "starthboxestohbox", "starthboxregister", "starthead", "startheadtext", "starthelptext", "starthiding", "starthighlight", "starthyphenation", "startimath", "startindentation", "startindentedtext", "startinteraction", "startinteractionmenu", "startinterface", "startintermezzotext", "startintertext", "startitem", "startitemgroup", "startitemgroupcolumns", "startitemize", "startknockout", "startlabeltext", "startlayout", "startleftaligned", "startlegend", "startline", "startlinealignment", "startlinecorrection", "startlinefiller", "startlinenote", "startlinenumbering", "startlines", "startlinetable", "startlinetablebody", "startlinetablecell", "startlinetablehead", "startlocalfootnotes", "startlocalheadsetup", "startlocallinecorrection", "startlocalnotes", "startlocalsetups", "startlua", "startluacode", "startluaparameterset", "startluasetups", "startmakeup", "startmarginblock", "startmarginrule", "startmarkedcontent", "startmathalignment", "startmathcases", "startmathlabeltext", "startmathmatrix", "startmathmode", "startmathstyle", "startmatrices", "startmatrix", "startmaxaligned", "startmdformula", "startmidaligned", "startmiddlealigned", "startmiddlemakeup", "startmixedcolumns", "startmode", "startmodeset", "startmodule", "startmoduletestsection", "startmpformula", "startnamedsection", "startnamedsubformulas", "startnarrow", "startnarrower", "startnegative", "startnicelyfilledbox", "startnointerference", "startnotallmodes", "startnotext", "startnotmode", "startoperatortext", "startopposite", "startoutputstream", "startoverlay", "startoverprint", "startpacked", "startpagecomment", "startpagefigure", "startpagegrid", "startpagegridspan", "startpagelayout", "startpagemakeup", "startpar", "startparagraph", "startparagraphs", "startparagraphscell", "startparbuilder", "startpart", "startpath", "startplacechemical", "startplacefigure", "startplacefloat", "startplaceformula", "startplacegraphic", "startplaceintermezzo", "startplacelegend", "startplacepairedbox", "startplacetable", "startpositioning", "startpositionoverlay", "startpositive", "startpostponing", "startprefixtext", "startprocessassignmentcommand", "startprocessassignmentlist", "startprocesscommacommand", "startprocesscommalist", "startproduct", "startproject", "startprotect", "startprotectedcolors", "startpublication", "startpunctuation", "startquotation", "startquote", "startrandomized", "startrandomseed", "startrawsetups", "startreadingfile", "startreferenceprefix", "startregime", "startregister", "startreusableMPgraphic", "startrightaligned", "startscript", "startsdformula", "startsection", "startsectionblock", "startsectionblockenvironment", "startsectionlevel", "startsetups", "startshapebox", "startshift", "startsidebar", "startsimplecolumns", "startspecialitem", "startspeech", "startspformula", "startspread", "startstandardmakeup", "startstartstop", "startstaticMPfigure", "startstaticMPgraphic", "startstrictinspectnextcharacter", "startstructurepageregister", "startstrut", "startstyle", "startsubformulas", "startsubject", "startsubjectlevel", "startsubsection", "startsubsentence", "startsubstack", "startsubsubject", "startsubsubsection", "startsubsubsubject", "startsubsubsubsection", "startsubsubsubsubject", "startsubsubsubsubsection", "startsubsubsubsubsubject", "startsuffixtext", "startsymbolset", "starttable", "starttablehead", "starttables", "starttabletail", "starttabletext", "starttabulate", "starttabulatehead", "starttabulatetail", "starttagged", "starttaglabeltext", "starttexcode", "starttexdefinition", "starttext", "starttextbackground", "starttextbackgroundmanual", "starttextcolor", "starttextcolorintent", "starttextflow", "starttextmakeup", "starttextrule", "starttitle", "starttokens", "starttransparent", "starttypescript", "starttypescriptcollection", "starttyping", "startuniqueMPgraphic", "startuniqueMPpagegraphic", "startunittext", "startunpacked", "startusableMPgraphic", "startuseMPgraphic", "startusemathstyleparameter", "startusingbtxspecification", "startvbox", "startvboxregister", "startvboxtohbox", "startvboxtohboxseparator", "startviewerlayer", "startvtop", "startvtopregister", "startxcell", "startxcellgroup", "startxgroup", "startxmldisplayverbatim", "startxmlinlineverbatim", "startxmlraw", "startxmlsetups", "startxrow", "startxrowgroup", "startxtable", "startxtablebody", "startxtablefoot", "startxtablehead", "startxtablenext", "stligature", "stopJScode", "stopJSpreamble", "stopLUA", "stopMP", "stopMPclip", "stopMPcode", "stopMPdefinitions", "stopMPdrawing", "stopMPenvironment", "stopMPextensions", "stopMPinclusions", "stopMPinitializations", "stopMPpage", "stopMPpositiongraphic", "stopMPpositionmethod", "stopMPrun", "stopPARSEDXML", "stopTABLE", "stopTABLEbody", "stopTABLEfoot", "stopTABLEhead", "stopTABLEnext", "stopTC", "stopTD", "stopTDs", "stopTEX", "stopTEXpage", "stopTH", "stopTN", "stopTR", "stopTRs", "stopTX", "stopTY", "stopXML", "stopalign", "stopalignment", "stopallmodes", "stopappendices", "stoparrangedpages", "stopaside", "stopattachment", "stopbackground", "stopbackmatter", "stopbar", "stopbbordermatrix", "stopbitmapimage", "stopblockquote", "stopbodymatter", "stopbordermatrix", "stopboxedcolumns", "stopbtxlabeltext", "stopbtxrenderingdefinitions", "stopbuffer", "stopcases", "stopcatcodetable", "stopcenteraligned", "stopchapter", "stopcharacteralign", "stopcheckedfences", "stopchemical", "stopchemicaltext", "stopcollect", "stopcollecting", "stopcolor", "stopcolorintent", "stopcoloronly", "stopcolorset", "stopcolumns", "stopcolumnspan", "stopcombination", "stopcomment", "stopcomponent", "stopcontextcode", "stopcontextdefinitioncode", "stopctxfunction", "stopctxfunctiondefinition", "stopcurrentcolor", "stopcurrentlistentrywrapper", "stopdelimited", "stopdelimitedtext", "stopdisplaymath", "stopdmath", "stopdocument", "stopeffect", "stopelement", "stopembeddedxtable", "stopendnote", "stopendofline", "stopenvironment", "stopexceptions", "stopexpanded", "stopexpandedcollect", "stopextendedcatcodetable", "stopexternalfigurecollection", "stopfact", "stopfigure", "stopfiguretext", "stopfittingpage", "stopfixed", "stopfloatcombination", "stopfont", "stopfontclass", "stopfontsolution", "stopfootnote", "stopformula", "stopformulas", "stopframed", "stopframedcell", "stopframedcontent", "stopframedrow", "stopframedtable", "stopframedtext", "stopfrontmatter", "stopgoto", "stopgraphictext", "stopgridsnapping", "stophanging", "stophbox", "stophboxestohbox", "stophboxregister", "stophead", "stopheadtext", "stophelptext", "stophiding", "stophighlight", "stophyphenation", "stopimath", "stopindentation", "stopindentedtext", "stopinteraction", "stopinteractionmenu", "stopinterface", "stopintermezzotext", "stopintertext", "stopitem", "stopitemgroup", "stopitemgroupcolumns", "stopitemize", "stopknockout", "stoplabeltext", "stoplayout", "stopleftaligned", "stoplegend", "stopline", "stoplinealignment", "stoplinecorrection", "stoplinefiller", "stoplinenote", "stoplinenumbering", "stoplines", "stoplinetable", "stoplinetablebody", "stoplinetablecell", "stoplinetablehead", "stoplocalfootnotes", "stoplocalheadsetup", "stoplocallinecorrection", "stoplocalnotes", "stoplocalsetups", "stoplua", "stopluacode", "stopluaparameterset", "stopluasetups", "stopmakeup", "stopmarginblock", "stopmarginrule", "stopmarkedcontent", "stopmathalignment", "stopmathcases", "stopmathlabeltext", "stopmathmatrix", "stopmathmode", "stopmathstyle", "stopmatrices", "stopmatrix", "stopmaxaligned", "stopmdformula", "stopmidaligned", "stopmiddlealigned", "stopmiddlemakeup", "stopmixedcolumns", "stopmode", "stopmodeset", "stopmodule", "stopmoduletestsection", "stopmpformula", "stopnamedsection", "stopnamedsubformulas", "stopnarrow", "stopnarrower", "stopnegative", "stopnicelyfilledbox", "stopnointerference", "stopnotallmodes", "stopnotext", "stopnotmode", "stopoperatortext", "stopopposite", "stopoutputstream", "stopoverlay", "stopoverprint", "stoppacked", "stoppagecomment", "stoppagefigure", "stoppagegrid", "stoppagegridspan", "stoppagelayout", "stoppagemakeup", "stoppar", "stopparagraph", "stopparagraphs", "stopparagraphscell", "stopparbuilder", "stoppart", "stoppath", "stopplacechemical", "stopplacefigure", "stopplacefloat", "stopplaceformula", "stopplacegraphic", "stopplaceintermezzo", "stopplacelegend", "stopplacepairedbox", "stopplacetable", "stoppositioning", "stoppositionoverlay", "stoppositive", "stoppostponing", "stopprefixtext", "stopprocessassignmentcommand", "stopprocessassignmentlist", "stopprocesscommacommand", "stopprocesscommalist", "stopproduct", "stopproject", "stopprotect", "stopprotectedcolors", "stoppublication", "stoppunctuation", "stopquotation", "stopquote", "stoprandomized", "stoprandomseed", "stoprawsetups", "stopreadingfile", "stopreferenceprefix", "stopregime", "stopregister", "stopreusableMPgraphic", "stoprightaligned", "stopscript", "stopsdformula", "stopsection", "stopsectionblock", "stopsectionblockenvironment", "stopsectionlevel", "stopsetups", "stopshapebox", "stopshift", "stopsidebar", "stopsimplecolumns", "stopspecialitem", "stopspeech", "stopspformula", "stopspread", "stopstandardmakeup", "stopstartstop", "stopstaticMPfigure", "stopstaticMPgraphic", "stopstrictinspectnextcharacter", "stopstructurepageregister", "stopstrut", "stopstyle", "stopsubformulas", "stopsubject", "stopsubjectlevel", "stopsubsection", "stopsubsentence", "stopsubstack", "stopsubsubject", "stopsubsubsection", "stopsubsubsubject", "stopsubsubsubsection", "stopsubsubsubsubject", "stopsubsubsubsubsection", "stopsubsubsubsubsubject", "stopsuffixtext", "stopsymbolset", "stoptable", "stoptablehead", "stoptables", "stoptabletail", "stoptabletext", "stoptabulate", "stoptabulatehead", "stoptabulatetail", "stoptagged", "stoptaglabeltext", "stoptexcode", "stoptexdefinition", "stoptext", "stoptextbackground", "stoptextbackgroundmanual", "stoptextcolor", "stoptextcolorintent", "stoptextflow", "stoptextmakeup", "stoptextrule", "stoptitle", "stoptokens", "stoptransparent", "stoptypescript", "stoptypescriptcollection", "stoptyping", "stopuniqueMPgraphic", "stopuniqueMPpagegraphic", "stopunittext", "stopunpacked", "stopusableMPgraphic", "stopuseMPgraphic", "stopusemathstyleparameter", "stopusingbtxspecification", "stopvbox", "stopvboxregister", "stopvboxtohbox", "stopvboxtohboxseparator", "stopviewerlayer", "stopvtop", "stopvtopregister", "stopxcell", "stopxcellgroup", "stopxgroup", "stopxmldisplayverbatim", "stopxmlinlineverbatim", "stopxmlraw", "stopxmlsetups", "stopxrow", "stopxrowgroup", "stopxtable", "stopxtablebody", "stopxtablefoot", "stopxtablehead", "stopxtablenext", "stretched", "strictdoifelsenextoptional", "strictdoifnextoptionalelse", "stripcharacter", "strippedcsname", "stripspaces", "structurelistuservariable", "structurenumber", "structuretitle", "structureuservariable", "structurevariable", "strut", "strutdp", "strutgap", "strutht", "struthtdp", "struttedbox", "strutwd", "style", "styleinstance", "subject", "subpagenumber", "subsection", "subsentence", "subset", "subseteq", "subseteqq", "subsetneq", "subsetneqq", "substituteincommalist", "subsubject", "subsubsection", "subsubsubject", "subsubsubsection", "subsubsubsubject", "subsubsubsubsection", "subsubsubsubsubject", "subtractfeature", "succ", "succapprox", "succcurlyeq", "succeq", "succeqq", "succnapprox", "succneq", "succneqq", "succnsim", "succsim", "suffixlanguage", "suffixtext", "sum", "supset", "supseteq", "supseteqq", "supsetneq", "supsetneqq", "surd", "surdradical", "swapcounts", "swapdimens", "swapface", "swapmacros", "swaptypeface", "swarrow", "switchstyleonly", "switchtobodyfont", "switchtocolor", "switchtointerlinespace", "symbol", "symbolreference", "synchronizeblank", "synchronizeindenting", "synchronizemarking", "synchronizeoutputstreams", "synchronizestrut", "synchronizewhitespace", "synctexblockfilename", "synctexresetfilename", "synctexsetfilename", "systemlog", "systemlogfirst", "systemloglast", "systemsetups", "tLeftarrow", "tLeftrightarrow", "tRightarrow", "tabulateautoline", "tabulateautorule", "tabulateline", "tabulaterule", "taggedctxcommand", "taggedlabeltexts", "taglabellanguage", "taglabeltext", "tau", "tbinom", "tbox", "tcaron", "tcedilla", "tcommaaccent", "tcurl", "tequal", "test", "testandsplitstring", "testcolumn", "testfeature", "testfeatureonce", "testpage", "testpageonly", "testpagesync", "testtokens", "tex", "texdefinition", "texsetup", "textAngstrom", "textacute", "textampersand", "textasciicircum", "textasciitilde", "textat", "textbackslash", "textbar", "textbottomcomma", "textbottomdot", "textbraceleft", "textbraceright", "textbreve", "textbrokenbar", "textbullet", "textcaron", "textcedilla", "textcelsius", "textcent", "textcircledP", "textcircumflex", "textcitation", "textcite", "textcomma", "textcontrolspace", "textcurrency", "textdag", "textddag", "textdegree", "textdiaeresis", "textdiv", "textdollar", "textdong", "textdotaccent", "textellipsis", "texteuro", "textflowcollector", "textfraction", "textgrave", "texthash", "texthorizontalbar", "texthungarumlaut", "texthyphen", "textkelvin", "textlognot", "textmacron", "textmath", "textmho", "textminus", "textmu", "textmultiply", "textnumero", "textogonek", "textohm", "textormathchar", "textounce", "textpercent", "textperiod", "textplus", "textpm", "textreference", "textring", "textrule", "textslash", "textsterling", "texttilde", "textunderscore", "textvisiblespace", "textyen", "thai", "thainumerals", "thefirstcharacter", "thenormalizedbodyfontsize", "therefore", "theremainingcharacters", "theta", "thickspace", "thinrule", "thinrules", "thinspace", "thirdoffivearguments", "thirdoffourarguments", "thirdofsixarguments", "thirdofthreearguments", "thirdofthreeunexpanded", "thook", "thookleftarrow", "thookrightarrow", "thorn", "threedigitrounding", "threeeighths", "threefifths", "threeperemspace", "threequarter", "threesuperior", "tibetannumerals", "tightlayer", "tilde", "times", "tinyfont", "title", "tlap", "tleftarrow", "tleftharpoondown", "tleftharpoonup", "tleftrightarrow", "tleftrightharpoons", "tmapsto", "to", "tochar", "tolinenote", "tooltip", "top", "topbox", "topleftbox", "toplinebox", "toprightbox", "topskippedbox", "tracecatcodetables", "tracedfontname", "traceoutputroutines", "tracepositions", "trademark", "translate", "transparencycomponents", "transparent", "trel", "triangle", "triangledown", "triangleleft", "triangleq", "triangleright", "trightarrow", "trightharpoondown", "trightharpoonup", "trightleftharpoons", "trightoverleftarrow", "triplebond", "tripleprime", "tripleverticalbar", "truefilename", "truefontname", "tstroke", "ttraggedright", "ttriplerel", "ttwoheadleftarrow", "ttwoheadrightarrow", "turnediota", "twodigitrounding", "twofifths", "twoheaddownarrow", "twoheadleftarrow", "twoheadrightarrow", "twoheadrightarrowtail", "twoheaduparrow", "twosuperior", "twothirds", "tx", "txx", "typ", "type", "typebuffer", "typedefinedbuffer", "typeface", "typefile", "typeinlinebuffer", "typescriptone", "typescriptprefix", "typescriptthree", "typescripttwo", "typesetbuffer", "typesetfile", "uacute", "ubreve", "ucaron", "ucircumflex", "uconvertnumber", "udiaeresis", "udiaeresisacute", "udiaeresiscaron", "udiaeresisgrave", "udiaeresismacron", "udotbelow", "udots", "udoublegrave", "uedcatcodecommand", "ugrave", "uhook", "uhorn", "uhornacute", "uhorndotbelow", "uhorngrave", "uhornhook", "uhorntilde", "uhungarumlaut", "uinvertedbreve", "ulcorner", "umacron", "undefinevalue", "undepthed", "underbar", "underbars", "underbrace", "underbracket", "underdash", "underdashes", "underdot", "underdots", "underleftarrow", "underparent", "underrandom", "underrandoms", "underrightarrow", "underset", "understrike", "understrikes", "undoassign", "unexpandeddocumentvariable", "unframed", "unhhbox", "unihex", "uniqueMPgraphic", "uniqueMPpagegraphic", "unit", "unitlanguage", "unitshigh", "unitslow", "unittext", "unknown", "unprotected", "unregisterhyphenationpattern", "unspaceafter", "unspaceargument", "unspaced", "unspacestring", "untexargument", "untexcommand", "uogonek", "upand", "uparrow", "updasharrow", "updownarrow", "updownarrowbar", "updownarrows", "upharpoonleft", "upharpoonright", "uplus", "uppercased", "uppercasestring", "upperleftdoubleninequote", "upperleftdoublesixquote", "upperleftsingleninequote", "upperleftsinglesixquote", "upperrightdoubleninequote", "upperrightdoublesixquote", "upperrightsingleninequote", "upperrightsinglesixquote", "upsilon", "upuparrows", "upwhitearrow", "urcorner", "uring", "url", "useJSscripts", "useMPenvironmentbuffer", "useMPgraphic", "useMPlibrary", "useMPrun", "useMPvariables", "useURL", "usealignparameter", "useblankparameter", "useblocks", "usebodyfont", "usebodyfontparameter", "usebtxdataset", "usebtxdefinitions", "usecitation", "usecolors", "usecomponent", "usedirectory", "usedummycolorparameter", "usedummystyleandcolor", "usedummystyleparameter", "useenvironment", "useexternaldocument", "useexternalfigure", "useexternalrendering", "useexternalsoundtrack", "usefigurebase", "usefile", "usegridparameter", "useindentingparameter", "useindentnextparameter", "useinterlinespaceparameter", "uselanguageparameter", "useluamodule", "usemathstyleparameter", "usemodule", "useproduct", "useprofileparameter", "useproject", "usereferenceparameter", "userpagenumber", "usesetupsparameter", "usestaticMPfigure", "usesubpath", "usesymbols", "usetexmodule", "usetypescript", "usetypescriptfile", "useurl", "usezipfile", "utfchar", "utflower", "utfupper", "utilde", "utilityregisterlength", "vDash", "varTheta", "varepsilon", "varkappa", "varnothing", "varphi", "varpi", "varrho", "varsigma", "vartheta", "vboxreference", "vdash", "vdots", "vec", "vee", "veebar", "veeeq", "verbatim", "verbatimstring", "verbosenumber", "version", "vert", "verticalgrowingbar", "verticalpositionbar", "veryraggedcenter", "veryraggedleft", "veryraggedright", "vglue", "viewerlayer", "vl", "vphantom", "vpos", "vsmash", "vsmashbox", "vsmashed", "vspace", "vspacing", "wcircumflex", "wdofstring", "wedge", "wedgeeq", "weekday", "whitearrowupfrombar", "widehat", "widetilde", "widthofstring", "widthspanningtext", "withoutpt", "word", "wordright", "words", "wordtonumber", "wp", "wr", "writebetweenlist", "writedatatolist", "writestatus", "writetolist", "xLeftarrow", "xLeftrightarrow", "xRightarrow", "xdefconvertedargument", "xequal", "xfrac", "xhookleftarrow", "xhookrightarrow", "xi", "xleftarrow", "xleftharpoondown", "xleftharpoonup", "xleftrightarrow", "xleftrightharpoons", "xmapsto", "xmladdindex", "xmlafterdocumentsetup", "xmlaftersetup", "xmlall", "xmlappenddocumentsetup", "xmlappendsetup", "xmlapplyselectors", "xmlatt", "xmlattdef", "xmlattribute", "xmlattributedef", "xmlbadinclusions", "xmlbeforedocumentsetup", "xmlbeforesetup", "xmlchainatt", "xmlchainattdef", "xmlchecknamespace", "xmlcommand", "xmlconcat", "xmlconcatrange", "xmlcontext", "xmlcount", "xmldefaulttotext", "xmldirectives", "xmldirectivesafter", "xmldirectivesbefore", "xmldisplayverbatim", "xmldoif", "xmldoifelse", "xmldoifelseempty", "xmldoifelseselfempty", "xmldoifelsetext", "xmldoifelsevalue", "xmldoifnot", "xmldoifnotselfempty", "xmldoifnottext", "xmldoifselfempty", "xmldoiftext", "xmlelement", "xmlfilter", "xmlfirst", "xmlflush", "xmlflushcontext", "xmlflushdocumentsetups", "xmlflushlinewise", "xmlflushpure", "xmlflushspacewise", "xmlflushtext", "xmlinclude", "xmlinclusion", "xmlinclusions", "xmlinfo", "xmlinjector", "xmlinlineprettyprint", "xmlinlineprettyprinttext", "xmlinlineverbatim", "xmlinstalldirective", "xmllast", "xmllastatt", "xmllastmatch", "xmlloadbuffer", "xmlloaddata", "xmlloaddirectives", "xmlloadfile", "xmlloadonly", "xmlmain", "xmlmapvalue", "xmlname", "xmlnamespace", "xmlnonspace", "xmlpath", "xmlpos", "xmlposition", "xmlprependdocumentsetup", "xmlprependsetup", "xmlprettyprint", "xmlprettyprinttext", "xmlprocessbuffer", "xmlprocessdata", "xmlprocessfile", "xmlpure", "xmlraw", "xmlrefatt", "xmlregistereddocumentsetups", "xmlregisteredsetups", "xmlregisterns", "xmlremapname", "xmlremapnamespace", "xmlremovedocumentsetup", "xmlremovesetup", "xmlresetdocumentsetups", "xmlresetinjectors", "xmlresetsetups", "xmlsave", "xmlsetentity", "xmlsetfunction", "xmlsetinjectors", "xmlsetsetup", "xmlsetup", "xmlshow", "xmlsnippet", "xmlstrip", "xmlstripnolines", "xmlstripped", "xmlstrippednolines", "xmltag", "xmltexentity", "xmltext", "xmltobuffer", "xmltobufferverbose", "xmltofile", "xmlvalue", "xmlverbatim", "xrel", "xrightarrow", "xrightharpoondown", "xrightharpoonup", "xrightleftharpoons", "xrightoverleftarrow", "xsplitstring", "xtriplerel", "xtwoheadleftarrow", "xtwoheadrightarrow", "xxfrac", "xypos", "yacute", "ycircumflex", "ydiaeresis", "ydotbelow", "yen", "ygrave", "yhook", "ymacron", "ytilde", "zacute", "zcaron", "zdotaccent", "zerowidthnobreakspace", "zerowidthspace", "zeta", "zhook", "zstroke", "zwj", "zwnj" },
["cs"]={ "Cisla", "Kap", "MESIC", "Rimskecislice", "SLOVA", "SLOVO", "Slova", "Slovo", "VSEDNIDEN", "Znak", "Znaky", "aktualnicislonadpisu", "aktualnidatum", "barevnalista", "barva", "cernalinka", "cernelinky", "cisla", "cislonadpisu", "cislorovnice", "cislostrany", "datum", "definuj", "definujakcent", "definujbarvu", "definujblok", "definujbloksekce", "definujbuffer", "definujfont", "definujformatodkazu", "definujhbox", "definujinterakcnimenu", "definujkombinovanyseznam", "definujkonverzi", "definujnadpis", "definujobrazeksymbol", "definujodkaz", "definujodstavce", "definujopis", "definujoramovani", "definujoramovanytext", "definujpaletu", "definujplvouciobjekt", "definujpodpole", "definujpole", "definujpopis", "definujpopisek", "definujprekryv", "definujprikaz", "definujprofil", "definujprogram", "definujprostredizakladnihofontu", "definujrejstrik", "definujsablonutabulky", "definujsekci", "definujseznam", "definujskupinubarev", "definujstartstop", "definujstyl", "definujstylfontu", "definujsymbol", "definujsynonumumfontu", "definujsynonyma", "definujtabelaci", "definujtext", "definujtrideni", "definujupravu", "definujvelikostpapiru", "definujvycet", "definujzakladnifont", "definujzasobnikpoli", "definujznaceni", "definujznak", "delkaseznamu", "externiobraz", "hlavnijazyk", "hodnotabarvy", "instalacejazyka", "interakcnilista", "interakcnitlacitka", "interaktivnimenu", "jazyk", "jdidolu", "jdina", "jdinabox", "jdinastranu", "klonujpole", "komponenta", "konvertujcislo", "kopirujpole", "korekcebilehomista", "matematika", "meritko", "mesic", "mezera", "mrizka", "nastavbarvu", "nastavbarvy", "nastavbilamista", "nastavblok", "nastavbloksekce", "nastavbuffer", "nastavcernelinky", "nastavcislonadpisu", "nastavcislostrany", "nastavcislovaniodstavcu", "nastavcislovaniradku", "nastavcislovanistran", "nastavcitaci", "nastavdeleniplvoucichobjektu", "nastavdelitko", "nastavdolnitexty", "nastavhorejsek", "nastavhornitexty", "nastavinterakci", "nastavinterakcnilistu", "nastavinterakcnimenu", "nastavinterakcniobrazovku", "nastavjazyk", "nastavkapitalky", "nastavkombinovanyseznam", "nastavkomentar", "nastavkomentarstrany", "nastavmarginalnilinky", "nastavmeziradkovoumezeru", "nastavnadpis", "nastavnadpisy", "nastavodkazovani", "nastavodsazovani", "nastavodstavce", "nastavopis", "nastavoramovanetexty", "nastavoramovani", "nastavorez", "nastavotoceni", "nastavpaletu", "nastavplvouciobjekt", "nastavplvouciobjekty", "nastavpodcislostrany", "nastavpole", "nastavpolozky", "nastavpopisek", "nastavpopisky", "nastavpozadi", "nastavprechodstrany", "nastavpreskok", "nastavprogramy", "nastavradkovani", "nastavradky", "nastavrejstrik", "nastavrovnice", "nastavsadusymbolu", "nastavseznam", "nastavsirkucary", "nastavsloupce", "nastavspodek", "nastavsynonyma", "nastavtabelaci", "nastavtabulky", "nastavtenkelinky", "nastavtext", "nastavtextovelinky", "nastavtexttexty", "nastavtextyupati", "nastavtextyzahlavi", "nastavtoleranci", "nastavtrideni", "nastavtype", "nastavumisteniprotejsku", "nastavumistovani", "nastavupati", "nastavupravu", "nastavurl", "nastavusporadani", "nastavvelikostpapiru", "nastavvsechnapole", "nastavvycty", "nastavvyplnovelinky", "nastavvyplnoveradky", "nastavvzhled", "nastavzahlavi", "nastavzakladnifont", "nastavzarovnani", "nastavznaceni", "nastavzuzeni", "nastrane", "nejakyradek", "nekde", "neznamo", "nivy", "nizky", "nokap", "obrazovka", "odkaz", "odkaznastranu", "odkaznatext", "odkazujici", "opis", "opissoubor", "oramovani", "oref", "orez", "otocit", "oznaceni", "pis", "plnezneni", "pole", "polozka", "polozky", "porovnejpaletu", "porovnejskupinubarev", "pozadi", "pozice", "poznamka", "pref", "prelozit", "prepninazakladnifont", "preskoc", "prizpusobivepole", "prizpusobvzhled", "produkt", "projekt", "prostredi", "resetznaceni", "rimskecislice", "rozdelplvouciobjekt", "roztazene", "schovejbloky", "sedabarva", "sloupec", "slovovpravo", "stanovcharakteristickuseznamu", "stanovcislonadpisu", "startbarva", "startinteraktivnimenu", "startjdina", "startkomponenta", "startmarginalnilinka", "startnadpis", "startoramovani", "startpolozka", "startpozadi", "startprodukt", "startprojekt", "startprostredi", "startpublikace", "startradek", "starttextovalinka", "startumistirovnici", "startzarovnanonastred", "startzarovnanovlevo", "startzarovnanovpravo", "startzhustene", "stopbarva", "stopinteraktivnimenu", "stopjdina", "stopkomponenta", "stopmarginalnilinka", "stopnadpis", "stoporamovani", "stoppolozka", "stoppozadi", "stopprodukt", "stopprojekt", "stopprostredi", "stoppublikace", "stopradek", "stoptextovalinka", "stopumistirovnici", "stopzarovnanonastred", "stopzarovnanovlevo", "stopzarovnanovpravo", "stopzhustene", "strana", "tecky", "tenkalinka", "tenkelinky", "textovalinka", "tlacitko", "tlacitkomenu", "tloustkacary", "tref", "tvrdamezera", "tvrdemezery", "ukazbarvu", "ukazmrizku", "ukaznastaveni", "ukazpaletu", "ukazpodpery", "ukazpostredizakladnihofontu", "ukazramecek", "ukazsadusymbolu", "ukazskupinubarev", "ukazupravu", "ukazvytisk", "ukazvzhled", "ukazzakladnifont", "umistikombinovanyseznam", "umistilokalnipoznamkypodcarou", "umistinadsebe", "umistinamrizku", "umistipodrovnici", "umistipoznamkypodcarou", "umistirejstrik", "umistirovnici", "umistiseznam", "umistivedlesebe", "umistizalozky", "urcicharakteristikurejstriku", "uzijJSscripts", "uzijURL", "uzijadresar", "uzijbloky", "uzijexternidokument", "uzijexterniobraz", "uzijexternizvuk", "uzijmodul", "uzijsymbol", "uzijurl", "verze", "vlasovalinka", "vradku", "vsedniden", "vyberbloky", "vyplnenytext", "vyplnovelinky", "vyplnovyradek", "vysoky", "zachovejbloky", "zadnamezera", "zadnehorniadolniradky", "zadnezahlaviaupati", "zalozka", "zapisdoseznamu", "zapismeziseznam", "zaramovani", "zarovnanonastred", "zarovnanovlevo", "zarovnanovpravo", "zasobnikpoli", "ziskejbuffer", "ziskejznaceni", "znaceni", "znak", "znaky", "zpracujbloky", "zrcadlit", "zref" },
["de"]={ "Buchstabe", "Buchstaben", "Kap", "MONAT", "Roemischezahlen", "WOCHENTAG", "WOERTER", "WORT", "Woerter", "Wort", "Ziffern", "amgitterausrichten", "aufseite", "ausfuelltext", "ausschnitt", "bearbeitebloecke", "behaltebloecke", "bei", "bemerkung", "benutzeverzeichnis", "beschriftung", "bestimmekopfnummer", "bestimmelistencharakeristika", "bestimmeregistercharakteristika", "bildschirm", "blanko", "buchstabe", "buchstaben", "datum", "defineschriftsynonym", "definiereabbsymbol", "definiereabsaetze", "definiereabschnitt", "definiereabschnittsblock", "definiereakzent", "definierebefehl", "definierebeschreibung", "definierebeschriftung", "definiereblock", "definierefarbe", "definierefarbengruppe", "definierefeld", "definierefeldstapel", "definierefliesstext", "definierefliesstextumgebung", "definieregleitobjekt", "definierehbox", "definiereinteraktionsmenue", "definierekonversion", "definierelabel", "definiereliste", "definieren", "definierenummerierung", "definiereoverlay", "definierepalette", "definierepapierformat", "definiereprofil", "definiereprogramme", "definierepuffer", "definierereferenz", "definierereferenzformat", "definiereregister", "definiereschrift", "definiereschriftstil", "definieresortieren", "definierestartstop", "definierestil", "definieresubfeld", "definieresymbol", "definieresynonyme", "definieretabellenvorlage", "definieretabulator", "definieretext", "definieretippen", "definiereueberschrift", "definiereumbruch", "definiereumrahmt", "definiereumrahmtertext", "definierezeichen", "definierezusammengestellteliste", "drehen", "duennelinie", "duennerumriss", "einezeile", "externeabbildung", "farbbalken", "farbe", "farbewert", "feld", "feldstapel", "festesspatium", "format", "formelnummer", "gefuelltesrechteck", "gefuelltezeile", "gestreckt", "gitter", "graufarbe", "haarlinie", "hauptsprache", "heutigesdatum", "heutigeskopfnummer", "hintergrund", "hoch", "holebeschriftung", "holepuffer", "imumriss", "installieresprache", "interaktionsbalken", "interaktionsknopfe", "interaktionsmenue", "inzeile", "irgendwo", "keinekopfundfusszeilen", "keinspatium", "keinzeilenobenundunten", "klonierefeld", "knopf", "komponente", "konvertierezahl", "kopfnummer", "kopierefeld", "korrigierezwischenraum", "liniendicke", "linksbuendig", "listenlaenge", "mathematik", "menueknopf", "monat", "nachunten", "nokap", "notiz", "passelayoutan", "passendfeld", "platzierebookmarks", "platziereformel", "platzierefussnoten", "platziereliste", "platzierelokalefussnoten", "platzierenebeneinander", "platziereregister", "platziereuntereinander", "platziereunterformel", "platzierezusammengestellteliste", "pos", "posten", "produkt", "programm", "projekt", "punkt", "rechteck", "rechtecke", "rechtsbuendig", "referenz", "referieren", "roemischezahlen", "ruecksetztenbeschriftung", "schreibezurliste", "schreibezwischenliste", "seite", "seitenreferenz", "seitenummer", "settext", "spalte", "spatium", "spiegeln", "sprache", "startfarbe", "starthintergrund", "startinteraktionsmenue", "startkleinerdurchschuss", "startkomponente", "startkopf", "startlinksbuendig", "startmarginallinie", "startplatziereformel", "startpos", "startprodukt", "startprojekt", "startpublikation", "startrechtsbuendig", "starttextlinie", "startumgebung", "startumrahmt", "startzeile", "startzentriert", "startzu", "stelleabsaetzeein", "stelleabsatznummerierungein", "stelleabschnittsblockein", "stelleanordnenein", "stelleaufzaehlungenein", "stelleausrichtungein", "stelleausschnittein", "stellebeschreibungein", "stellebeschriftungein", "stellebilderunterschriftein", "stellebildunterschriftein", "stellebindestrichein", "stelleblankoein", "stelleblockein", "stelledrehenein", "stelleduennerumrissein", "stelleeinziehenein", "stelleengerein", "stellefarbeein", "stellefarbenein", "stellefeldein", "stellefelderin", "stellefliesstextein", "stelleformelnein", "stellefusszeileein", "stellefusszeilentextein", "stellegefuelltesrechteckein", "stellegefuelltezeileein", "stellegegenueberplatzierenein", "stellegleitobjekteein", "stellegleitobjektein", "stellehintergruendeein", "stellehintergrundein", "stelleinteraktionein", "stelleinteraktionsbalkenein", "stelleinteraktionsbildschirmein", "stelleinteraktionsmenueein", "stellekommentarein", "stellekopfzahlein", "stellekopfzeileein", "stellekopfzeilentextein", "stellelayoutein", "stellelinienbreiteein", "stellelisteein", "stellemarginallinieein", "stellenobenein", "stellepaletteein", "stellepapierformatein", "stelleplatziegeteiltegleitobjekt", "stellepositionierenein", "stellepostenein", "stelleprogrammein", "stellepufferein", "stellerechteckein", "stellereferenzierenein", "stelleregisterein", "stelleseitenkommentarein", "stelleseitennummerein", "stelleseitennummeriernungein", "stelleseitenuebergangein", "stellesortierenein", "stellespaltenein", "stellespatiumein", "stellespracheein", "stellesymbolsetein", "stellesynonymein", "stelletabellenein", "stelletabulatorein", "stelletextein", "stelletextobenein", "stelletexttexteein", "stelletextumrissein", "stelletextuntenein", "stelletipein", "stelletippenein", "stelletoleranzein", "stelleueberschriftein", "stelleueberschriftenein", "stelleumbruchein", "stelleumrahmtein", "stelleumrahmtetexteein", "stelleuntenein", "stelleunterseitennummerein", "stelleurlein", "stelleversalienein", "stellezeilenabstandein", "stellezeilenein", "stellezeilennumerierungein", "stellezitierenein", "stellezusammengestelltelisteein", "stellezwischenraumein", "stopfarbe", "stophintergrund", "stopinteraktionsmenue", "stopkleinerdurchschuss", "stopkomponente", "stopkopf", "stoplinksbuendig", "stopmarginallinie", "stopplatziereformel", "stoppos", "stopprodukt", "stopprojekt", "stoppublikation", "stoprechtsbuendig", "stoptextlinie", "stopumgebung", "stopumrahmt", "stopzeile", "stopzentriert", "stopzu", "teilegleitobjekt", "textlinie", "textreferenz", "tief", "tiho", "tip", "tippedatei", "tippen", "tippepuffer", "ueber", "uebersetzten", "umgebung", "umrahmt", "unbekant", "verbergebloecke", "vergleichefarbengruppe", "vergleichepalette", "verwendeJSscript", "verwendeURL", "verwendebloecke", "verwendeexteresdokument", "verwendeexterneabbildung", "verwendeexternestonstueck", "verwendemodul", "verwendesymbole", "verwendeurl", "volleswort", "von", "waehlebloeckeaus", "wechselezumfliesstext", "wochentag", "wortrechts", "zeigedruck", "zeigeeinstellungen", "zeigefarbe", "zeigefarbengruppe", "zeigefliesstext", "zeigefliesstextumgebung", "zeigegitter", "zeigelayout", "zeigepalette", "zeigerahmen", "zeigestruts", "zeigeumbruch", "zentriert", "ziffern", "zu", "zurbox", "zurseite" },
["en"]={},
diff --git a/doc/context/documents/general/manuals/libraries-mkiv.pdf b/doc/context/documents/general/manuals/libraries-mkiv.pdf
new file mode 100644
index 000000000..f5a1e27f1
--- /dev/null
+++ b/doc/context/documents/general/manuals/libraries-mkiv.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/math-mkiv.pdf b/doc/context/documents/general/manuals/math-mkiv.pdf
index f446813b2..19fcecf13 100644
--- a/doc/context/documents/general/manuals/math-mkiv.pdf
+++ b/doc/context/documents/general/manuals/math-mkiv.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/metafun-p.pdf b/doc/context/documents/general/manuals/metafun-p.pdf
new file mode 100644
index 000000000..4a67d67a1
--- /dev/null
+++ b/doc/context/documents/general/manuals/metafun-p.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/metafun-s.pdf b/doc/context/documents/general/manuals/metafun-s.pdf
new file mode 100644
index 000000000..fea74466a
--- /dev/null
+++ b/doc/context/documents/general/manuals/metafun-s.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/mkiv-publications.pdf b/doc/context/documents/general/manuals/mkiv-publications.pdf
index 35381d8db..f428c2ca0 100644
--- a/doc/context/documents/general/manuals/mkiv-publications.pdf
+++ b/doc/context/documents/general/manuals/mkiv-publications.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/notnow.pdf b/doc/context/documents/general/manuals/notnow.pdf
new file mode 100644
index 000000000..e597a48bd
--- /dev/null
+++ b/doc/context/documents/general/manuals/notnow.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/onandon.pdf b/doc/context/documents/general/manuals/onandon.pdf
new file mode 100644
index 000000000..fe291acf0
--- /dev/null
+++ b/doc/context/documents/general/manuals/onandon.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/spacing-mkiv.pdf b/doc/context/documents/general/manuals/spacing-mkiv.pdf
index 1f0057f1d..fde9d6c70 100644
--- a/doc/context/documents/general/manuals/spacing-mkiv.pdf
+++ b/doc/context/documents/general/manuals/spacing-mkiv.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/xtables-mkiv.pdf b/doc/context/documents/general/manuals/xtables-mkiv.pdf
index fb04a53d9..d1b1a3ed0 100644
--- a/doc/context/documents/general/manuals/xtables-mkiv.pdf
+++ b/doc/context/documents/general/manuals/xtables-mkiv.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 4db161c3e..4e2a317eb 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 00872d94d..b23404020 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 4301961ca..0dfec2ab9 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 5b68155d3..9bcb77016 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 9a631dcb1..23d5ba4af 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
new file mode 100644
index 000000000..695f21829
--- /dev/null
+++ 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
new file mode 100644
index 000000000..bce5e40ee
--- /dev/null
+++ 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
new file mode 100644
index 000000000..2087f28aa
--- /dev/null
+++ 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
new file mode 100644
index 000000000..b9110b36b
--- /dev/null
+++ 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
new file mode 100644
index 000000000..5092cd018
--- /dev/null
+++ 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
new file mode 100644
index 000000000..7b55474ab
--- /dev/null
+++ 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
new file mode 100644
index 000000000..d85c7319c
--- /dev/null
+++ 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 a0fab84fb..d98bdb987 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 0a2c9159d..382c2de42 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/bachotex/2017/bachotex-2017-emoji-demo.pdf b/doc/context/presentations/bachotex/2017/bachotex-2017-emoji-demo.pdf
new file mode 100644
index 000000000..cce61e1b3
--- /dev/null
+++ b/doc/context/presentations/bachotex/2017/bachotex-2017-emoji-demo.pdf
Binary files differ
diff --git a/doc/context/presentations/bachotex/2017/bachotex-2017-emoji-demo.tex b/doc/context/presentations/bachotex/2017/bachotex-2017-emoji-demo.tex
new file mode 100644
index 000000000..ada27160b
--- /dev/null
+++ b/doc/context/presentations/bachotex/2017/bachotex-2017-emoji-demo.tex
@@ -0,0 +1,26 @@
+\starttext
+
+\definefontfeature
+ [seguiemj-cl]
+ [default]
+ [colr=yes,
+ ccmp=yes,
+ dist=yes]
+
+\definefont
+ [MyEmoji]
+ [seguiemj*seguiemj-cl]
+
+\typefile{emoji-demo-001.tex}
+
+\showotfcomposition
+ {seguiemj*seguiemj-cl}
+ {1}
+ {\resolvedemoji
+ {family
+ man light skin tone
+ woman dark skin tone
+ girl medium skin tone
+ boy medium skin tone}}
+
+\stoptext
diff --git a/doc/context/presentations/bachotex/2017/bachotex-2017-emoji.pdf b/doc/context/presentations/bachotex/2017/bachotex-2017-emoji.pdf
new file mode 100644
index 000000000..d7e01f59c
--- /dev/null
+++ b/doc/context/presentations/bachotex/2017/bachotex-2017-emoji.pdf
Binary files differ
diff --git a/doc/context/presentations/bachotex/2017/bachotex-2017-emoji.tex b/doc/context/presentations/bachotex/2017/bachotex-2017-emoji.tex
new file mode 100644
index 000000000..c6deb3873
--- /dev/null
+++ b/doc/context/presentations/bachotex/2017/bachotex-2017-emoji.tex
@@ -0,0 +1,374 @@
+% language=uk
+
+\setuppapersize
+ [S6]
+
+\setupbackgrounds
+ [page]
+ [background=color,
+ backgroundcolor=darkgray]
+
+\setuplayout
+ [backspace=24pt,
+ topspace=20pt,
+ bottomspace=8pt,
+ width=middle,
+ height=middle,
+ footerdistance=8pt,
+ footer=8pt,
+ header=0pt]
+
+\setupcolors
+ [textcolor=white]
+
+\setupbodyfont
+ [dejavu,14.4pt]
+
+\definecolor[trace:o] [s=1]
+\definecolor[trace:r] [s=1]
+\definecolor[trace:do][s=1]
+\definecolor[trace:dr][s=1]
+
+\usemodule[abr-03]
+
+\definefontfeature[noligatures][liga=no]
+
+\setuphead
+ [section]
+ [page=yes,
+ style=\bfb,
+ after={\blank[3*medium]}]
+
+\setuphead
+ [subsection]
+ [page=no,
+ style=\bf\addfeature{noligatures},
+ before={\blank[3*medium]},
+ after={\blank}]
+
+\setupfooter
+ [strut=no,
+ style=\bf]
+
+\startdocument
+ [title={Picture Fonts},
+ subtitle={welcome to a (beautiful) mess},
+ author={Hans Hagen},
+ occasion={BachoTUG 2017}]
+
+\startstandardmakeup
+ \vskip32pt
+ \bfd \setupinterlinespace
+ \documentvariable{title}
+ \crlf
+ \bfb \setupinterlinespace
+ \vskip12pt
+ \documentvariable{subtitle}
+ \vfill
+ \bfb \setupinterlinespace
+ \documentvariable{author}
+ \crlf
+ \documentvariable{occasion}
+\stopstandardmakeup
+
+\startsubject[title=A Summary]
+
+\startitemize
+\startitem
+ {\bf the macro package's view:} just a font like any other but it needs to configure
+ some extra color related properties
+\stopitem
+\startitem
+ {\bf the engine's view:} depending on the technology a normal font that needs a bit
+ special treatment or needs to be dealt with as collection of graphics
+\stopitem
+\startitem
+ {\bf the viewer's view:} regular outline glyphs or images tagged as kind of
+ characters so that their unicode representation can be cut and paste
+\stopitem
+\startitem
+ {\bf the user's view:} more pictures than glyphs although some people one can
+ communicate using them
+\stopitem
+\stopitemize
+
+So, in practice, for most \TEX\ users it's probably not a high priority font but more a fun
+one.
+
+\stopsubject
+
+\startsubject[title=Technologies]
+
+As each vendor came up with something, we have to deal with a all kinds of formats. And or
+course, as eagerness pushes things on the market before it's perfect we now have to deal
+with all of them.
+
+\startitemize
+\startitem
+ {\bf overlapping glyphs:} this technique uses the \type {colr} and \type {cpal} tables
+ and is actually a quite clean technology, you can combine in different ways
+\stopitem
+\startitem
+ {\bf svg graphics:} this technique uses the \type {svg} table that contains a svg vector
+ image
+\stopitem
+\startitem
+ {\bf bitmap graphics:} this technique uses for instance \type {sbix} tables that can have
+ various graphic images
+\stopitem
+\stopitemize
+
+The first two are already supported in the \CONTEXT\ font loader and processor
+for a while, the last one was added recently.
+
+\blank
+
+Only the overlapping method is useable for the tens of thousands of skin tone combinations of
+families, (kissing) couples, and professions.
+
+\stopsubject
+
+\startsubject[title=Preparation]
+
+For now one has to enable the feature:
+
+\startbuffer
+\definefontfeature[overlay][default][ccmp=yes,colr=yes,dist=yes]
+\definefontfeature[svg] [default][svg=yes]
+\definefontfeature[bitmap] [default][sbix=yes]
+
+\definefontfeature [colored] [default]
+ [cmcp=yes,dist=yes,
+ colr=yes,svg=yes,sbix=yes]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Defining a font is not different from others
+
+\starttyping
+\definefont[MyEmojiFont] [seguiemj*overlay]
+\definefontsynonym[emoji][seguiemj*overlay]
+\stoptyping
+
+As is using:
+
+\starttyping
+{\MyEmojiFont\resolvedemoji{woman}}
+\emoji{woman}
+\stoptyping
+
+\stopsubject
+
+\startsubject[title=Accessing shapes]
+
+\startbuffer
+\definesymbol[man] [\emoji{man}]
+\definesymbol[woman][\emoji{woman}]
+\definesymbol[girl] [\emoji{girl}]
+\definesymbol[boy] [\emoji{boy}]
+
+\definesymbol[family][\emoji{family man woman girl boy}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\starttyping
+\definefontsynonym[emoji][file:seguiemj.ttf*default,overlay]
+
+\symbol[boy] \symbol[girl] \symbol[man] \symbol[woman]
+
+\symbol[family]
+\stoptyping
+
+\stopsubject
+
+\startsubject[title=Different fonts]
+
+\def\ShowThem#1#2#3%
+ {\NC #1
+ \NC default
+ \NC \definefontsynonym[emoji][#3*default]\symbol[boy] \symbol[girl] \symbol[man] \symbol[woman]
+ \NC \definefontsynonym[emoji][#3*default]\symbol[family]
+ \NC \NR
+ \NC
+ \NC #2
+ \NC \definefontsynonym[emoji][#3*#2]\symbol[boy] \symbol[girl] \symbol[man] \symbol[woman]
+ \NC \definefontsynonym[emoji][#3*#2]\symbol[family]
+ \NC \NR}
+
+\starttabulate[|T|T|||]
+ \ShowThem{seguiemj} {overlay}{file:seguiemj.ttf}
+ \ShowThem{emojionecolor-svginot}{svg} {file:emojionecolor-svginot.ttf}
+ \ShowThem{emojionemozilla} {overlay}{file:emojionemozilla.ttf}
+ \ShowThem{applecoloremoji} {bitmap} {file:applecoloremoji.ttc}
+\stoptabulate
+
+\stopsubject
+
+\startsubject[title=Ligatures]
+
+\definefontfeature[seguiemj-cl][default][colr=yes,ccmp=yes,dist=yes]
+\definefontfeature[seguiemj-bw][default][ccmp=yes]
+
+% \definefont[MyEmoji][emojionecolor-svginot*default,svg]
+% \definefont[MyEmoji][seguiemj*seguiemj-bw]
+\definefont[MyEmoji][seguiemj*seguiemj-cl]
+% \definefont[MyEmoji][emojionemozilla*default,overlay]
+% \definefont[MyEmoji][applecoloremoji*default,bitmap]
+
+{\MyEmoji 👨🏽‍🌾 👨🏽‍🍳 👨🏽‍🎓 👨🏽‍🎤 👨🏽‍🎨 👨🏽‍🏫 👨🏽‍🏭 👨🏽‍💻 👨🏽‍💼 👨🏽‍🔧 👨🏽‍🔬 👨🏽‍🚀}
+
+\starttabulate[|T|T||]
+\NC character \NC 1F477 \NC \MyEmoji \utfchar{"1F477} \NC \NR % construction worker
+\NC skin modifier \NC 1F3FE \NC \MyEmoji \utfchar{"1F3FE} \NC \NR % medium dark skin
+\NC ligature \NC 1F477 1F3FE \NC \MyEmoji \utfchar{"1F477}%
+ \utfchar{"1F3FE} \NC \NR
+\NC zero width joiner \NC 0200D \NC \MyEmoji \utfchar{"0200D} \NC \NR
+\NC female modifier \NC 02640 0FE0F \NC \MyEmoji \utfchar{"02640}%
+ \utfchar{"0FE0F} \NC \NR
+\NC the whole lot \NC \NC \MyEmoji \utfchar{"1F477}%
+ \utfchar{"1F3FE}%
+ \utfchar{"0200D}%
+ \utfchar{"02640}%
+ \utfchar{"0FE0F} \NC \NR
+\stoptabulate
+
+\starttabulate[|T|T||]
+\NC 1F468 1F3FD 200D 1F33E \NC \MyEmoji 👨🏽‍🌾 \NC man farmer medium skin tone \NC \NR
+\NC 1F468 1F3FD 200D 1F373 \NC \MyEmoji 👨🏽‍🍳 \NC man cook medium skin tone \NC \NR
+\NC 1F468 1F3FD 200D 1F393 \NC \MyEmoji 👨🏽‍🎓 \NC man student medium skin tone \NC \NR
+\NC 1F468 1F3FD 200D 1F3A4 \NC \MyEmoji 👨🏽‍🎤 \NC man singer medium skin tone \NC \NR
+\NC 1F468 1F3FD 200D 1F3A8 \NC \MyEmoji 👨🏽‍🎨 \NC man artist medium skin tone \NC \NR
+\NC 1F468 1F3FD 200D 1F3EB \NC \MyEmoji 👨🏽‍🏫 \NC man teacher medium skin tone \NC \NR
+\NC 1F468 1F3FD 200D 1F3ED \NC \MyEmoji 👨🏽‍🏭 \NC man factory worker medium skin tone \NC \NR
+\NC 1F468 1F3FD 200D 1F4BB \NC \MyEmoji 👨🏽‍💻 \NC man technologist medium skin tone \NC \NR
+\NC 1F468 1F3FD 200D 1F4BC \NC \MyEmoji 👨🏽‍💼 \NC man office worker medium skin tone \NC \NR
+\NC 1F468 1F3FD 200D 1F527 \NC \MyEmoji 👨🏽‍🔧 \NC man mechanic medium skin tone \NC \NR
+\NC 1F468 1F3FD 200D 1F52C \NC \MyEmoji 👨🏽‍🔬 \NC man scientist medium skin tone \NC \NR
+\NC 1F468 1F3FD 200D 1F680 \NC \MyEmoji 👨🏽‍🚀 \NC man astronaut medium skin tone \NC \NR
+\stoptabulate
+
+\stopsubject
+
+\usemodule[fonts-emoji]
+
+\startsubject[title=Snippets]
+
+\start
+
+ \definedfont[seguiemj*seguiemj-cl @ 32pt]
+
+ \ShowEmojiSnippets
+ [family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone]
+
+ \vskip1ex
+
+ \ShowEmojiSnippetsOverlay
+ [family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone]
+
+ \vskip1ex
+
+ \ShowEmojiGlyphs
+ [family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone]
+
+\stop
+
+\stopsubject
+
+\startsubject[title=Using \type{\ShowEmoji[^man]}]
+
+\start
+
+ \MyEmoji
+
+ \ShowEmoji[^man]
+
+\stop
+
+\stopsubject
+
+\startsubject[title=Recoloring Seguiem]
+
+\start
+
+\definecolor[emoji-red] [r=.4]
+\definecolor[emoji-blue] [b=.4]
+\definecolor[emoji-yellow][y=.4]
+\definecolor[emoji-gray] [s=.5,t=.5,a=1]
+
+\definefontcolorpalette
+ [emoji-red]
+ [emoji-red,emoji-gray]
+
+\definefontcolorpalette
+ [emoji-blue]
+ [emoji-blue,emoji-gray]
+
+\definefontcolorpalette
+ [emoji-yellow]
+ [emoji-yellow,emoji-gray]
+
+\definefontfeature[seguiemj-r][default][ccmp=yes,dist=yes,colr=emoji-red]
+\definefontfeature[seguiemj-b][default][ccmp=yes,dist=yes,colr=emoji-blue]
+\definefontfeature[seguiemj-y][default][ccmp=yes,dist=yes,colr=emoji-yellow]
+
+\definefont[MyColoredEmojiR][seguiemj*seguiemj-r @ 80pt]
+\definefont[MyColoredEmojiB][seguiemj*seguiemj-b @ 80pt]
+\definefont[MyColoredEmojiY][seguiemj*seguiemj-y @ 80pt]
+
+\MyColoredEmojiR
+ \resolvedemoji{man}
+ \resolvedemoji{woman}
+ \resolvedemoji{baby}
+
+\vskip24pt
+
+\MyColoredEmojiB
+ \resolvedemoji{triangular ruler}
+ \resolvedemoji{rabbit face}
+ \resolvedemoji{family man woman girl boy}
+
+\vskip24pt
+
+\MyColoredEmojiY
+ \resolvedemoji{triangular ruler}
+ \resolvedemoji{rabbit face}
+ \resolvedemoji{family man woman girl boy}
+
+\stop
+
+\page
+
+\starttyping
+\definecolor [emoji-red] [r=.4]
+\definecolor [emoji-gray] [s=.5,t=.5,a=1]
+
+\definefontcolorpalette
+ [emoji-red]
+ [emoji-red,emoji-gray]
+
+\definefontfeature
+ [seguiemj-r]
+ [default]
+ [ccmp=yes,dist=yes,colr=emoji-red]
+
+\definefont
+ [MyColoredEmojiR]
+ [seguiemj*seguiemj-r @ 80pt]
+
+\MyColoredEmojiR
+ \emoji{man}
+ \emoji{woman}
+ \emoji{baby}
+\stoptyping
+
+\stopsubject
+
+\startsubject[title=Pallet \type{\ShowEmojiPalettes[1]}]
+
+{\MyEmoji \ShowEmojiPalettes[1]}
+
+\stopsubject
+
+\stopdocument
diff --git a/doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts-demo.pdf b/doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts-demo.pdf
new file mode 100644
index 000000000..bac8d54c1
--- /dev/null
+++ b/doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts-demo.pdf
Binary files differ
diff --git a/doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts-demo.tex b/doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts-demo.tex
new file mode 100644
index 000000000..e9543a30a
--- /dev/null
+++ b/doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts-demo.tex
@@ -0,0 +1,44 @@
+% macros=mkvi
+
+\usemodule[art-01] \dontcomplain
+
+\starttexdefinition unexpanded TestFont #font#variant#size
+ \bgroup
+ \definedfont[name:#font#variant*default @ #size]
+ \setupinterlinespace
+ % \showstruts
+ % \strut
+ \samplefile{tufte}
+ \par
+ \egroup
+\stoptexdefinition
+
+\starttext
+
+\dorecurse {5} {
+
+ \dostepwiserecurse {8} {14} {1} { % 30 fonts
+ \TestFont {adobevariablefontprototype} {extralight} {##1pt}
+ \TestFont {adobevariablefontprototype} {light} {##1pt}
+ \TestFont {adobevariablefontprototype} {regular} {##1pt}
+ \TestFont {adobevariablefontprototype} {semibold} {##1pt}
+ \TestFont {adobevariablefontprototype} {bold} {##1pt}
+ \TestFont {adobevariablefontprototype} {black} {##1pt}
+ }
+
+ \page
+
+ % \dostepwiserecurse {8} {14} {1} { % 40 fonts
+ % \TestFont {avenirnextvariable} {regular} {##1pt}
+ % \TestFont {avenirnextvariable} {medium} {##1pt}
+ % \TestFont {avenirnextvariable} {bold} {##1pt}
+ % \TestFont {avenirnextvariable} {heavy } {##1pt}
+ % \TestFont {avenirnextvariable} {condensed} {##1pt}
+ % \TestFont {avenirnextvariable} {medium condensed} {##1pt}
+ % \TestFont {avenirnextvariable} {bold condensed} {##1pt}
+ % \TestFont {avenirnextvariable} {heavy condensed} {##1pt}
+ % }
+
+}
+
+\stoptext
diff --git a/doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts.pdf b/doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts.pdf
new file mode 100644
index 000000000..ee3537bd2
--- /dev/null
+++ b/doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts.pdf
Binary files differ
diff --git a/doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts.tex b/doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts.tex
new file mode 100644
index 000000000..08050a57d
--- /dev/null
+++ b/doc/context/presentations/bachotex/2017/bachotex-2017-variablefonts.tex
@@ -0,0 +1,500 @@
+% language=uk
+
+\setuppapersize
+ [S6]
+
+\setupbackgrounds
+ [page]
+ [background=color,
+ backgroundcolor=darkblue]
+
+\setuplayout
+ [backspace=24pt,
+ topspace=20pt,
+ bottomspace=8pt,
+ width=middle,
+ height=middle,
+ footerdistance=8pt,
+ footer=8pt,
+ header=0pt]
+
+\setupcolors
+ [textcolor=white]
+
+\setupbodyfont
+ [dejavu,14.4pt]
+
+\definecolor[trace:o] [s=1]
+\definecolor[trace:r] [s=1]
+\definecolor[trace:do][s=1]
+\definecolor[trace:dr][s=1]
+
+\usemodule[abr-03]
+
+\definefontfeature[noligatures][liga=no]
+
+\setuphead
+ [section]
+ [page=yes,
+ style=\bfb,
+ after={\blank[3*medium]}]
+
+\setuphead
+ [subsection]
+ [page=no,
+ style=\bf\addfeature{noligatures},
+ before={\blank[3*medium]},
+ after={\blank}]
+
+\setupfooter
+ [strut=no,
+ style=\bf]
+
+\startuseMPgraphic{pagenumber}
+ if LastPageNumber > 0 :
+ draw outlinetext.f
+ (decimal RealPageNumber)
+ (withcolor "darkgray")
+ xysized ((RealPageNumber/LastPageNumber) * TextWidth/2,FooterHeight) ;
+ fi ;
+\stopuseMPgraphic
+
+\setupfootertexts
+ [\useMPgraphic{pagenumber}]
+
+\startdocument
+ [title={Variable Fonts},
+ subtitle={we're ready for them},
+ author={Hans Hagen},
+ occasion={BachoTUG 2017}]
+
+\startstandardmakeup
+ \vskip32pt
+ \bfd \setupinterlinespace
+ \documentvariable{title}
+ \crlf
+ \bfb \setupinterlinespace
+ \vskip12pt
+ \documentvariable{subtitle}
+ \vfill
+ \bfb \setupinterlinespace
+ \documentvariable{author}
+ \crlf
+ \documentvariable{occasion}
+\stopstandardmakeup
+
+\startsubject[title=A Summary]
+
+\startitemize
+\startitem
+ {\bf the macro package's view:} just a font but with many possible variations
+ in shapes (width, weight, slope, etc) and therefore a bit more complex user
+ interface
+\stopitem
+\startitem
+ {\bf the engine's view:} an abstraction not different from other fonts but
+ that needs a special treatment in the backend
+\stopitem
+\startitem
+ {\bf the viewer's view:} a font to be displayed like any other with outlines
+ in cff of ttf format
+\stopitem
+\startitem
+ {\bf the user's view:} an opentype font with possibly surprising shapes of
+ which you need to know a bit more than usual if you want to profit from it
+\stopitem
+\stopitemize
+
+So, in practice, for most \TEX\ users it's just a font that has to be supported by
+\TEX\ and friends.
+
+\stopsubject
+
+\startsubject[title=Starting point]
+
+\startitemize
+\startitem
+ The OpenType 1.8 specification at the MicroSoft website defined the extra
+ tables and explains bits and pieces.
+\stopitem
+\startitem
+ There a few fonts that have relevant tables (not all) and implement variants
+ as well as features.
+\stopitem
+\startitem
+ There are some posts on the internet that show a bit about axis and other things
+ that go on in these fonts.
+\stopitem
+\startitem
+ Luckily we have ways (in \CONTEXT) to explore what goes on in these fonts and
+ how they could look.
+\stopitem
+\startitem
+ Condition: no tricks, no fuzzy heuristics, just the specification should be
+ enough.
+\stopitem
+\stopitemize
+
+\stopsubject
+
+\startsubject[title=Implementation steps]
+
+\startitemize
+\startitem
+ First try to render variants in order to see what we're dealing with. This was not too
+ hard (starting with cff) because we have already virtual font support.
+\stopitem
+\startitem
+ Next try to load the relevant tables and figure out what these deltas and such really
+ mean and how axis and regions and \unknown\ have to be applied.
+\stopitem
+\startitem
+ Try to make it all work on a real piece of text, so not only shapes but also features
+ and dimensions.
+\stopitem
+\startitem
+ Finally make sure that the font can get embedded as a normal font and not as inline
+ (tagged) graphic.
+\stopitem
+\startitem
+ Also, try to generalize the helpers and methods in such ways that we can experiment
+ with additional tricks (after all, \TEX\ is about control).
+\stopitem
+\startitem
+ Todo: once there are more fonts (with the right data tables), check the code with the
+ specification.
+\stopitem
+\stopitemize
+
+\stopsubject
+
+\setupTABLE[c][1][style=tttf,align={flushleft,lohi}]
+
+\startsubject[title=Adobe Variable Font Prototype (cff)]
+
+\unexpanded\def\SampleFont#1#2% weight / contrast
+ {\definedfont[name:adobevariablefontprototype#1*default at 32pt]It looks like this!}
+
+\bTABLE[distance=2em,frame=off]
+\bTR \bTD extralight 0/0 \eTD \bTD \SampleFont {extralight} \eTD \eTR
+\bTR \bTD light 150/0 \eTD \bTD \SampleFont {light} \eTD \eTR
+\bTR \bTD regular 394/0 \eTD \bTD \SampleFont {regular} \eTD \eTR
+\bTR \bTD semibold 600/0 \eTD \bTD \SampleFont {semibold} \eTD \eTR
+\bTR \bTD bold 824/0 \eTD \bTD \SampleFont {bold} \eTD \eTR
+\bTR \bTD black high contrast 1000/100 \eTD \bTD \SampleFont {blackhighcontrast} \eTD \eTR
+\bTR \bTD black medium contrast 1000/50 \eTD \bTD \SampleFont {blackmediumcontrast} \eTD \eTR
+\bTR \bTD black 1000/0 \eTD \bTD \SampleFont {black} \eTD \eTR
+\eTABLE
+
+\stopsubject
+
+% \starttyping
+% \definefont
+% [MyLightFont]
+% [name:adobevariablefontprototypelight*default]
+% \stoptyping
+
+\unexpanded\def\SampleFont#1#2% weight / width
+ {\definedfont[name:avenirnextvariable#1*default at 32pt]It looks like this!}
+
+\startsubject[title=Avenir Next Variable (ttf)]
+
+\bTABLE[distance=2em,frame=off]
+\bTR \bTD regular 400/100 \eTD \bTD \SampleFont {regular} \eTD \eTR
+\bTR \bTD medium 500/100 \eTD \bTD \SampleFont {medium} \eTD \eTR
+\bTR \bTD bold 700/100 \eTD \bTD \SampleFont {bold} \eTD \eTR
+\bTR \bTD heavy 900/100 \eTD \bTD \SampleFont {heavy} \eTD \eTR
+\bTR \bTD condensed 400/75 \eTD \bTD \SampleFont {condensed} \eTD \eTR
+\bTR \bTD medium condensed 500/75 \eTD \bTD \SampleFont {mediumcondensed} \eTD \eTR
+\bTR \bTD bold condensed 700/75 \eTD \bTD \SampleFont {boldcondensed} \eTD \eTR
+\bTR \bTD heavy condensed 900/75 \eTD \bTD \SampleFont {heavycondensed} \eTD \eTR
+\eTABLE
+
+\stopsubject
+
+\startbuffer[both]
+\vfill
+\startMPcode
+ draw outlinetext.b
+ ("\getbuffer[a]")
+ (withcolor "white")
+ (withcolor "red" withpen pencircle scaled 1/10)
+ xsized .9TextWidth ;
+\stopMPcode
+\vfill
+\startMPcode
+ draw outlinetext.b
+ ("\getbuffer[b]")
+ (withcolor "white")
+ (withcolor "red" withpen pencircle scaled 1/10)
+ xsized .9TextWidth ;
+\stopMPcode
+\vfill
+\startMPcode
+ draw outlinetext.b
+ ("\getbuffer[c]")
+ (withcolor "white")
+ (withcolor "red" withpen pencircle scaled 1/10)
+ xsized .90TextWidth ;
+\stopMPcode
+\vfill
+\stopbuffer
+
+\startbuffer[fill]
+\vfill
+\startMPcode
+ draw outlinetext.f
+ ("\getbuffer[a]")
+ (withcolor "white")
+ xsized .9TextWidth ;
+\stopMPcode
+\vfill
+\startMPcode
+ draw outlinetext.f
+ ("\getbuffer[b]")
+ (withcolor "white")
+ xsized .9TextWidth ;
+\stopMPcode
+\vfill
+\startMPcode
+ draw outlinetext.f
+ ("\getbuffer[c]")
+ (withcolor "white")
+ xsized .9TextWidth ;
+\stopMPcode
+\vfill
+\stopbuffer
+
+\startbuffer[draw]
+\vfill
+\startMPcode
+ draw outlinetext.d
+ ("\getbuffer[a]")
+ (withcolor "white" withpen pencircle scaled 1/10)
+ xsized .9TextWidth ;
+\stopMPcode
+\vfill
+\startMPcode
+ draw outlinetext.d
+ ("\getbuffer[b]")
+ (withcolor "white" withpen pencircle scaled 1/10)
+ xsized .9TextWidth ;
+\stopMPcode
+\vfill
+\startMPcode
+ draw outlinetext.d
+ ("\getbuffer[c]")
+ (withcolor "white" withpen pencircle scaled 1/10)
+ xsized .9TextWidth ;
+\stopMPcode
+\vfill
+\stopbuffer
+
+\startbuffer[overlay]
+\startoverlay{%
+\startMPcode
+ draw outlinetext.d
+ ("\getbuffer[a]")
+ (withcolor "green" withtransparency (3,0.5) withpen pencircle scaled 1/10)
+ xsized .9TextWidth ;
+\stopMPcode
+}{%
+\startMPcode
+ draw outlinetext.d
+ ("\getbuffer[b]")
+ (withcolor "yellow" withtransparency (3,0.5) withpen pencircle scaled 1/10)
+ xsized .9TextWidth ;
+\stopMPcode
+}{%
+\startMPcode
+ draw outlinetext.d
+ ("\getbuffer[c]")
+ (withcolor "red" withtransparency (3,0.5) withpen pencircle scaled 1/10)
+ xsized .9TextWidth ;
+\stopMPcode
+}
+\stopoverlay
+\stopbuffer
+
+\startbuffer[a]
+\definedfont[name:adobevariablefontprototypeextralight]bachotex%
+\stopbuffer
+
+\startbuffer[b]
+\definedfont[name:adobevariablefontprototypelight]bachotex%
+\stopbuffer
+
+\startbuffer[c]
+\definedfont[name:adobevariablefontprototypebold]bachotex%
+\stopbuffer
+
+\startsubject[title=Metafontisch overlap (1)]
+ \getbuffer[both]
+\stopsubject
+
+\startbuffer[a]
+\definefontfeature[whatever][axis={weight:50}]%
+\definedfont[name:adobevariablefontprototype*whatever]bachotex%
+\stopbuffer
+
+\startbuffer[b]
+\definefontfeature[whatever][axis={weight:300}]%
+\definedfont[name:adobevariablefontprototype*whatever]bachotex%
+\stopbuffer
+
+\startbuffer[c]
+\definefontfeature[whatever][axis={weight:700}]%
+\definedfont[name:adobevariablefontprototype*whatever]bachotex%
+\stopbuffer
+
+\startsubject[title=Metafontisch overlap (2)]
+ \getbuffer[both]
+\stopsubject
+\startsubject[title=Fills hide the details]
+ \getbuffer[fill]
+\stopsubject
+\startsubject[title=Unsuitable outlines]
+ \getbuffer[draw]
+\stopsubject
+
+\startbuffer[a]
+\definefontfeature[whatever][axis={weight:100,contrast:0}]%
+\definedfont[name:adobevariablefontprototype*whatever]bachotex%
+\stopbuffer
+
+\startbuffer[b]
+\definefontfeature[whatever][axis={weight:200,contrast:20}]%
+\definedfont[name:adobevariablefontprototype*whatever]bachotex%
+\stopbuffer
+
+\startbuffer[c]
+\definefontfeature[whatever][axis={weight:200,contrast:50}]%
+\definedfont[name:adobevariablefontprototype*whatever]bachotex%
+\stopbuffer
+
+\startsubject[title=Stay within specification]
+ \getbuffer[draw]
+\stopsubject
+
+\startsubject[title=Subjective choices]
+ \getbuffer[fill]
+\stopsubject
+
+\startbuffer[a]
+\definefontfeature[whatever][axis={weight:100,contrast:0}]%
+\definedfont[name:adobevariablefontprototype*whatever]tex%
+\stopbuffer
+
+\startbuffer[b]
+\definefontfeature[whatever][axis={weight:200,contrast:20}]%
+\definedfont[name:adobevariablefontprototype*whatever]tex%
+\stopbuffer
+
+\startbuffer[c]
+\definefontfeature[whatever][axis={weight:200,contrast:50}]%
+\definedfont[name:adobevariablefontprototype*whatever]tex%
+\stopbuffer
+
+\startsubject[title=Difficult choices]
+ \getbuffer[overlay]
+\stopsubject
+
+\startsubject[title=Definitions (1)]
+
+\startbuffer
+\definefontfeature
+ [default:shaped]
+ [default]
+ [axis={width:10}]
+
+\definefont
+ [SomeFont]
+ [file:avenirnextvariable*default:shaped]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\start \setupinterlinespace \showglyphs \showfontkerns \SomeFont \input zapf \wordright{Hermann Zapf}\par \stop
+
+\stopsubject
+
+\startsubject[title=Definitions (2)]
+
+\startbuffer
+\definefontfeature
+ [default:shaped]
+ [default]
+ [axis={width:100,weight=200}]
+
+\definefont
+ [SomeFont]
+ [file:avenirnextvariable*default:shaped @ 12pt]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\start \setupinterlinespace \showglyphs \showfontkerns \SomeFont \input zapf \wordright{Hermann Zapf}\par \stop
+
+\stopsubject
+
+\startsubject[title=Transformations]
+
+\subsubject{correction:}
+
+\startformula
+ x^\prime = x
+ + s_{x1} \cdot x_1
+ + s_{x2} \cdot x_2
+ + s_{x3} \cdot x_3
+ + s_{x4} \cdot x_4
+\stopformula
+
+\startformula
+ y^\prime = y
+ + s_{y1} \cdot y_1
+ + s_{y2} \cdot y_2
+ + s_{y3} \cdot y_3
+ + s_{y4} \cdot y_4
+\stopformula
+
+\subsubject{internal cff:}
+
+\starttyping
+1 <setvstore>
+120 [10 -30 40 -60] 1 <blend> ... <operator>
+100 120 [10 -30 40 -60] [30 -10 -30 20] 2 <blend> .. <operator>
+\stoptyping
+
+\subsubject{external ttf:}
+
+\starttyping
+apply x deltas [10 -30 40 -60] to x 120
+apply y deltas [30 -10 -30 20] to y 100
+\stoptyping
+
+\stopsubject
+
+\startsubject[title=Follow up]
+
+\startitemize
+\startitem
+ Performance is quite okay because we cache instances. I might come up with an
+ alternative way but there is not much to gain.
+\stopitem
+\startitem
+ Once fonts show up alternative interfaces to axis and scaling can be explored
+ and provided.
+\stopitem
+\startitem
+ I will look into ways to do all the backend font code in \CONTEXT\ in \LUA\
+ (easier to update and more flexible).
+\stopitem
+\startitem
+ Luigi and I will play with variable fonts defined in the traditional meta tools
+ that come with \TEX.
+\stopitem
+\stopitemize
+
+\stopsubject
+
+\stopdocument
diff --git a/doc/context/scripts/mkii/ctxtools.man b/doc/context/scripts/mkii/ctxtools.man
index d85ab59e4..54a0a442c 100644
--- a/doc/context/scripts/mkii/ctxtools.man
+++ b/doc/context/scripts/mkii/ctxtools.man
@@ -1,4 +1,4 @@
-.TH "ctxtools" "1" "01-01-2017" "version 1.3.5" "CtxTools"
+.TH "ctxtools" "1" "01-01-2018" "version 1.3.5" "CtxTools"
.SH NAME
.B ctxtools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/imgtopdf.man b/doc/context/scripts/mkii/imgtopdf.man
index 4cebf81fe..11cc46f95 100644
--- a/doc/context/scripts/mkii/imgtopdf.man
+++ b/doc/context/scripts/mkii/imgtopdf.man
@@ -1,4 +1,4 @@
-.TH "imgtopdf" "1" "01-01-2017" "version 1.1.2" "ImgToPdf"
+.TH "imgtopdf" "1" "01-01-2018" "version 1.1.2" "ImgToPdf"
.SH NAME
.B imgtopdf
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/mptopdf.man b/doc/context/scripts/mkii/mptopdf.man
index e1c4ff914..c6f4655e0 100644
--- a/doc/context/scripts/mkii/mptopdf.man
+++ b/doc/context/scripts/mkii/mptopdf.man
@@ -1,4 +1,4 @@
-.TH "mptopdf" "1" "01-01-2017" "version 1.4.1" "convert MetaPost figures to PDF"
+.TH "mptopdf" "1" "01-01-2018" "version 1.4.1" "convert MetaPost figures to PDF"
.SH NAME
.B mptopdf
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/pdftools.man b/doc/context/scripts/mkii/pdftools.man
index b59b9494e..556035a0f 100644
--- a/doc/context/scripts/mkii/pdftools.man
+++ b/doc/context/scripts/mkii/pdftools.man
@@ -1,4 +1,4 @@
-.TH "pdftools" "1" "01-01-2017" "version 1.2.1" "PDFTools"
+.TH "pdftools" "1" "01-01-2018" "version 1.2.1" "PDFTools"
.SH NAME
.B pdftools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/pstopdf.man b/doc/context/scripts/mkii/pstopdf.man
index b633c731f..1502fa168 100644
--- a/doc/context/scripts/mkii/pstopdf.man
+++ b/doc/context/scripts/mkii/pstopdf.man
@@ -1,4 +1,4 @@
-.TH "pstopdf" "1" "01-01-2017" "version 2.0.1" "PStoPDF"
+.TH "pstopdf" "1" "01-01-2018" "version 2.0.1" "PStoPDF"
.SH NAME
.B pstopdf
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/rlxtools.man b/doc/context/scripts/mkii/rlxtools.man
index 934623a79..56bc3c690 100644
--- a/doc/context/scripts/mkii/rlxtools.man
+++ b/doc/context/scripts/mkii/rlxtools.man
@@ -1,4 +1,4 @@
-.TH "rlxtools" "1" "01-01-2017" "version 1.0.1" "RlxTools"
+.TH "rlxtools" "1" "01-01-2018" "version 1.0.1" "RlxTools"
.SH NAME
.B rlxtools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/texexec.man b/doc/context/scripts/mkii/texexec.man
index c0b2a0f35..8de194d39 100644
--- a/doc/context/scripts/mkii/texexec.man
+++ b/doc/context/scripts/mkii/texexec.man
@@ -1,4 +1,4 @@
-.TH "texexec" "1" "01-01-2017" "version 6.2.1" "TeXExec"
+.TH "texexec" "1" "01-01-2018" "version 6.2.1" "TeXExec"
.SH NAME
.B texexec
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/texmfstart.man b/doc/context/scripts/mkii/texmfstart.man
index b79d1603f..fdff5103c 100644
--- a/doc/context/scripts/mkii/texmfstart.man
+++ b/doc/context/scripts/mkii/texmfstart.man
@@ -1,4 +1,4 @@
-.TH "mtxrun" "1" "01-01-2017" "version 1.33" "ConTeXt TDS Runner Tool"
+.TH "mtxrun" "1" "01-01-2018" "version 1.33" "ConTeXt TDS Runner Tool"
.SH NAME
.B mtxrun
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/textools.man b/doc/context/scripts/mkii/textools.man
index 578c0ded5..d355ccf5d 100644
--- a/doc/context/scripts/mkii/textools.man
+++ b/doc/context/scripts/mkii/textools.man
@@ -1,4 +1,4 @@
-.TH "textools" "1" "01-01-2017" "version 1.3.1" "TeXTools"
+.TH "textools" "1" "01-01-2018" "version 1.3.1" "TeXTools"
.SH NAME
.B textools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/texutil.man b/doc/context/scripts/mkii/texutil.man
index c086eb603..918660e45 100644
--- a/doc/context/scripts/mkii/texutil.man
+++ b/doc/context/scripts/mkii/texutil.man
@@ -1,4 +1,4 @@
-.TH "texutil" "1" "01-01-2017" "version 9.1.0" "TeXUtil"
+.TH "texutil" "1" "01-01-2018" "version 9.1.0" "TeXUtil"
.SH NAME
.B texutil
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/tmftools.man b/doc/context/scripts/mkii/tmftools.man
index f3fe4cade..68550bb00 100644
--- a/doc/context/scripts/mkii/tmftools.man
+++ b/doc/context/scripts/mkii/tmftools.man
@@ -1,4 +1,4 @@
-.TH "tmftools" "1" "01-01-2017" "version 1.1.0" "TMFTools"
+.TH "tmftools" "1" "01-01-2018" "version 1.1.0" "TMFTools"
.SH NAME
.B tmftools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/xmltools.man b/doc/context/scripts/mkii/xmltools.man
index 1da86756c..aacd5ee78 100644
--- a/doc/context/scripts/mkii/xmltools.man
+++ b/doc/context/scripts/mkii/xmltools.man
@@ -1,4 +1,4 @@
-.TH "xmltools" "1" "01-01-2017" "version 1.2.2" "XMLTools"
+.TH "xmltools" "1" "01-01-2018" "version 1.2.2" "XMLTools"
.SH NAME
.B xmltools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/context.man b/doc/context/scripts/mkiv/context.man
index 630fe6bec..e1480b4c5 100644
--- a/doc/context/scripts/mkiv/context.man
+++ b/doc/context/scripts/mkiv/context.man
@@ -1,4 +1,4 @@
-.TH "mtx-context" "1" "01-01-2017" "version 1.01" "ConTeXt Process Management"
+.TH "mtx-context" "1" "01-01-2018" "version 1.01" "ConTeXt Process Management"
.SH NAME
.B mtx-context
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/luatools.man b/doc/context/scripts/mkiv/luatools.man
index 7795a18a4..8cdcf0fd6 100644
--- a/doc/context/scripts/mkiv/luatools.man
+++ b/doc/context/scripts/mkiv/luatools.man
@@ -1,4 +1,4 @@
-.TH "luatools" "1" "01-01-2017" "version 1.35" "ConTeXt TDS Management Tool (aka luatools)"
+.TH "luatools" "1" "01-01-2018" "version 1.35" "ConTeXt TDS Management Tool (aka luatools)"
.SH NAME
.B luatools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-babel.man b/doc/context/scripts/mkiv/mtx-babel.man
index 236434f94..712911333 100644
--- a/doc/context/scripts/mkiv/mtx-babel.man
+++ b/doc/context/scripts/mkiv/mtx-babel.man
@@ -1,4 +1,4 @@
-.TH "mtx-babel" "1" "01-01-2017" "version 1.20" "Babel Input To UTF Conversion"
+.TH "mtx-babel" "1" "01-01-2018" "version 1.20" "Babel Input To UTF Conversion"
.SH NAME
.B mtx-babel
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-base.man b/doc/context/scripts/mkiv/mtx-base.man
index d092ae514..c38347353 100644
--- a/doc/context/scripts/mkiv/mtx-base.man
+++ b/doc/context/scripts/mkiv/mtx-base.man
@@ -1,4 +1,4 @@
-.TH "mtx-base" "1" "01-01-2017" "version 1.35" "ConTeXt TDS Management Tool (aka luatools)"
+.TH "mtx-base" "1" "01-01-2018" "version 1.35" "ConTeXt TDS Management Tool (aka luatools)"
.SH NAME
.B mtx-base
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-bibtex.man b/doc/context/scripts/mkiv/mtx-bibtex.man
index c7fbe4261..9553b900d 100644
--- a/doc/context/scripts/mkiv/mtx-bibtex.man
+++ b/doc/context/scripts/mkiv/mtx-bibtex.man
@@ -1,4 +1,4 @@
-.TH "mtx-bibtex" "1" "01-01-2017" "version 1.00" "bibtex helpers"
+.TH "mtx-bibtex" "1" "01-01-2018" "version 1.00" "bibtex helpers"
.SH NAME
.B mtx-bibtex
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-cache.man b/doc/context/scripts/mkiv/mtx-cache.man
index f0f6a11ac..188e72078 100644
--- a/doc/context/scripts/mkiv/mtx-cache.man
+++ b/doc/context/scripts/mkiv/mtx-cache.man
@@ -1,4 +1,4 @@
-.TH "mtx-cache" "1" "01-01-2017" "version 0.10" "ConTeXt & MetaTeX Cache Management"
+.TH "mtx-cache" "1" "01-01-2018" "version 0.10" "ConTeXt & MetaTeX Cache Management"
.SH NAME
.B mtx-cache
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-chars.man b/doc/context/scripts/mkiv/mtx-chars.man
index 9afac1b5c..8914c9ed5 100644
--- a/doc/context/scripts/mkiv/mtx-chars.man
+++ b/doc/context/scripts/mkiv/mtx-chars.man
@@ -1,4 +1,4 @@
-.TH "mtx-chars" "1" "01-01-2017" "version 0.10" "MkII Character Table Generators"
+.TH "mtx-chars" "1" "01-01-2018" "version 0.10" "MkII Character Table Generators"
.SH NAME
.B mtx-chars
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-check.man b/doc/context/scripts/mkiv/mtx-check.man
index 2a23dce7f..9c1f02a49 100644
--- a/doc/context/scripts/mkiv/mtx-check.man
+++ b/doc/context/scripts/mkiv/mtx-check.man
@@ -1,4 +1,4 @@
-.TH "mtx-check" "1" "01-01-2017" "version 0.10" "Basic ConTeXt Syntax Checking"
+.TH "mtx-check" "1" "01-01-2018" "version 0.10" "Basic ConTeXt Syntax Checking"
.SH NAME
.B mtx-check
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-colors.man b/doc/context/scripts/mkiv/mtx-colors.man
index fb7800586..de271e01b 100644
--- a/doc/context/scripts/mkiv/mtx-colors.man
+++ b/doc/context/scripts/mkiv/mtx-colors.man
@@ -1,4 +1,4 @@
-.TH "mtx-colors" "1" "01-01-2017" "version 0.10" "ConTeXt Color Management"
+.TH "mtx-colors" "1" "01-01-2018" "version 0.10" "ConTeXt Color Management"
.SH NAME
.B mtx-colors
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-context.man b/doc/context/scripts/mkiv/mtx-context.man
index 630fe6bec..e1480b4c5 100644
--- a/doc/context/scripts/mkiv/mtx-context.man
+++ b/doc/context/scripts/mkiv/mtx-context.man
@@ -1,4 +1,4 @@
-.TH "mtx-context" "1" "01-01-2017" "version 1.01" "ConTeXt Process Management"
+.TH "mtx-context" "1" "01-01-2018" "version 1.01" "ConTeXt Process Management"
.SH NAME
.B mtx-context
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-dvi.man b/doc/context/scripts/mkiv/mtx-dvi.man
index 09a1301c0..29c5dd772 100644
--- a/doc/context/scripts/mkiv/mtx-dvi.man
+++ b/doc/context/scripts/mkiv/mtx-dvi.man
@@ -1,4 +1,4 @@
-.TH "mtx-dvi" "1" "01-01-2017" "version 0.01" "ConTeXt DVI Helpers"
+.TH "mtx-dvi" "1" "01-01-2018" "version 0.01" "ConTeXt DVI Helpers"
.SH NAME
.B mtx-dvi
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-epub.man b/doc/context/scripts/mkiv/mtx-epub.man
index a3101e84b..3e6875204 100644
--- a/doc/context/scripts/mkiv/mtx-epub.man
+++ b/doc/context/scripts/mkiv/mtx-epub.man
@@ -1,4 +1,4 @@
-.TH "mtx-epub" "1" "01-01-2017" "version 1.10" "ConTeXt EPUB Helpers"
+.TH "mtx-epub" "1" "01-01-2018" "version 1.10" "ConTeXt EPUB Helpers"
.SH NAME
.B mtx-epub
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-evohome.html b/doc/context/scripts/mkiv/mtx-evohome.html
index e2d41ea82..dc21f7721 100644
--- a/doc/context/scripts/mkiv/mtx-evohome.html
+++ b/doc/context/scripts/mkiv/mtx-evohome.html
@@ -42,10 +42,13 @@
<tr><th>--collect</th><td></td><td>collect data from device</td></tr>
<tr><th>--presets</th><td></td><td>file with authenciation data</td></tr>
<tr><th>--auto</th><td></td><td>fetch temperature data every hour</td></tr>
+ <tr><th>--port</th><td></td><td>server port when running the service, default: 8068</td></tr>
+ <tr><th>--host</th><td></td><td>server host when running the service, default: localhost</td></tr>
</table>
<br/>
<h1>Example</h1>
<tt>mtxrun --script evohome --collect --presets=c:/data/develop/domotica/code/evohome-presets.lua</tt>
+<br/><tt>mtxrun --script evohome --server --presets=c:/data/develop/domotica/code/evohome-presets.lua</tt>
<br/><br/> </div>
</div>
</body>
diff --git a/doc/context/scripts/mkiv/mtx-evohome.man b/doc/context/scripts/mkiv/mtx-evohome.man
index 37b53e945..3c20161dc 100644
--- a/doc/context/scripts/mkiv/mtx-evohome.man
+++ b/doc/context/scripts/mkiv/mtx-evohome.man
@@ -1,4 +1,4 @@
-.TH "mtx-evohome" "1" "01-01-2017" "version 1.00" "Evohome Fetcher"
+.TH "mtx-evohome" "1" "01-01-2018" "version 1.00" "Evohome Fetcher"
.SH NAME
.B mtx-evohome
.SH SYNOPSIS
@@ -19,6 +19,12 @@ file with authenciation data
.TP
.B --auto
fetch temperature data every hour
+.TP
+.B --port
+server port when running the service, default: 8068
+.TP
+.B --host
+server host when running the service, default: localhost
.SH AUTHOR
More information about ConTeXt and the tools that come with it can be found at:
diff --git a/doc/context/scripts/mkiv/mtx-evohome.xml b/doc/context/scripts/mkiv/mtx-evohome.xml
index 4c69e39ad..7224d4183 100644
--- a/doc/context/scripts/mkiv/mtx-evohome.xml
+++ b/doc/context/scripts/mkiv/mtx-evohome.xml
@@ -11,6 +11,8 @@
<flag name="collect"><short>collect data from device</short></flag>
<flag name="presets"><short>file with authenciation data</short></flag>
<flag name="auto"><short>fetch temperature data every hour</short></flag>
+ <flag name="port"><short>server port when running the service, default: 8068</short></flag>
+ <flag name="host"><short>server host when running the service, default: localhost</short></flag>
</subcategory>
</category>
</flags>
@@ -19,6 +21,7 @@
<title>Example</title>
<subcategory>
<example><command>mtxrun --script evohome --collect --presets=c:/data/develop/domotica/code/evohome-presets.lua</command></example>
+ <example><command>mtxrun --script evohome --server --presets=c:/data/develop/domotica/code/evohome-presets.lua</command></example>
</subcategory>
</category>
</examples>
diff --git a/doc/context/scripts/mkiv/mtx-fcd.man b/doc/context/scripts/mkiv/mtx-fcd.man
index c322b55ed..7b668b091 100644
--- a/doc/context/scripts/mkiv/mtx-fcd.man
+++ b/doc/context/scripts/mkiv/mtx-fcd.man
@@ -1,4 +1,4 @@
-.TH "mtx-fcd" "1" "01-01-2017" "version 1.00" "Fast Directory Change"
+.TH "mtx-fcd" "1" "01-01-2018" "version 1.00" "Fast Directory Change"
.SH NAME
.B mtx-fcd
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-flac.man b/doc/context/scripts/mkiv/mtx-flac.man
index 87aa90dda..02c977d76 100644
--- a/doc/context/scripts/mkiv/mtx-flac.man
+++ b/doc/context/scripts/mkiv/mtx-flac.man
@@ -1,4 +1,4 @@
-.TH "mtx-flac" "1" "01-01-2017" "version 0.10" "ConTeXt Flac Helpers"
+.TH "mtx-flac" "1" "01-01-2018" "version 0.10" "ConTeXt Flac Helpers"
.SH NAME
.B mtx-flac
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-fonts.man b/doc/context/scripts/mkiv/mtx-fonts.man
index 46eee5acc..c27731e33 100644
--- a/doc/context/scripts/mkiv/mtx-fonts.man
+++ b/doc/context/scripts/mkiv/mtx-fonts.man
@@ -1,4 +1,4 @@
-.TH "mtx-fonts" "1" "01-01-2017" "version 1.00" "ConTeXt Font Database Management"
+.TH "mtx-fonts" "1" "01-01-2018" "version 1.00" "ConTeXt Font Database Management"
.SH NAME
.B mtx-fonts
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-grep.man b/doc/context/scripts/mkiv/mtx-grep.man
index 3254c904d..19675cc51 100644
--- a/doc/context/scripts/mkiv/mtx-grep.man
+++ b/doc/context/scripts/mkiv/mtx-grep.man
@@ -1,4 +1,4 @@
-.TH "mtx-grep" "1" "01-01-2017" "version 0.10" "Simple Grepper"
+.TH "mtx-grep" "1" "01-01-2018" "version 0.10" "Simple Grepper"
.SH NAME
.B mtx-grep
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-interface.man b/doc/context/scripts/mkiv/mtx-interface.man
index 831b9acc9..7dab0d528 100644
--- a/doc/context/scripts/mkiv/mtx-interface.man
+++ b/doc/context/scripts/mkiv/mtx-interface.man
@@ -1,4 +1,4 @@
-.TH "mtx-interface" "1" "01-01-2017" "version 0.13" "ConTeXt Interface Related Goodies"
+.TH "mtx-interface" "1" "01-01-2018" "version 0.13" "ConTeXt Interface Related Goodies"
.SH NAME
.B mtx-interface
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-metapost.man b/doc/context/scripts/mkiv/mtx-metapost.man
index 66f178287..e8e7b465e 100644
--- a/doc/context/scripts/mkiv/mtx-metapost.man
+++ b/doc/context/scripts/mkiv/mtx-metapost.man
@@ -1,4 +1,4 @@
-.TH "mtx-metapost" "1" "01-01-2017" "version 0.10" "MetaPost to PDF processor"
+.TH "mtx-metapost" "1" "01-01-2018" "version 0.10" "MetaPost to PDF processor"
.SH NAME
.B mtx-metapost
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-metatex.man b/doc/context/scripts/mkiv/mtx-metatex.man
index 1ff5ec367..fd45e312f 100644
--- a/doc/context/scripts/mkiv/mtx-metatex.man
+++ b/doc/context/scripts/mkiv/mtx-metatex.man
@@ -1,4 +1,4 @@
-.TH "mtx-metatex" "1" "01-01-2017" "version 0.10" "MetaTeX Process Management"
+.TH "mtx-metatex" "1" "01-01-2018" "version 0.10" "MetaTeX Process Management"
.SH NAME
.B mtx-metatex
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-modules.man b/doc/context/scripts/mkiv/mtx-modules.man
index 0455d83c9..c0441a93d 100644
--- a/doc/context/scripts/mkiv/mtx-modules.man
+++ b/doc/context/scripts/mkiv/mtx-modules.man
@@ -1,4 +1,4 @@
-.TH "mtx-modules" "1" "01-01-2017" "version 1.00" "ConTeXt Module Documentation Generators"
+.TH "mtx-modules" "1" "01-01-2018" "version 1.00" "ConTeXt Module Documentation Generators"
.SH NAME
.B mtx-modules
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-package.man b/doc/context/scripts/mkiv/mtx-package.man
index 2ff4a165a..958e4a975 100644
--- a/doc/context/scripts/mkiv/mtx-package.man
+++ b/doc/context/scripts/mkiv/mtx-package.man
@@ -1,4 +1,4 @@
-.TH "mtx-package" "1" "01-01-2017" "version 0.10" "Distribution Related Goodies"
+.TH "mtx-package" "1" "01-01-2018" "version 0.10" "Distribution Related Goodies"
.SH NAME
.B mtx-package
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-patterns.man b/doc/context/scripts/mkiv/mtx-patterns.man
index c962da2e8..1b7906b23 100644
--- a/doc/context/scripts/mkiv/mtx-patterns.man
+++ b/doc/context/scripts/mkiv/mtx-patterns.man
@@ -1,4 +1,4 @@
-.TH "mtx-patterns" "1" "01-01-2017" "version 0.20" "ConTeXt Pattern File Management"
+.TH "mtx-patterns" "1" "01-01-2018" "version 0.20" "ConTeXt Pattern File Management"
.SH NAME
.B mtx-patterns
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-pdf.man b/doc/context/scripts/mkiv/mtx-pdf.man
index fa702b86c..30aacc03a 100644
--- a/doc/context/scripts/mkiv/mtx-pdf.man
+++ b/doc/context/scripts/mkiv/mtx-pdf.man
@@ -1,4 +1,4 @@
-.TH "mtx-pdf" "1" "01-01-2017" "version 0.10" "ConTeXt PDF Helpers"
+.TH "mtx-pdf" "1" "01-01-2018" "version 0.10" "ConTeXt PDF Helpers"
.SH NAME
.B mtx-pdf
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-plain.man b/doc/context/scripts/mkiv/mtx-plain.man
index 73c1a9377..fbdf301f7 100644
--- a/doc/context/scripts/mkiv/mtx-plain.man
+++ b/doc/context/scripts/mkiv/mtx-plain.man
@@ -1,4 +1,4 @@
-.TH "mtx-plain" "1" "01-01-2017" "version 1.00" "Plain TeX Runner"
+.TH "mtx-plain" "1" "01-01-2018" "version 1.00" "Plain TeX Runner"
.SH NAME
.B mtx-plain
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-profile.man b/doc/context/scripts/mkiv/mtx-profile.man
index 862afe5fb..fefc60e74 100644
--- a/doc/context/scripts/mkiv/mtx-profile.man
+++ b/doc/context/scripts/mkiv/mtx-profile.man
@@ -1,4 +1,4 @@
-.TH "mtx-profile" "1" "01-01-2017" "version 1.00" "ConTeXt MkIV LuaTeX Profiler"
+.TH "mtx-profile" "1" "01-01-2018" "version 1.00" "ConTeXt MkIV LuaTeX Profiler"
.SH NAME
.B mtx-profile
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-rsync.man b/doc/context/scripts/mkiv/mtx-rsync.man
index 13c838fd7..6b7e6e8bc 100644
--- a/doc/context/scripts/mkiv/mtx-rsync.man
+++ b/doc/context/scripts/mkiv/mtx-rsync.man
@@ -1,4 +1,4 @@
-.TH "mtx-rsync" "1" "01-01-2017" "version 0.10" "Rsync Helpers"
+.TH "mtx-rsync" "1" "01-01-2018" "version 0.10" "Rsync Helpers"
.SH NAME
.B mtx-rsync
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-scite.man b/doc/context/scripts/mkiv/mtx-scite.man
index 4911790f2..58733624d 100644
--- a/doc/context/scripts/mkiv/mtx-scite.man
+++ b/doc/context/scripts/mkiv/mtx-scite.man
@@ -1,4 +1,4 @@
-.TH "mtx-scite" "1" "01-01-2017" "version 1.00" "Scite Helper Script"
+.TH "mtx-scite" "1" "01-01-2018" "version 1.00" "Scite Helper Script"
.SH NAME
.B mtx-scite
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-server.man b/doc/context/scripts/mkiv/mtx-server.man
index 5dec932e3..dfda87e71 100644
--- a/doc/context/scripts/mkiv/mtx-server.man
+++ b/doc/context/scripts/mkiv/mtx-server.man
@@ -1,4 +1,4 @@
-.TH "mtx-server" "1" "01-01-2017" "version 0.10" "Simple Webserver For Helpers"
+.TH "mtx-server" "1" "01-01-2018" "version 0.10" "Simple Webserver For Helpers"
.SH NAME
.B mtx-server
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-texworks.man b/doc/context/scripts/mkiv/mtx-texworks.man
index e475dc10e..1e29cb7db 100644
--- a/doc/context/scripts/mkiv/mtx-texworks.man
+++ b/doc/context/scripts/mkiv/mtx-texworks.man
@@ -1,4 +1,4 @@
-.TH "mtx-texworks" "1" "01-01-2017" "version 1.00" "TeXworks Startup Script"
+.TH "mtx-texworks" "1" "01-01-2018" "version 1.00" "TeXworks Startup Script"
.SH NAME
.B mtx-texworks
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-timing.man b/doc/context/scripts/mkiv/mtx-timing.man
index 3a9f76a5e..785c40d78 100644
--- a/doc/context/scripts/mkiv/mtx-timing.man
+++ b/doc/context/scripts/mkiv/mtx-timing.man
@@ -1,4 +1,4 @@
-.TH "mtx-timing" "1" "01-01-2017" "version 0.10" "ConTeXt Timing Tools"
+.TH "mtx-timing" "1" "01-01-2018" "version 0.10" "ConTeXt Timing Tools"
.SH NAME
.B mtx-timing
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-tools.man b/doc/context/scripts/mkiv/mtx-tools.man
index d5be45d72..d3a92138d 100644
--- a/doc/context/scripts/mkiv/mtx-tools.man
+++ b/doc/context/scripts/mkiv/mtx-tools.man
@@ -1,4 +1,4 @@
-.TH "mtx-tools" "1" "01-01-2017" "version 1.01" "Some File Related Goodies"
+.TH "mtx-tools" "1" "01-01-2018" "version 1.01" "Some File Related Goodies"
.SH NAME
.B mtx-tools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-unicode.man b/doc/context/scripts/mkiv/mtx-unicode.man
index 3d9ec0785..a4665374f 100644
--- a/doc/context/scripts/mkiv/mtx-unicode.man
+++ b/doc/context/scripts/mkiv/mtx-unicode.man
@@ -1,4 +1,4 @@
-.TH "mtx-unicode" "1" "01-01-2017" "version 1.02" "Checker for char-dat.lua"
+.TH "mtx-unicode" "1" "01-01-2018" "version 1.02" "Checker for char-dat.lua"
.SH NAME
.B mtx-unicode
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-unzip.man b/doc/context/scripts/mkiv/mtx-unzip.man
index d6e3ded10..f2a382ad1 100644
--- a/doc/context/scripts/mkiv/mtx-unzip.man
+++ b/doc/context/scripts/mkiv/mtx-unzip.man
@@ -1,4 +1,4 @@
-.TH "mtx-unzip" "1" "01-01-2017" "version 0.10" "Simple Unzipper"
+.TH "mtx-unzip" "1" "01-01-2018" "version 0.10" "Simple Unzipper"
.SH NAME
.B mtx-unzip
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-update.man b/doc/context/scripts/mkiv/mtx-update.man
index ed7d09b9c..79743d7d5 100644
--- a/doc/context/scripts/mkiv/mtx-update.man
+++ b/doc/context/scripts/mkiv/mtx-update.man
@@ -1,4 +1,4 @@
-.TH "mtx-update" "1" "01-01-2017" "version 1.03" "ConTeXt Minimals Updater"
+.TH "mtx-update" "1" "01-01-2018" "version 1.03" "ConTeXt Minimals Updater"
.SH NAME
.B mtx-update
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-watch.man b/doc/context/scripts/mkiv/mtx-watch.man
index acb5ff22d..82dccbb8e 100644
--- a/doc/context/scripts/mkiv/mtx-watch.man
+++ b/doc/context/scripts/mkiv/mtx-watch.man
@@ -1,4 +1,4 @@
-.TH "mtx-watch" "1" "01-01-2017" "version 1.00" "ConTeXt Request Watchdog"
+.TH "mtx-watch" "1" "01-01-2018" "version 1.00" "ConTeXt Request Watchdog"
.SH NAME
.B mtx-watch
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-youless.html b/doc/context/scripts/mkiv/mtx-youless.html
index d5678920b..a95170344 100644
--- a/doc/context/scripts/mkiv/mtx-youless.html
+++ b/doc/context/scripts/mkiv/mtx-youless.html
@@ -14,7 +14,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
- <title>YouLess Fetcher 1.00</title>
+ <title>YouLess Fetcher 1.100</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<style type="text/css">
body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } .invisible { visibility: hidden; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
@@ -24,7 +24,7 @@
</head>
<body>
<div id="top"> <div id="top-one">
- <div id="top-two">YouLess Fetcher 1.00 </div>
+ <div id="top-two">YouLess Fetcher 1.100 </div>
</div>
</div>
<div id="bottom"> <div id="bottom-one">
@@ -42,16 +42,18 @@
<tr><th>--collect</th><td></td><td>collect data from device</td></tr>
<tr><th>--nobackup</th><td></td><td>don't backup old datafile</td></tr>
<tr><th>--nofile</th><td></td><td>don't write data to file (for checking)</td></tr>
- <tr><th>--kwh</th><td></td><td>summative kwh data</td></tr>
- <tr><th>--watt</th><td></td><td>collected watt data</td></tr>
+ <tr><th>--electricity</th><td></td><td>collected eletricity data (p)</td></tr>
+ <tr><th>--gas</th><td></td><td>collected gas data</td></tr>
+ <tr><th>--pulse</th><td></td><td>collected eletricity data (s)</td></tr>
<tr><th>--host</th><td></td><td>ip address of device</td></tr>
- <tr><th>--auto</th><td></td><td>fetch kwh and watt data every hour</td></tr>
+ <tr><th>--auto</th><td></td><td>fetch (refresh) all data every hour</td></tr>
</table>
<br/>
<h1>Example</h1>
-<tt>mtxrun --script youless --collect --host=192.168.2.50 --kwh</tt>
-<br/><tt>mtxrun --script youless --collect --host=192.168.2.50 --watt somefile.lua</tt>
-<br/><tt>mtxrun --script youless --collect --host=192.168.2.50 --auto file-prefix</tt>
+<tt>mtxrun --script youless --collect --host=192.168.2.50 --electricity somefile.lua</tt>
+<br/><tt>mtxrun --script youless --collect --host=192.168.2.50 --gas somefile.lua</tt>
+<br/><tt>mtxrun --script youless --collect --host=192.168.2.50 --pulse somefile.lua</tt>
+<br/><tt>mtxrun --script youless --collect --host=192.168.2.50 --auto file-prefix</tt>
<br/><br/> </div>
</div>
</body>
diff --git a/doc/context/scripts/mkiv/mtx-youless.man b/doc/context/scripts/mkiv/mtx-youless.man
index 64a108402..043edd071 100644
--- a/doc/context/scripts/mkiv/mtx-youless.man
+++ b/doc/context/scripts/mkiv/mtx-youless.man
@@ -1,4 +1,4 @@
-.TH "mtx-youless" "1" "01-01-2017" "version 1.00" "youless Fetcher"
+.TH "mtx-youless" "1" "01-01-2018" "version 1.100" "youless Fetcher"
.SH NAME
.B mtx-youless
.SH SYNOPSIS
@@ -20,17 +20,20 @@ don't backup old datafile
.B --nofile
don't write data to file (for checking)
.TP
-.B --kwh
-summative kwh data
+.B --electricity
+collected eletricity data (p)
.TP
-.B --watt
-collected watt data
+.B --gas
+collected gas data
+.TP
+.B --pulse
+collected eletricity data (s)
.TP
.B --host
ip address of device
.TP
.B --auto
-fetch kwh and watt data every hour
+fetch (refresh) all data every hour
.SH AUTHOR
More information about ConTeXt and the tools that come with it can be found at:
diff --git a/doc/context/scripts/mkiv/mtx-youless.xml b/doc/context/scripts/mkiv/mtx-youless.xml
index 888c34934..e4482bb6b 100644
--- a/doc/context/scripts/mkiv/mtx-youless.xml
+++ b/doc/context/scripts/mkiv/mtx-youless.xml
@@ -3,7 +3,7 @@
<metadata>
<entry name="name">mtx-youless</entry>
<entry name="detail">youless Fetcher</entry>
- <entry name="version">1.00</entry>
+ <entry name="version">1.100</entry>
</metadata>
<flags>
<category name="basic">
@@ -11,10 +11,11 @@
<flag name="collect"><short>collect data from device</short></flag>
<flag name="nobackup"><short>don't backup old datafile</short></flag>
<flag name="nofile"><short>don't write data to file (for checking)</short></flag>
- <flag name="kwh"><short>summative kwh data</short></flag>
- <flag name="watt"><short>collected watt data</short></flag>
+ <flag name="electricity"><short>collected eletricity data (p)</short></flag>
+ <flag name="gas"><short>collected gas data</short></flag>
+ <flag name="pulse"><short>collected eletricity data (s)</short></flag>
<flag name="host"><short>ip address of device</short></flag>
- <flag name="auto"><short>fetch kwh and watt data every hour</short></flag>
+ <flag name="auto"><short>fetch (refresh) all data every hour</short></flag>
</subcategory>
</category>
</flags>
@@ -22,9 +23,10 @@
<category>
<title>Example</title>
<subcategory>
- <example><command>mtxrun --script youless --collect --host=192.168.2.50 --kwh</command></example>
- <example><command>mtxrun --script youless --collect --host=192.168.2.50 --watt somefile.lua</command></example>
- <example><command>mtxrun --script youless --collect --host=192.168.2.50 --auto file-prefix</command></example>
+ <example><command>mtxrun --script youless --collect --host=192.168.2.50 --electricity somefile.lua</command></example>
+ <example><command>mtxrun --script youless --collect --host=192.168.2.50 --gas somefile.lua</command></example>
+ <example><command>mtxrun --script youless --collect --host=192.168.2.50 --pulse somefile.lua</command></example>
+ <example><command>mtxrun --script youless --collect --host=192.168.2.50 --auto file-prefix</command></example>
</subcategory>
</category>
</examples>
diff --git a/doc/context/scripts/mkiv/mtxrun.man b/doc/context/scripts/mkiv/mtxrun.man
index b79d1603f..fdff5103c 100644
--- a/doc/context/scripts/mkiv/mtxrun.man
+++ b/doc/context/scripts/mkiv/mtxrun.man
@@ -1,4 +1,4 @@
-.TH "mtxrun" "1" "01-01-2017" "version 1.33" "ConTeXt TDS Runner Tool"
+.TH "mtxrun" "1" "01-01-2018" "version 1.33" "ConTeXt TDS Runner Tool"
.SH NAME
.B mtxrun
.SH SYNOPSIS
diff --git a/doc/context/sources/general/fonts/fonts/fonts-environment.tex b/doc/context/sources/general/fonts/fonts/fonts-environment.tex
index a8de89a42..c884d97e5 100644
--- a/doc/context/sources/general/fonts/fonts/fonts-environment.tex
+++ b/doc/context/sources/general/fonts/fonts/fonts-environment.tex
@@ -1,6 +1,46 @@
\startenvironment fonts-environment
- \blockligatures[fi,fl,ff] % we need to do this beforehand
+ % we need to do this beforehand
+
+ \blockligatures[fi,fl,ff]
+
+ \startbuffer[extraminus]
+ \startluacode
+ fonts.helpers.addextraprivate("smallminus", function(tfmdata)
+ local hchar = tfmdata.characters[0x002D]
+ local mchar = tfmdata.characters[0x2212]
+ if hchar and mchar then
+ return {
+ width = hchar.width,
+ height = mchar.height,
+ commands = {
+ { "down", hchar.height - mchar.height },
+ { "char", 0x002D },
+ }
+ }
+ end
+ end)
+ fonts.helpers.addextraprivate("highminus", function(tfmdata)
+ local hchar = tfmdata.characters[0x002D]
+ local mchar = tfmdata.characters[0x2212]
+ local xchar = tfmdata.characters[0x0058]
+ if hchar and mchar and xchar then
+ return {
+ width = hchar.width,
+ height = mchar.height,
+ commands = {
+ { "down", - xchar.height + mchar.height },
+ { "char", 0x002D },
+ }
+ }
+ end
+ end)
+ \stopluacode
+ \stopbuffer
+
+ \getbuffer[extraminus]
+
+ % so far for preloading
\environment manuals-explaining-environment
\environment manuals-explaining-cover
diff --git a/doc/context/sources/general/fonts/fonts/fonts-extensions.tex b/doc/context/sources/general/fonts/fonts/fonts-extensions.tex
index 1d84bfdc6..26b3d5f2d 100644
--- a/doc/context/sources/general/fonts/fonts/fonts-extensions.tex
+++ b/doc/context/sources/general/fonts/fonts/fonts-extensions.tex
@@ -2612,6 +2612,92 @@ gets defined and because we share resources it even has to happen before the
first font gets loaded. So, the \type {\blockligatures} commands go before
setting up the body font. This is no real problem because it's a hack anyway.
+The next example combines several tricks:
+
+\startbuffer[definitions]
+\startluacode
+ fonts.handlers.otf.addfeature {
+ name = "kernligatures",
+ type = "kern",
+ data = {
+ f = { i = 50, l = 50 },
+ }
+ }
+\stopluacode
+
+\blockligatures[u:fl:a]
+
+\definefontfeature[default:b][default][blockligatures=yes]
+\definefontfeature[default:k][default][blockligatures=yes,kernligatures=yes]
+
+\showfontkerns
+\stopbuffer
+
+\startbuffer[demo]
+{\definedfont[Brill*default @ 11pt]auflage}\par
+{\definedfont[Brill*default:b @ 11pt]auflage}\par
+{\definedfont[Brill*default:k @ 11pt]auflage}\par
+\stopbuffer
+
+\typebuffer[definitions,demo] \getbuffer[definitions]
+
+\startlinecorrection
+ \externalfigure[demo.buffer][width=4cm]
+\stoplinecorrection
+
+Processing fonts is complicated by the fact that a text can be hyphenated. This
+complicates for instance ligature building which can cross the pre, post and|/|or
+replace bounds. The current implementation does a decent job although there will
+always be border cases. And, figuring out what goes wrong is a pain. There are
+several ways to trace what happens and here's one. As mentioned, blocking only
+works when we haven't not yet defined a font instance, so we use a funny size
+here.
+
+\startbuffer
+\blockligatures[u:fl:a]
+
+\definefontfeature
+ [blockligatures]
+ [default]
+ [blockligatures=yes]
+
+\startotfcompositionlist{texgyrepagella-regular*blockligatures @ 14.5pt}{l2r}
+ \HL
+ \showotfcompositionsample{auflage}
+ \showotfcompositionsample{a\discretionary{-}{}{}uflage}
+ \showotfcompositionsample{au\discretionary{-}{}{}flage}
+ \showotfcompositionsample{auf\discretionary{-}{}{}lage}
+ \showotfcompositionsample{aufl\discretionary{-}{}{}age}
+ \showotfcompositionsample{aufla\discretionary{-}{}{}ge}
+ \showotfcompositionsample{auflag\discretionary{-}{}{}e}
+ \HL
+ \showotfcompositionsample{auflegt}
+ \showotfcompositionsample{a\discretionary{-}{}{}uflegt}
+ \showotfcompositionsample{au\discretionary{-}{}{}flegt}
+ \showotfcompositionsample{auf\discretionary{-}{}{}legt}
+ \showotfcompositionsample{aufl\discretionary{-}{}{}egt}
+ \showotfcompositionsample{aufle\discretionary{-}{}{}gt}
+ \showotfcompositionsample{aufleg\discretionary{-}{}{}t}
+ \HL
+\stopotfcompositionlist
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Here is another example. This one demonstrates that ligatures can force
+collapsing of discretionaries.
+
+\startbuffer
+\startotfcompositionlist{Serif*default @ 11pt}{l2r}
+ \HL
+ \showotfcompositionsample{effe}
+ \showotfcompositionsample{efficient}
+ \HL
+\stopotfcompositionlist
+\stopbuffer
+
+\typebuffer \getbuffer
+
\stopsection
\startsection[title=Collections]
diff --git a/doc/context/sources/general/fonts/fonts/fonts-features.tex b/doc/context/sources/general/fonts/fonts/fonts-features.tex
index f6a12c30d..d6d116856 100644
--- a/doc/context/sources/general/fonts/fonts/fonts-features.tex
+++ b/doc/context/sources/general/fonts/fonts/fonts-features.tex
@@ -1,4 +1,4 @@
-language=uk
+% language=uk
\startcomponent fonts-features
@@ -2626,6 +2626,86 @@ changes in a lifetime than foreseen when \TEX\ showed up.
\stopsection
+\startsection[title=Different spaces]
+
+The width of the space and its stretch and shrink are taken from the font. The so
+called emspace is the reference for much spacing related parameters. It is the
+width of character \type {0x2014}. The regular space width is taken from \type
+{0x0020}, the space character. When there is no space character, in the case of a
+monospaced font we take the emwidth, otherwise we take half the emwidth. As a
+last resort we can take the average width of characters. And of even that fails
+we take half of the font units. When there is no emwidth that one is set to the
+font units.
+
+In the \CONTEXT\ font loader we use a stretch that is 1/2 of the width of a space
+and the shrink is 1/3 the width of a space, so we use values that are quite
+similar to what \TEX\ always used.
+
+You can overload these values when a font is loaded and the overload is
+implemented as a feature. The next example demonstrates how this is done:
+
+\startbuffer
+\definefontfeature[morespace][spacing=0.50 plus 0.50 minus 0.250]
+\definefontfeature[lessspace][spacing=0.25 plus 0.25 minus 0.125]
+
+\definedfont[Serif*default] \samplefile{klein}\blank
+\definedfont[Serif*default,morespace]\samplefile{klein}\blank
+\definedfont[Serif*default,lessspace]\samplefile{klein}\blank
+\definedfont[Serif*default] \samplefile{klein}\blank
+\stopbuffer
+
+\typebuffer \blank \getbuffer \blank
+
+\stopsection
+
+\startsection[title=Dynamic features]
+
+We can enable and disable features any time in the input by using the
+\type {\feature} command. he following example was posted on the list:
+
+\startbuffer
+\definefont
+ [WeirdShapes]
+ [file:linlibertiner*default]
+
+\definefontfeature
+ [hist]
+ [hlig=yes]
+
+\definefontfeature
+ [rare]
+ [dlig=yes]
+
+\setupquotation
+ [style={\feature[+][hist,rare]}]
+
+\startlines
+\WeirdShapes
+strict {\feature[+][hist]strict}
+wurtzite {\feature[+][rare]wurtzite}
+\quotation{strict wurtzite}
+\stoplines
+\stopbuffer
+
+\typebuffer
+
+Or typeset:
+
+\getbuffer
+
+The \type {\feature} command takes as first argument a directive of what
+do do:
+
+\starttabulate[|T||]
+\NC + more \NC add set to previous set and combine with font set \NC \NR
+\NC - less \NC subtract set to previous set and combine with font set \NC \NR
+\NC = new \NC replace font set \NC \NR
+\NC ! < reset \NC forget sets and revert to font set \NC \NR
+\NC > old default \NC make sure the current set is used on top of the font set \NC \NR
+\stoptabulate
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/doc/context/sources/general/fonts/fonts/fonts-mkiv.tex b/doc/context/sources/general/fonts/fonts/fonts-mkiv.tex
index c5283ad41..6b05bb0c2 100644
--- a/doc/context/sources/general/fonts/fonts/fonts-mkiv.tex
+++ b/doc/context/sources/general/fonts/fonts/fonts-mkiv.tex
@@ -66,6 +66,7 @@
\component fonts-math
\component fonts-extensions
\component fonts-hooks
+ \component fonts-tricks
\stopbodymatter
\startappendices
diff --git a/doc/context/sources/general/fonts/fonts/fonts-tricks.tex b/doc/context/sources/general/fonts/fonts/fonts-tricks.tex
new file mode 100644
index 000000000..6596a43fb
--- /dev/null
+++ b/doc/context/sources/general/fonts/fonts/fonts-tricks.tex
@@ -0,0 +1,183 @@
+% language=uk
+
+\startcomponent fonts-tricks
+
+\environment fonts-environment
+
+\startchapter[title=Tricks][color=middleorange]
+
+\startsection[title=Introduction]
+
+In this chapter topics that don't fit in the previous chapters are
+collected.
+
+\stopsection
+
+\startsection[title=Extra characters]
+
+In one of our projects we need a small (high) minus and here we discuss
+one way of achieving this. An option is to define a new character
+and use a font feature to add it, as in:
+
+\starttyping
+\startluacode
+ local function addextraminus(tfmdata)
+ fonts.helpers.addprivate(tfmdata, "smallminus", ... ) -- see below
+ fonts.helpers.addprivate(tfmdata, "highminus", ... ) -- see below
+ end
+ fonts.constructors.newfeatures.otf.register {
+ name = "extraminus",
+ description = "extra minus symbols",
+ default = true,
+ manipulators = {
+ base = addextraminus,
+ node = addextraminus,
+ }
+ }
+\stopluacode
+\stoptyping
+
+However, why make it an option when we can just add it to any font. So,
+we can end up with just:
+
+\typebuffer[extraminus] % already defined before loading fonts
+
+It is important to do this before fonts get loaded. Next we need to decide how to
+access these characters. A straightforward way is:
+
+\startbuffer
+\def\smallminus{\privatechar{smallminus}}
+\def\highminus {\privatechar{highminus}}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+An alternative is:
+
+\starttyping
+\definemathcommand [smallminus] [ord] {\privatechar{smallminus}}
+\definemathcommand [highminus] [ord] {\privatechar{highminus}}
+\stoptyping
+
+but that fails in text mode. So, we can consider:
+
+\starttyping
+\def\smallminus{\mathortext{\mathord{\privatechar{smallminus}}}{\privatechar{smallminus}}}
+\def\highminus {\mathortext{\mathord{\privatechar {highminus}}}{\privatechar {highminus}}}
+\stoptyping
+
+or more compact
+
+\starttyping
+\def\smallminus{\mathortext\mathord\firstofoneargument{\privatechar{smallminus}}}
+\def\highminus {\mathortext\mathord\firstofoneargument{\privatechar {highminus}}}
+\stoptyping
+
+What method you choose depends on usage. With the first, simple definitions we
+get this:
+
+\startbuffer
+[\getprivateslot{smallminus}] [\getprivatechar{smallminus}] [\smallminus] $[\smallminus]$\par
+[\getprivateslot {highminus}] [\getprivatechar {highminus}] [\highminus ] $[\highminus ]$\par
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Because we are fully expandable we can even use this in:
+
+\startbuffer
+\bTABLE[aligncharacter=yes,alignmentcharacter={text->\smallminus}]
+ \bTR \bTD \mathminus100\smallminus00+ \eTD \eTR
+ \bTR \bTD 100\smallminus00 \eTD \eTR
+ \bTR \bTD \mathminus 99\smallminus00+ \eTD \eTR
+ \bTR \bTD \mathminus 99\smallminus00 \eTD \eTR
+ \bTR \bTD 100\highminus \eTD \eTR
+\eTABLE
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+With the other definitions the alignment would not work. If you need both then
+you can define different commands for text and math.
+
+\stopsection
+
+\startsection[title=Tabular numbers]
+
+Some font features are meant to be used in controlled situations. An example is
+the \type {tnum} feature that triggers so called \quote {tabular figures} meaning
+numbers that have equal widths. Its opposite feature is \type {lnum} or lining
+figures. We have two predefined \CONTEXT\ font features for this:
+
+\starttyping
+\definefontfeature [inlinenumbers] [lnum=yes,tnum=no]
+\definefontfeature [tabularnumbers] [tnum=yes,lnum=no]
+\stoptyping
+
+Some mechanisms in \CONTEXT\ had better be aware of this and one of them is the
+alignment mechanism in tables.
+
+\startbuffer[demo]
+\startcombination[before=,after=]
+ \startcontent
+ \switchtobodyfont[pagella]\showglyphs%
+ \disabledirectives[typesetters.characteralign.autofont]%
+ \bTABLE[alignmentcharacter=.,aligncharacter=yes]
+ \bTR \bTD 11.111 \eTD \eTR
+ \bTR \bTD 2.2 \eTD \eTR
+ \bTR \bTD 444.444 \eTD \eTR
+ \eTABLE
+ \enabledirectives[typesetters.characteralign.autofont]%
+ \stopcontent
+ \startcaption
+ \small manual \type {tnum}
+ \stopcaption
+ \startcontent
+ \switchtobodyfont[pagella]\showglyphs%
+ \bTABLE[alignmentcharacter=.,aligncharacter=yes]
+ \bTR \bTD 11.111 \eTD \eTR
+ \bTR \bTD 2.2 \eTD \eTR
+ \bTR \bTD 444.444 \eTD \eTR
+ \eTABLE
+ \stopcontent
+ \startcaption
+ \small auto \type {tnum}
+ \stopcaption
+\stopcombination
+\stopbuffer
+
+In the following examples we demonstrate how the automatic font adaption makes
+sure that tabular figures are used. The table is defined as:
+
+\typebuffer[demo]
+
+\startbuffer
+\dontleavehmode\hbox to .3\textwidth \bgroup
+ \hss\getbuffer[demo]\hss
+\egroup
+\stopbuffer
+
+In \in {figure}[fig:tabularnumbers] we see what the features do. We use the \type
+{\feature} or \type {\addfeature} macro for this. For the moment this trickery is
+controlled by a directive (beware: enabling them is global).
+
+\startplacefigure[reference=fig:tabularnumbers,title={Tabular numbers}]
+ \startcombination[nx=3,ny=2]
+ {\getbuffer} {\tt\nohyphens default}
+ {\addfeature [inlinenumbers]\getbuffer} {\tt\nohyphens inlinenumbers}
+ {\addfeature [tabularnumbers]\getbuffer} {\tt\nohyphens tabularnumbers}
+ {\addfeature[oldstylenumbers]\getbuffer} {\tt\nohyphens oldstylenumbers}
+ {\addfeature[oldstylenumbers]%
+ \addfeature [inlinenumbers]\getbuffer} {\tt\nohyphens oldstylenumbers\par inlinenumbers}
+ {\addfeature[oldstylenumbers]%
+ \addfeature [tabularnumbers]\getbuffer} {\tt\nohyphens oldstylenumbers\par tabularnumbers}
+ \stopcombination
+\stopplacefigure
+
+\stopsection
+
+\stopchapter
diff --git a/doc/context/sources/general/manuals/about/about-metafun.tex b/doc/context/sources/general/manuals/about/about-metafun.tex
index 8daff05a7..d289dd803 100644
--- a/doc/context/sources/general/manuals/about/about-metafun.tex
+++ b/doc/context/sources/general/manuals/about/about-metafun.tex
@@ -389,7 +389,7 @@ By using some \METAPOST\ magic we can even go a step further in readability:
Here we demonstrate that it also works well in \type {double} mode, which makes
much sense when processing data from other sources. Note how we omit the
-type {lua.} prefix: the \type {MP} macro will deal with that.
+type {lua} prefix: the \type {MP} macro will deal with that.
\startlinecorrection[blank]
\getbuffer
diff --git a/doc/context/sources/general/manuals/libraries/libraries-mkiv.tex b/doc/context/sources/general/manuals/libraries/libraries-mkiv.tex
new file mode 100644
index 000000000..67ca75966
--- /dev/null
+++ b/doc/context/sources/general/manuals/libraries/libraries-mkiv.tex
@@ -0,0 +1,199 @@
+% language=uk
+
+% author : Hans Hagen
+% copyright : PRAGMA ADE & ConTeXt Development Team
+% license : Creative Commons Attribution ShareAlike 4.0 International
+% reference : pragma-ade.nl | contextgarden.net | texlive (related) distributions
+% origin : the ConTeXt distribution
+%
+% comment : Because this manual is distributed with TeX distributions it comes with a rather
+% liberal license. We try to adapt these documents to upgrades in the (sub)systems
+% that they describe. Using parts of the content otherwise can therefore conflict
+% with existing functionality and we cannot be held responsible for that. Many of
+% the manuals contain characteristic graphics and personal notes or examples that
+% make no sense when used out-of-context.
+%
+% comment : Some chapters might have been published in TugBoat, the NTG Maps, the ConTeXt
+% Group journal or otherwise. Thanks to the editors for corrections. Also thanks
+% to users for testing, feedback and corrections.
+
+\usemodule[art-01,abr-02]
+
+\definecolor
+ [maincolor]
+ [r=.4]
+
+\definecolor
+ [extracolor]
+ [g=.4]
+
+\setupbodyfont
+ [11pt]
+
+\setuptype
+ [color=maincolor]
+
+\setuptyping
+ [color=maincolor]
+
+\definefontsynonym
+ [TitlePageMono]
+ [file:lmmonoproplt10-bold*default]
+
+\setuphead
+ [color=maincolor]
+
+\usesymbols
+ [cc]
+
+\setupinteraction
+ [hidden]
+
+\loadfontgoodies[lm]
+
+\startdocument
+ [metadata:author=Hans Hagen,
+ metadata:title=Libraries in ConTeXt,
+ author=Hans Hagen,
+ affiliation=PRAGMA ADE,
+ location=Hasselt NL,
+ title=Libraries in \ConTeXt,
+ support=www.contextgarden.net,
+ website=www.pragma-ade.nl]
+
+\startluasetups[swiglib]
+ context.nohyphens()
+ for i=1,640 do
+ context.definedfont { string.formatters["TitlePageMono at %p"](65536*(10+math.random(5))) }
+ context("Libraries ")
+ end
+ context.removeunwantedspaces()
+\stopluasetups
+
+\startMPpage
+
+StartPage ;
+
+ fill Page enlarged 1cm withcolor \MPcolor{extracolor} ;
+
+ draw textext("\framed[loffset=2pt,roffset=2pt,frame=off,width=\paperwidth,align={normal,paragraph,verytolerant,stretch}]{\luasetup{swiglib}}")
+ xysized (PaperWidth,PaperHeight)
+ shifted center Page
+ withcolor .8white ;
+
+ draw textext.ulft("\definedfont[TitlePageMono]basics")
+ xsized .75PaperWidth
+ shifted lrcorner Page
+ shifted (-1cm,2cm)
+ withcolor \MPcolor{maincolor} ;
+
+ % draw textext.ulft("\definedfont[TitlePageMono]in context mkiv")
+ % xsized .6PaperWidth
+ % shifted lrcorner Page
+ % shifted (-1cm,6cm)
+ % withcolor \MPcolor{maincolor} ;
+
+StopPage ;
+
+\stopMPpage
+
+\dontcomplain
+
+\startsubject[title=Contents]
+
+\placelist[section][alternative=a]
+
+\stopsubject
+
+\startsection[title=Introduction]
+
+Not long after we released \LUATEX\ 1.0, we started experimenting a bit more with
+so called foreign function interface: \FFI. Originally that interface to external
+libraries was only available in \LUAJITTEX, but a good and compatible alternative
+is now also available in the normal engine too. For users it is not that relevant
+to know how it works, as long as it works. It means that in addition to \SWIGLIB\
+we have a method that doesn't demand compilation as it uses normal (public)
+libraries.
+
+Of course one needs to make sure that the right version of a library is used.
+And, as there is the danger of the \API\ having been changed in an incompatible
+way one can wonder if such a dependency is really what one wants. On the other
+hand one can expect \CONTEXT\ to keep up.
+
+Do you really need libraries? For instance does it really make sense to use curl,
+ghostscript or graphicmagic libraries while the command line version is
+(normally) just as efficient and avoids a dependency. This is even more true if
+you realizes that for instance a fetch or conversion only needs to happen once
+per run or in fact only when there is some change in the resource.
+
+On the other hand, when accessing databases one can avoid the often slower
+command line calls and save the hassle of intermediate files. Here efficiency
+wins. Also, when \CONTEXT\ is used in a high performance database backend
+application a distribution and the used libraries are not updated on a daily
+basis.
+
+\stopsection
+
+\startsection[title=Supported]
+
+Apart from some experiments we currently can use \FFI\ interfaced libraries in:
+
+\starttabulate[|l|l|l|l|l|]
+\FL
+\BC module \BC library \BC windows \BC unix \NC \NR
+\ML
+\NC util-crl \NC curl \NC libcurl \NC libcurl \NC \NR % todo: client and ffi
+\NC util-sql-imp-ffi \NC mysql \NC libmysql \NC libmysqlclient \NC \NR
+\NC util-sql-imp-sqlite \NC sqlite \NC sqlite3 \NC sqlite3 \NC \NR
+%NC font-phb-imp-library \NC harfbuzz \NC libharfbuzz \NC libharfbuzz \NC \NR % for testing uniscribe (idris fonts)
+%NC \NC ghostscript \NC \NC \NC \NR % only a few experiments
+%NC \NC graphicmagick \NC \NC \NC \NR % only a few experiments
+\LL
+\stoptabulate
+
+The profiler that we occasionally use to identify bottlenecks in the engine (for
+instance when we upgrade \LUA) uses \FFI\ to provide access to the high resolution
+timers but this is typically different per platform.
+
+One problem with libraries, especially on \WINDOWS\ is that the library is found on
+some system path and it can happen that multiple programs ship the same library but in
+different versions. You can try to play safe and put libraries in the \TEX\ tree, for
+instance on my system they are in:
+
+\starttyping
+c:/data/tex-context/tex/texmf-win64/bin/lib/luatex/lua/whatever/libwhatever.dll
+\stoptyping
+
+You can trace where libraries are looked for with:
+
+\starttyping
+\enabletrackers[resolvers.ffilib]
+\stoptyping
+
+or in \LUA\ with:
+
+\starttyping
+trackers.enable("resolvers.ffilib")
+\stoptyping
+
+The library is first located on one of the valid \TDS\ paths (these are sort of
+standardized in \TEX\ distributions) and then using the normal \FFI\ loader.
+
+As this is all still experimental in \LUATEX\ there is not much more to say about
+it now. Of course this kind of specialized support to a large degree depends on
+the need to use it.
+
+\stopsection
+
+\startsection[title=Colofon]
+
+\starttabulate[|B|p|]
+\NC author \NC \getvariable{document}{author}, \getvariable{document}{affiliation}, \getvariable{document}{location} \NC \NR
+\NC version \NC \currentdate \NC \NR
+\NC website \NC \getvariable{document}{website} \endash\ \getvariable{document}{support} \NC \NR
+\NC comment \NC many thanks to Luigi Scarso for taking care of ffi support in the engines \NC \NR
+\stoptabulate
+
+\stopsection
+
+\stopdocument
diff --git a/doc/context/sources/general/manuals/luatex/luatex-enhancements.tex b/doc/context/sources/general/manuals/luatex/luatex-enhancements.tex
index 775d11999..d1da33878 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-enhancements.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-enhancements.tex
@@ -891,6 +891,20 @@ ignores the value.
This allows for embedded spaces, without the need for double quotes. Macro
expansion takes place inside the argument.
+The \type {\tracingfonts} primitive that has been inherited from \PDFTEX\ has
+been adapted to support variants in reporting the font. The reason for this
+extension is that a csname not always makes sense. The zero case is the default.
+
+\starttabulate[|T||]
+\NC 0 \EQ \type{\foo xyz} \NC \NR
+\NC 1 \EQ \type{\foo (bar)} \NC \NR
+\NC 2 \EQ \type{<bar> xyz} \NC \NR
+\NC 3 \EQ \type{<bar @ ..pt> xyz} \NC \NR
+\NC 4 \EQ \type{<id>} \NC \NR
+\NC 5 \EQ \type{<id: bar>} \NC \NR
+\NC 6 \EQ \type{<id: bar @ ..pt> xyz} \NC \NR
+\stoptabulate
+
\subsection{Writing to file}
You can now open upto 127 files with \type {\openout}. When no file is open
diff --git a/doc/context/sources/general/manuals/luatex/luatex-fonts.tex b/doc/context/sources/general/manuals/luatex/luatex-fonts.tex
index 6d7236483..ea176d197 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-fonts.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-fonts.tex
@@ -483,8 +483,8 @@ parameters to that command. The allowed commands and their arguments are:
\NC \type{right} \NC 1 \NC number \NC move right on the page \NC \NR
\NC \type{special} \NC 1 \NC string \NC output a \type {\special} command \NC \NR
\NC \type{pdf} \NC 2 \NC 2 strings \NC output a \PDF\ literal, the first string is one of \type {origin},
- \type {page}, \type {direct} or \type {raw}; if you have one string
- only \type {origin} is assumed \NC \NR
+ \type {page}, \type {text}, \type {font}, \type {direct} or \type {raw}; if you
+ have one string only \type {origin} is assumed \NC \NR
\NC \type{lua} \NC 1 \NC string \NC execute a \LUA\ script (at \type {\latelua} time) \NC \NR
\NC \type{image} \NC 1 \NC image \NC output an image (the argument can be either an \type
{<image>} variable or an \type {image_spec} table) \NC \NR
@@ -496,6 +496,27 @@ font id. This prevents the need for hackery with future id's (normally one could
use \type {font.nextid} but when more complex fonts are built in the meantime
other instances could have been loaded.
+The \type {pdf} option also accepts a \type {mode} keyword in which case the
+third argument sets the mode. That option will change the mode in an efficient
+way (passing an empty string would result in an extra empty lines in the \PDF\
+file. This option only makes sense for virtual fonts. The \type {font} mode only
+makes sense in virtual fonts.
+
+These modes are somewhat fuzzy and partially inherited from \PDFTEX.
+
+\starttabulate[|l|p|]
+\BC mode \BC description \NC \NR
+\NC \type {origin} \NC enter page mode and set the position \NC \NR
+\NC \type {page} \NC enter page mode \NC \NR
+\NC \type {text} \NC enter text mode \NC \NR
+\NC \type {font} \NC enter font mode (kind of text mode, only in virtual fonts) \NC \NR
+\NC \type {always} \NC finish the current string and force a transform if needed \NC \NR
+\NC \type {raw} \NC finish the current string \NC \NR
+\stoptabulate
+
+You always need to check what \PDF\ code is generated because there can be all kind of
+interferences with optimizations in the backend and fonts are complicated anyway.
+
Here is a rather elaborate glyph commands example:
\starttyping
diff --git a/doc/context/sources/general/manuals/luatex/luatex-nodes.tex b/doc/context/sources/general/manuals/luatex/luatex-nodes.tex
index 16488dbbb..ee60f6451 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-nodes.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-nodes.tex
@@ -758,11 +758,12 @@ The difference between \type {data} and \type {string} is that on assignment, th
Possible mode values are:
\starttabulate[|l|p|]
-\BC value \BC \PDFTEX\ keyword \NC \NR
-\NC 0 \NC \type{setorigin} \NC \NR
-\NC 1 \NC \type{page} \NC \NR
-\NC 2 \NC \type{direct} \NC \NR
-\NC 3 \NC \type{raw} \NC \NR
+\BC value \BC keyword \NC \NR
+\NC 0 \NC \type{origin} \NC \NR
+\NC 1 \NC \type{page} \NC \NR
+\NC 2 \NC \type{direct} \NC \NR
+\NC 3 \NC \type{raw} \NC \NR
+\NC 4 \NC \type{text} \NC \NR
\stoptabulate
The higher the number, the less checking and the more you can run into troubles.
diff --git a/doc/context/sources/general/manuals/math/math-alignments.tex b/doc/context/sources/general/manuals/math/math-alignments.tex
new file mode 100644
index 000000000..86fedb569
--- /dev/null
+++ b/doc/context/sources/general/manuals/math/math-alignments.tex
@@ -0,0 +1,253 @@
+\environment math-layout
+
+\startcomponent math-alignments
+
+\startchapter[title=Alignments and such]
+
+\startsection[title=Using ampersands]
+
+When you come from plain \TEX, using ampersands probably comes as a custom, like in:
+
+\startbuffer
+\startformula
+\bordermatrix {
+ a & b & c & d \cr
+ e & f & G & h \cr
+ i & j & k & l \cr
+}
+\stopformula
+\stopbuffer
+
+\typebuffer \getbuffer
+
+or:
+
+\startbuffer
+\startformula
+\bbordermatrix {
+ a & b & c & d \cr
+ e & f & G & h \cr
+ i & j & k & l \cr
+}
+\stopformula
+\stopbuffer
+
+\typebuffer \getbuffer
+
+A more \CONTEXT\ way is this:
+
+\startbuffer
+\startformula
+\startbordermatrix
+ \NC a \NC b \NC c \NC d \NR
+ \NC e \NC f \NC G \NC h \NR
+ \NC i \NC j \NC k \NC l \NR
+\stopbordermatrix
+\stopformula
+\stopbuffer
+
+\typebuffer \getbuffer
+
+and:
+
+\startbuffer
+\startformula
+\startbbordermatrix
+ \NC a \NC b \NC c \NC d \NR
+ \NC e \NC f \NC G \NC h \NR
+ \NC i \NC j \NC k \NC l \NR
+\stopbbordermatrix
+\stopformula
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Just that you know. In general ampersands in \CONTEXT\ text mode are just that:
+ampersands, not something alignment related.
+
+\stopsection
+
+\startsection[title=Locations]
+
+The \type {location} feature gives some control over the alignment of alignments.
+The following examples are taken from an email exchange with Henri Menke.
+
+\startbuffer
+\startplaceformula
+ \startformula
+ \startmathalignment[location=top]
+ \NC a + b \NC= c + d \NR
+ \NC a + b \NC= c + d \NR
+ \NC a + b \NC= c + d \NR
+ \stopmathalignment
+ \quad\text{or}\quad
+ \startmathalignment[location=center]
+ \NC a + b \NC= c + d \NR
+ \NC a + b \NC= c + d \NR
+ \NC a + b \NC= c + d \NR
+ \stopmathalignment
+ \quad\text{or}\quad
+ \startmathalignment[location=bottom]
+ \NC a + b \NC= c + d \NR
+ \NC a + b \NC= c + d \NR
+ \NC a + b \NC= c + d \NR
+ \stopmathalignment
+ \stopformula
+\stopplaceformula
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Numbering works ok for a single mathalignment
+
+\startbuffer
+\startplaceformula
+ \startformula
+ \startmathalignment[number=auto]
+ \NC a + b \NC= c + d \NR
+ \NC a + b \NC= c + d \NR
+ \NC a + b \NC= c + d \NR
+ \stopmathalignment
+ \stopformula
+\stopplaceformula
+\stopbuffer
+
+\typebuffer \getbuffer
+
+But for one with a location the results are suboptimal:
+
+\startbuffer
+\startplaceformula
+ \startformula
+ \startmathalignment[location=center,number=auto]
+ \NC a + b \NC= c + d \NR
+ \NC a + b \NC= c + d \NR
+ \NC a + b \NC= c + d \NR
+ \stopmathalignment
+ \stopformula
+\stopplaceformula
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Here is a real example:
+
+\startbuffer
+\startplaceformula
+ \startformula
+ U_2 = \frac{1}{2!}
+ \int_0^\beta \diff\tau_1 \int_0^\beta \diff\tau_2\;
+ \sum_{\startsubstack k_1,q_1 \NR k_2,q_2 \stopsubstack}
+ \Bigl\langle
+ \startmathalignment[location=top,align=left]
+ \NC
+ \mathcal T \Bigl[
+ c_{k_1}^\dagger (\tau_1)
+ \Delta_{k_1,q_1}^r c_{-k_1}^* (\tau_1) + c_{-q_1}^T (\tau_1)
+ \Delta_{k_1,q_1}^{r\dagger} c_{q_1} (\tau_1)
+ \Bigr]
+ \NR
+ \NC
+ \times \Bigl[
+ c_{k_2}^\dagger(\tau_2) \Delta_{k_2,q_2}^r c_{-k_2}^*
+ (\tau_2) + c_{-q_2}^T (\tau_2) \Delta_{k_2,q_2}^{r\dagger}
+ c_{q_2} (\tau_2)
+ \Bigr] \Bigr\rangle .
+ \NR
+ \stopmathalignment
+ \stopformula
+\stopplaceformula
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stopsection
+
+\startsection[title=Tuning alignments]
+
+Again a few examples of manipulating alignments. It really helps to play
+with examples if you want to get an idea what is possible.
+
+\startbuffer
+\startformula
+ \startalign[m=2,align={middle}]
+ \NC \text to 6cm{} \NC x = 0 \NR
+ \stopalign
+\stopformula
+
+\startformula
+ \startalign[m=2,align={middle}]
+ \NC \text to 6cm{One\hfill} \NC a = 1 \NR
+ \NC \text to 6cm{One Two\hfill} \NC b = 2 \NR
+ \NC \text to 6cm{One Two Three\hfill} \NC c = 3 \NR
+ \stopalign
+\stopformula
+
+\startformula
+ \startalign[m=2,align={left}]
+ \NC \text to 6cm{One\hfill} \NC a = 1 \NR
+ \NC \text to 6cm{One Two\hfill} \NC b = 2 \NR
+ \NC \text to 6cm{One Two Three\hfill} \NC c = 3 \NR
+ \stopalign
+\stopformula
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startformula
+ \startalign[m=2,align={middle}]
+ \NC \text to 6cm{} \NC x = 0 \NR
+ \stopalign
+\stopformula
+
+\startformula
+ \startalign[m=2,align={middle}]
+ \NC \text to 6cm{One} \NC a = 1 \NR
+ \NC \text to 6cm{One Two} \NC b = 2 \NR
+ \NC \text to 6cm{One Two Three} \NC c = 3 \NR
+ \stopalign
+\stopformula
+
+\startformula
+ \startalign[m=2,align={left}]
+ \NC \text to 6cm{One} \NC a = 1 \NR
+ \NC \text to 6cm{One Two} \NC b = 2 \NR
+ \NC \text to 6cm{One Two Three} \NC c = 3 \NR
+ \stopalign
+\stopformula
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startformula
+ \startalign[m=2,align={middle}]
+ \NC \text{} \NC x = 0 \NR
+ \stopalign
+\stopformula
+
+\startformula
+ \startalign[m=2,align={middle}]
+ \NC \text{One} \NC a = 1 \NR
+ \NC \text{One Two} \NC b = 2 \NR
+ \NC \text{One Two Three} \NC c = 3 \NR
+ \stopalign
+\stopformula
+
+\startformula
+ \startalign[m=2,align={left}]
+ \NC \text{One} \NC a = 1 \NR
+ \NC \text{One Two} \NC b = 2 \NR
+ \NC \text{One Two Three} \NC c = 3 \NR
+ \stopalign
+\stopformula
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/math/math-definitions.tex b/doc/context/sources/general/manuals/math/math-definitions.tex
new file mode 100644
index 000000000..d8903121a
--- /dev/null
+++ b/doc/context/sources/general/manuals/math/math-definitions.tex
@@ -0,0 +1,101 @@
+\environment math-layout
+
+\startcomponent math-definitions
+
+\startchapter[title=Definitions]
+
+\startsection[title=Special stackers]
+
+There are many math symbols but never enough. Here is an example of how you can
+roll out your own. We start out with nothing:
+
+\startbuffer
+\definemathstackers
+ [nosymbol]
+ [voffset=\zeropoint,
+ hoffset=\zeropoint,
+ mathclass=ord,
+ topoffset=\zeropoint,
+ middlecommand=,
+ color=maincolor]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+You can now use this class of stackers:
+
+\startbuffer
+\startformula
+ \mathover [nosymbol] {"2217} {A}
+ \mathover [nosymbol] {"2218} {A}
+ \mathover [nosymbol] {"2219} {A}
+\stopformula
+\stopbuffer
+
+\typebuffer
+
+This looks like this:
+
+\getbuffer
+
+But we want proper math, which means an an italic nucleus, a properly placed
+accent, a shift of that accent matching the slope or the nucleus, so we actually
+need:
+
+\startbuffer
+\definemathstackers
+ [mysymbol]
+ [voffset=-.30\mathexheight,
+ hoffset=\zeropoint,
+ mathclass=ord,
+ topoffset=.4\mathemwidth,
+ middlecommand=\mathematics,
+ color=maincolor]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startformula
+ \mathover [mysymbol]{"2217} {A}
+ \mathover [mysymbol]{"2218} {A}
+ \mathover [mysymbol]{"2219} {A}
+ \mathunder [mysymbol] {"2217}{A}
+ \mathunder [mysymbol] {"2218}{A}
+ \mathunder [mysymbol] {"2219}{A}
+ \mathdouble[mysymbol]{"2217}{"2217}{A}
+ \mathdouble[mysymbol]{"2218}{"2218}{A}
+ \mathdouble[mysymbol]{"2219}{"2219}{A}
+\stopformula
+\stopbuffer
+
+We show both over and under variants:
+
+\typebuffer
+
+So this time we get:
+
+\getbuffer
+
+We can now redefine the \quote {interiorset} symbol to use
+\type {0x2217} instead of \type {0x2218}:
+
+\startbuffer
+\definemathover[mysymbol][interiorset]["2217]
+
+\startformula
+ \interiorset{A}^{\interiorset{A}^{\interiorset{A}}}
+\stopformula
+\stopbuffer
+
+\typebuffer
+
+Of course normally you will not use color:
+
+\getbuffer
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/math/math-features.tex b/doc/context/sources/general/manuals/math/math-features.tex
index 3869c575e..863493804 100644
--- a/doc/context/sources/general/manuals/math/math-features.tex
+++ b/doc/context/sources/general/manuals/math/math-features.tex
@@ -122,6 +122,84 @@ show the plus sign.
\stopsection
+\startsection[title=Script kerning]
+
+Text in math is somewhat special. First of all, a math font is not a text fonts
+because the characters and glyphs have a different purpose. Text features are
+normally not present (and often not even wanted). Anyway, you can force a text
+font, but that doesn't mean you will get for instance kerning. You can force a
+box which in turn will trigger font processing, but then you normally loose the
+script related size properties. So we end up with some juggling possibly combined
+with user intervention, and that is what the \type {\text} macro does.
+
+But still there is the kern between a variable and its subscript to consider,
+something that normally is dealt with with staircase kerns, an \OPENTYPE\ math
+speciality. But, as we progress over the math list, and we bind a subscript to a
+variable, that subscript can be anything: a simple character, or more characters
+(a list) or something wrapped in a box. There is simply no universal solution
+that we can hard code because sometimes you don't want that special kerning. This
+is why in \LUATEX\ the integer variable \type {\mathscriptboxmode} controls the
+way this is dealt with.
+
+\starttabulate[|l|p|]
+\NC \type {0} \NC forget about kerning \NC \NR
+\NC \type {1} \NC kern math sub lists with a valid glyph (default in the engine) \NC \NR
+\NC \type {2} \NC also kern math sub boxes that have a valid glyph (default in \CONTEXT) \NC \NR
+\NC \type {3} \NC only kern math sub boxes with a boundary node present \NC \NR
+\stoptabulate
+
+Here we show some examples of how this parameter controls kerning. Watch the
+difference between a simple font switch and a text wrapped in a box. There are
+differences between fonts: some fonts have kerns, some don't. When present kerns
+are passed to the engine without further user intervention.
+
+\startbuffer[1]
+ $T_{\tf fluff}$
+\stopbuffer
+
+\startbuffer[2]
+ $T_{\text{fluff}}$
+\stopbuffer
+
+\startbuffer[3]
+ $T_{\text{\boundary1 fluff}}$
+\stopbuffer
+
+\unexpanded\def\Show#1#2#3%
+ {\doifelsenothing{#3}
+ {\typeinlinebuffer[#1]}
+ {\doifelse{#3}{-}
+ {\type{mode #2}}
+ {\switchtobodyfont[#3,big]\setstrut\strut\showfontkerns\showglyphs\mathscriptboxmode#2\relax\inlinebuffer[#1]}}}
+
+% \starttabulate[|lT|c|c|c|c|c|]
+% \NC \NC \Show{1}{0}{} \NC\Show{1}{1}{} \NC \Show{2}{1}{} \NC \Show{2}{2}{} \NC \Show{3}{3}{} \NC \NR
+% \NC \NC \Show{1}{0}{-} \NC\Show{1}{1}{-} \NC \Show{2}{1}{-} \NC \Show{2}{2}{-} \NC \Show{3}{3}{-} \NC \NR
+% \NC modern \NC \Show{1}{0}{modern} \NC\Show{1}{1}{modern} \NC \Show{2}{1}{modern} \NC \Show{2}{2}{modern} \NC \Show{3}{3}{modern} \NC \NR
+% \NC lucidaot \NC \Show{1}{0}{lucidaot} \NC\Show{1}{1}{lucidaot} \NC \Show{2}{1}{lucidaot} \NC \Show{2}{2}{lucidaot} \NC \Show{3}{3}{lucidaot} \NC \NR
+% \NC pagella \NC \Show{1}{0}{pagella} \NC\Show{1}{1}{pagella} \NC \Show{2}{1}{pagella} \NC \Show{2}{2}{pagella} \NC \Show{3}{3}{pagella} \NC \NR
+% \NC cambria \NC \Show{1}{0}{cambria} \NC\Show{1}{1}{cambria} \NC \Show{2}{1}{cambria} \NC \Show{2}{2}{cambria} \NC \Show{3}{3}{cambria} \NC \NR
+% \NC dejavu \NC \Show{1}{0}{dejavu} \NC\Show{1}{1}{dejavu} \NC \Show{2}{1}{dejavu} \NC \Show{2}{2}{dejavu} \NC \Show{3}{3}{dejavu} \NC \NR
+% \stoptabulate
+
+\def\ShowMore#1#2%
+ {\subsubject{\Show{#1}{#2}{} (\Show{#1}{#2}{-})}
+ \starttabulate[|lT|c|c|c|c|c|]
+ \NC modern \NC \Show{#1}{#2}{modern} \NC \NR
+ \NC lucidaot \NC \Show{#1}{#2}{lucidaot} \NC \NR
+ \NC pagella \NC \Show{#1}{#2}{pagella} \NC \NR
+ \NC cambria \NC \Show{#1}{#2}{cambria} \NC \NR
+ \NC dejavu \NC \Show{#1}{#2}{dejavu} \NC \NR
+ \stoptabulate}
+
+\ShowMore{1}{0}
+\ShowMore{1}{1}
+\ShowMore{2}{1}
+\ShowMore{2}{2}
+\ShowMore{3}{3}
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/doc/context/sources/general/manuals/math/math-input.tex b/doc/context/sources/general/manuals/math/math-input.tex
new file mode 100644
index 000000000..d395e1865
--- /dev/null
+++ b/doc/context/sources/general/manuals/math/math-input.tex
@@ -0,0 +1,100 @@
+% language=uk
+
+\environment math-layout
+
+\startcomponent math-input
+
+\startchapter[title=Inputting math]
+
+\startsection[title=Collapsing]
+
+When in text mode you enter a combination of combining accent and character, a
+composed character is assumed and often you then get one shape in your document.
+A similar feature is available in math mode. After some discussion and analysis
+of the potential clashes and confusion (thanks to Aditya Mahajan) we settled on a
+combination of methods: so called math lists entries that we entered in the
+character database and|/|or so called special sequences that are part of
+\UNICODE. In the next tables we use \type {ml} for math list and \type {sp} for
+specials. Collapsing mode \type {1} only uses the specials, while \type {2} first
+checks the specials and then the math lists, and \type {3} does the reverse.
+
+In the database you can find this (a few fields have been omitted):
+
+\starttyping
+[0x2260] = {
+ adobename = "notequal",
+ category = "sm",
+ description = "NOT EQUAL TO",
+ mathlist = { 0x2F, 0x3D },
+ mathspec = {
+ {
+ class = "relation",
+ name = "neq",
+ },
+ {
+ class = "relation",
+ name = "ne",
+ },
+ },
+ specials = { "char", 0x3D, 0x338 },
+ unicodeslot = 0x2260,
+}
+\stoptyping
+
+and
+
+\starttyping
+[0x2261] = {
+ adobename = "equivalence",
+ category = "sm",
+ description = "IDENTICAL TO",
+ mathclass = "relation",
+ mathextensible = "h",
+ mathname = "equiv",
+ mathlist = { 0x3D, 0x3D },
+ unicodeslot = 0x2261,
+}
+\stoptyping
+
+Here are a few examples:
+
+\def\Test#1%
+ {\NC \bf \type{$#1$}
+ \NC \setupmathematics[collapsing=0] $#1$
+ \NC \setupmathematics[collapsing=1] $#1$
+ \NC \setupmathematics[collapsing=2] $#1$
+ \NC \setupmathematics[collapsing=3] $#1$ \NC \NR}
+
+\starttabulate[|c|cp|cp|cp|cp|]
+ \NC \BC \ttbf 0 \BC \ttbf 1 (sp) \BC \ttbf 2 (sp ml) \BC \ttbf 3 (ml sp) \BC \NR
+ \Test{==}
+ \Test{/=}
+ \Test{>=}
+\stoptabulate
+
+A complete list of collapses can be generated after loading one of the tracing
+modules:
+
+\startbuffer
+\usemodule[math-ligatures]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This provides the command:
+
+\startbuffer
+\showmathligatures
+\stopbuffer
+
+\typebuffer
+
+which gives:
+
+\start \switchtobodyfont[8pt] \getbuffer \stop
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/math/math-introduction.tex b/doc/context/sources/general/manuals/math/math-introduction.tex
index c89d1d7b1..de7c0a960 100644
--- a/doc/context/sources/general/manuals/math/math-introduction.tex
+++ b/doc/context/sources/general/manuals/math/math-introduction.tex
@@ -7,7 +7,7 @@
This manual is not a systematic discussion about math in \CONTEXT\ but more a
collection of wrap|-|ups. The file also serves as testcase. The content can
change over time and can also serve as a trigger for discussions on the mailing
-list. Suggestions are welcome.
+list. Content gets added sort of random. Suggestions are welcome.
We discuss high level as well as low level commands. Some of the low level
commands (primitives) are wrapped in high level commands but you can of course
diff --git a/doc/context/sources/general/manuals/math/math-layout.tex b/doc/context/sources/general/manuals/math/math-layout.tex
index 5e84c996e..83137444d 100644
--- a/doc/context/sources/general/manuals/math/math-layout.tex
+++ b/doc/context/sources/general/manuals/math/math-layout.tex
@@ -39,21 +39,24 @@
height=middle,
width=middle]
+\definecolor[maincolor] [darkmagenta]
+\definecolor[extracolor][darkyellow]
+
\setuphead
[chapter]
[header=high,
style=\bfc,
- color=darkmagenta]
+ color=maincolor]
\setuphead
[section]
[style=\bfb,
- color=darkmagenta]
+ color=maincolor]
\setuphead
[subsection]
[style=\bfa,
- color=darkmagenta]
+ color=maincolor]
\usemodule[abr-02]
diff --git a/doc/context/sources/general/manuals/math/math-mkiv.tex b/doc/context/sources/general/manuals/math/math-mkiv.tex
index f36b1032d..93409fd79 100644
--- a/doc/context/sources/general/manuals/math/math-mkiv.tex
+++ b/doc/context/sources/general/manuals/math/math-mkiv.tex
@@ -31,11 +31,15 @@
\stopfrontmatter
\startbodymatter
+ \component math-input
+ \component math-definitions
\component math-spacing
\component math-framing
\component math-numbering
\component math-combining
\component math-features
+ \component math-alignments
+ \component math-suboptimal
\component math-tricks
\stopbodymatter
diff --git a/doc/context/sources/general/manuals/math/math-numbering.tex b/doc/context/sources/general/manuals/math/math-numbering.tex
index 64f766628..1576e17bb 100644
--- a/doc/context/sources/general/manuals/math/math-numbering.tex
+++ b/doc/context/sources/general/manuals/math/math-numbering.tex
@@ -69,6 +69,61 @@ are some examples:
\typebuffer \getbuffer
+In the next examples we demonstrate how we can avoid numbering, pass a reference as key,
+use assignments instead and add a title or suffix.
+
+\startbuffer
+\startplaceformula
+ \startformula e=mc^2 \stopformula
+\stopplaceformula
+\startplaceformula[-]
+ \startformula e=mc^2 \stopformula
+\stopplaceformula
+\startplaceformula[p]
+ \startformula e=mc^2 \stopformula
+\stopplaceformula
+\startplaceformula[reference=foo]
+ \startformula e=mc^2 \stopformula
+\stopplaceformula
+\startplaceformula[title=whatever]
+ \startformula e=mc^2 \stopformula
+\stopplaceformula
+\startplaceformula[suffix=q]
+ \startformula e=mc^2 \stopformula
+\stopplaceformula
+\startplaceformula[r]
+ \startformula e=mc^2 \stopformula
+\stopplaceformula
+\stopbuffer
+
+\typebuffer \getbuffer
+
+If you want consistent spacing you can enforce this:
+
+\startbuffer
+\startplaceformula[s]
+ \startformula e=mc^2 \stopformula
+\stopplaceformula
+\startplaceformula[-]
+ \startformula e=mc^2 \stopformula
+\stopplaceformula
+\startplaceformula[-]
+ \startformula e=mc^2 \stopformula
+\stopplaceformula
+\setupformulas[numberstrut=always]
+\startplaceformula[-]
+ \startformula e=mc^2 \stopformula
+\stopplaceformula
+\startplaceformula[-]
+ \startformula e=mc^2 \stopformula
+\stopplaceformula
+\stopbuffer
+
+\typebuffer \start \showstruts \getbuffer \stop
+
+Possible values for \type {numberstrut} are \type {yes} (the default), \type
+{always} and \type {no}.
+
\stopchapter
\stopcomponent
diff --git a/doc/context/sources/general/manuals/math/math-suboptimal.tex b/doc/context/sources/general/manuals/math/math-suboptimal.tex
new file mode 100644
index 000000000..f86539d55
--- /dev/null
+++ b/doc/context/sources/general/manuals/math/math-suboptimal.tex
@@ -0,0 +1,41 @@
+\environment math-layout
+
+\startcomponent math-subtoptimal
+
+\startchapter[title=Suboptimal]
+
+\startsection[title=Extensibles]
+
+Extensibles are implemented as follows: we start with the default shape, and when
+that doesn't cover the body of text, a next size is chosen. When we run out of
+sizes, a glyph is made from snippets (often a start glyph, overlapping middle
+pieces and an end piece. Of course a font needs to provide these variants and
+snippets.
+
+However, the quality of the coverage can differ per font. Here we show how Latin
+Modern, Pagella, Cambria, Lucida and Dejavu look like:
+
+\showglyphs
+
+\starttexdefinition ShowSample #1#2
+ \start
+ \switchtobodyfont [#1]
+ #2: \dorecurse{50}{$\vec{\blackrule[width=##1pt]}$\space}\unskip
+ \par
+ \stop
+\stoptexdefinition
+
+\ShowSample{modern} {Latin Modern} \blank
+\ShowSample{pagella} {Pagella} \blank
+\ShowSample{cambria} {Cambria} \blank
+\ShowSample{lucidaot}{Lucida} \blank
+\ShowSample{dejavu} {Dejavu}
+
+Of course fonts can be improved (or patched) and these samples might come out
+better compared to previous renderings.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/math/math-tricks.tex b/doc/context/sources/general/manuals/math/math-tricks.tex
index 5c0315f8d..7efcec50b 100644
--- a/doc/context/sources/general/manuals/math/math-tricks.tex
+++ b/doc/context/sources/general/manuals/math/math-tricks.tex
@@ -454,6 +454,156 @@ defined explicitly.
\stopsection
+\startsection[title=Middle class fences]
+
+The next examples are somewhat obscure. They are a side effect of some extensions
+to the engine that were introduced to control spacing around the \type {\middle}
+class fences. Actually there is no real middle class and spacing was somewhat
+hard codes when \type {\middle} was added to \ETEX. In \LUATEX\ we have
+introduced keywords to some primitives that control spacing and other properties.
+This permits better control over spacing than messing around with (for instance)
+injected \type {\mathrel} commands that can have their own side effects.
+
+\startbuffer
+\def\Middle{\middle|}
+\def\Riddle{\Umiddle class 5 |}
+\def\Left {\left (}
+\def\Right {\right )}
+\def\Rel {\mathrel{}}
+\def\Per {\mathrel{.}}
+\stopbuffer
+
+\startbuffer[1a]
+$ a b $
+\stopbuffer
+\startbuffer[1b]
+$ \Rel a\Rel b\Rel $
+\stopbuffer
+
+\startbuffer[2a]
+$ a b $
+\stopbuffer
+\startbuffer[2b]
+$ \Per a\Per b\Per $
+\stopbuffer
+
+\startbuffer[3a]
+$\Left a \Middle b \Right$
+\stopbuffer
+\startbuffer[3b]
+$\Left\Rel a \Middle\Rel b\Rel\Right$
+\stopbuffer
+
+\startbuffer[4a]
+$\Left a \Middle b \Right$
+\stopbuffer
+\startbuffer[4b]
+$\Left\Rel a \Middle\Per b\Per\Right$
+\stopbuffer
+
+\startbuffer[5a]
+$\Left a \Middle b \Right$
+\stopbuffer
+\startbuffer[5b]
+$\Left\Rel a\Rel\Middle\Rel b\Rel\Right$
+\stopbuffer
+
+\startbuffer[6a]
+$\Left a \Middle b \Right$
+\stopbuffer
+\startbuffer[6b]
+$\Left\Per a\Per\Middle\Per b\Per\Right$
+\stopbuffer
+
+\startbuffer[7a]
+$\Left a \Riddle b \Right$
+\stopbuffer
+\startbuffer[7b]
+$\Left\Rel a \Riddle\Rel b\Rel\Right$
+\stopbuffer
+
+\startbuffer[8a]
+$\Left a \Riddle b \Right$
+\stopbuffer
+\startbuffer[8b]
+$\Left\Rel a \Riddle\Per b\Per\Right$
+\stopbuffer
+
+\startbuffer[9a]
+$\Left a \Riddle b \Right$
+\stopbuffer
+\startbuffer[9b]
+$\Left\Rel a\Rel\Riddle\Rel b\Rel\Right$
+\stopbuffer
+
+\startbuffer[10a]
+$\Left a \Riddle b \Right$
+\stopbuffer
+\startbuffer[10b]
+$\Left\Per a\Per\Riddle\Per b\Per\Right$
+\stopbuffer
+
+We use the following definitions:
+
+\typebuffer
+
+Applied to samples these give the following outcome and spacing:
+
+\start
+ \getbuffer
+
+ \starttabulate
+ \NC \ruledhbox{\typeinlinebuffer[1a]} \NC \showglyphs \inlinebuffer[1a] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[1b]} \NC \showglyphs \inlinebuffer[1b] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[2a]} \NC \showglyphs \inlinebuffer[2a] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[2b]} \NC \showglyphs \inlinebuffer[2b] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[3a]} \NC \showglyphs \inlinebuffer[3a] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[3b]} \NC \showglyphs \inlinebuffer[3b] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[4a]} \NC \showglyphs \inlinebuffer[4a] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[4b]} \NC \showglyphs \inlinebuffer[4b] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[5a]} \NC \showglyphs \inlinebuffer[5a] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[5b]} \NC \showglyphs \inlinebuffer[5b] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[6a]} \NC \showglyphs \inlinebuffer[6a] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[6b]} \NC \showglyphs \inlinebuffer[6b] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[7a]} \NC \showglyphs \inlinebuffer[7a] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[7b]} \NC \showglyphs \inlinebuffer[7b] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[8a]} \NC \showglyphs \inlinebuffer[8a] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[8b]} \NC \showglyphs \inlinebuffer[8b] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[9a]} \NC \showglyphs \inlinebuffer[9a] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[9b]} \NC \showglyphs \inlinebuffer[9b] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[10a]} \NC \showglyphs \inlinebuffer[10a] \NC \NR
+ \NC \ruledhbox{\typeinlinebuffer[10b]} \NC \showglyphs \inlinebuffer[10b] \NC \NR
+ \stoptabulate
+\stop
+
+\stopsection
+
+\startsection[title=Auto|-|punctuation]
+
+\def\TestA#1#2#3%
+ {\ifnum#1=0 \type{#2}\else\setupmathematics[autopunctuation={#2}]$#3$\fi}
+
+\def\TestB#1#2%
+ {\NC \TestA{#1}{no} {#2}
+ \NC \TestA{#1}{yes} {#2}
+ \NC \TestA{#1}{yes,semicolon}{#2}
+ \NC \TestA{#1}{all} {#2}
+ \NC \TestA{#1}{all,semicolon}{#2}
+ \NC \NR}
+
+The \type {\setupmathematics} command has an option \type {autopunctuation} that
+influences the way spacing after punctuatuon is handled, especially in cases like
+the following (coordinates and such):
+
+\starttabulate[|c|c|c|c|c|]
+ \TestB{0}{}
+ \TestB{1}{(1,2)=(1, 2)}
+ \TestB{1}{(1.2)=(1. 2)}
+ \TestB{1}{(1;2)=(1; 2)}
+\stoptabulate
+
+\stopsection
+
\stopcomponent
% \enabletrackers[math.makeup=boxes]
diff --git a/doc/context/sources/general/manuals/metafun/cow-fun.mps b/doc/context/sources/general/manuals/metafun/cow-fun.mps
new file mode 100644
index 000000000..4235985ba
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/cow-fun.mps
@@ -0,0 +1,154 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%BoundingBox: 52 425 327 625
+%%Comment: originally a CorelDraw cow
+%%Creator: MetaPost
+%%Pages: 1
+%%EndProlog
+%%Page: 1 1
+0 2 dtransform truncate idtransform setlinewidth pop
+.625 0 0 setrgbcolor
+newpath 245.45 600.34 moveto
+242.78 599.40 239.62 596.02 237.67 594.07 curveto
+236.74 584.42 244.58 583.63 250.20 577.44 curveto
+258.77 573.70 251.21 567.72 256.18 557.42 curveto
+257.04 550.94 257.90 543.89 255.31 539.78 curveto
+249.48 538.92 247.97 540.22 246.89 531.43 curveto
+246.31 526.97 231.77 529.06 229.03 538.27 curveto
+227.09 544.97 221.33 546.70 217.80 543.17 curveto
+213.77 538.06 215.78 531.22 217.80 527.47 curveto
+224.93 517.32 212.04 511.42 205.13 516.74 curveto
+199.73 508.68 211.39 500.04 207.43 494.50 curveto
+205.78 493.99 204.77 489.17 185.47 500.54 curveto
+180.36 504.14 167.83 500.76 168.77 520.63 curveto
+168.77 525.82 165.60 543.53 162.14 555.91 curveto
+159.41 561.24 156.74 559.08 156.89 553.90 curveto
+157.18 547.85 162.94 531.22 155.52 540.22 curveto
+153.58 539.21 156.89 523.58 156.89 521.64 curveto
+162.00 517.03 157.39 513.58 154.73 512.28 curveto
+151.27 518.33 149.62 518.04 147.17 514.44 curveto
+141.70 514.08 144.58 528.19 140.26 528.62 curveto
+137.02 527.76 139.18 520.06 138.24 518.76 curveto
+132.98 524.74 130.90 529.27 127.01 521.64 curveto
+126.14 521.64 122.11 519.19 120.96 526.54 curveto
+117.65 552.74 107.06 558.36 93.82 565.13 curveto
+92.02 565.63 84.24 566.71 79.34 568.15 curveto
+73.51 560.88 58.32 565.63 56.23 570.31 curveto
+54.79 572.69 54.65 575.21 54.79 576.50 curveto
+52.34 580.10 55.87 582.70 59.62 583.06 curveto
+62.86 587.16 68.54 594.94 71.28 601.56 curveto
+72.29 603.07 74.95 609.34 78.19 609.55 curveto
+74.95 612.94 74.30 622.51 82.66 617.33 curveto
+87.12 624.02 92.09 624.31 95.76 615.82 curveto
+102.89 615.38 102.31 608.69 115.78 605.52 curveto
+122.76 602.86 132.77 604.58 140.26 603.72 curveto
+136.22 596.88 127.44 566.86 132.98 559.80 curveto
+140.76 564.70 141.84 605.38 157.03 595.66 curveto
+160.56 593.93 159.91 590.04 164.09 590.18 curveto
+170.42 587.45 169.13 600.77 172.51 600.77 curveto
+176.47 599.76 183.02 599.04 186.98 599.54 curveto
+197.71 600.77 206.93 604.08 223.92 602.50 curveto
+231.12 601.78 238.25 601.06 245.45 600.34 curveto
+closepath fill
+newpath 305.28 560.95 moveto
+304.63 560.95 299.95 561.24 299.38 561.24 curveto
+302.40 550.44 303.98 536.47 304.20 525.31 curveto
+303.70 521.35 299.81 517.46 299.38 525.67 curveto
+295.85 530.86 296.42 540.07 293.40 540.29 curveto
+287.35 539.64 285.34 513.22 280.01 509.33 curveto
+276.26 512.28 280.73 524.02 275.54 524.74 curveto
+270.50 524.02 264.31 526.68 266.69 534.46 curveto
+270.29 543.02 268.34 554.76 266.54 561.60 curveto
+262.37 578.59 264.02 587.09 271.58 596.09 curveto
+267.48 604.51 lineto
+275.40 608.26 285.62 604.58 290.02 602.21 curveto
+294.62 600.26 300.24 595.94 301.10 587.38 curveto
+303.34 578.88 304.42 569.74 305.28 560.95 curveto
+closepath fill
+.625 .625 0 setrgbcolor
+newpath 84.38 618.55 moveto
+88.34 624.38 92.59 622.94 96.34 615.67 curveto
+101.23 615.60 102.46 612.43 104.98 610.78 curveto
+122.62 598.39 147.46 607.18 167.90 601.92 curveto
+180.94 598.54 190.87 599.76 200.09 602.06 curveto
+220.32 607.25 246.10 596.16 263.74 603.86 curveto
+274.75 608.62 284.76 605.66 292.97 600.91 curveto
+297.58 597.96 299.59 596.09 300.96 591.26 curveto
+306.29 572.54 306.29 551.02 309.53 530.57 curveto
+309.53 528.84 312.19 526.10 312.48 522.07 curveto
+315.79 511.34 316.08 510.12 317.16 502.20 curveto
+317.16 501.34 326.52 488.45 325.01 479.02 curveto
+323.93 481.25 323.86 482.83 321.62 481.68 curveto
+320.33 479.30 320.90 473.90 322.56 471.74 curveto
+320.83 470.81 318.46 473.47 317.52 475.20 curveto
+318.17 473.04 317.81 470.81 316.73 469.30 curveto
+315.86 472.25 316.58 473.18 315.36 473.90 curveto
+313.99 472.90 314.21 469.30 314.28 466.20 curveto
+313.49 468.07 311.47 472.46 312.55 476.42 curveto
+312.48 484.20 308.81 489.10 310.32 499.10 curveto
+310.10 504.43 307.30 521.06 304.56 524.30 curveto
+303.12 526.25 306.36 510.77 306.36 506.16 curveto
+306.65 500.90 307.08 468.72 306.43 463.10 curveto
+306.43 459.22 306.22 453.96 307.08 452.16 curveto
+308.74 450.79 309.38 450.50 309.60 447.98 curveto
+309.24 446.62 308.74 446.04 307.73 445.54 curveto
+306.07 444.60 307.37 441.79 306.07 439.85 curveto
+304.49 438.77 304.13 441.86 303.34 441.86 curveto
+302.69 441.00 303.05 437.98 302.47 436.18 curveto
+299.66 433.80 292.18 432.50 289.15 434.66 curveto
+289.73 440.64 291.74 441.58 295.63 446.62 curveto
+298.66 452.59 297.00 460.94 296.93 468.14 curveto
+295.49 480.38 289.22 487.30 289.44 496.44 curveto
+287.86 495.72 286.42 494.57 284.26 494.86 curveto
+283.39 489.46 286.42 484.56 284.83 480.82 curveto
+281.95 471.96 277.06 446.62 279.00 437.76 curveto
+280.01 434.74 278.21 433.15 277.06 433.94 curveto
+276.77 433.94 276.55 433.94 276.41 433.94 curveto
+276.41 433.94 276.55 431.42 275.69 430.92 curveto
+274.10 430.34 273.67 431.71 272.66 432.14 curveto
+271.22 430.85 272.52 429.48 271.15 428.04 curveto
+267.19 428.04 261.36 425.38 257.98 428.26 curveto
+257.33 434.16 263.30 436.68 266.47 440.71 curveto
+268.63 446.62 271.08 462.89 267.77 474.62 curveto
+267.77 475.56 264.38 485.28 261.43 488.66 curveto
+258.70 487.66 257.33 485.50 253.22 486.29 curveto
+252.58 484.34 253.30 482.33 252.22 480.10 curveto
+251.86 479.52 249.34 478.58 249.19 481.39 curveto
+248.98 483.05 248.90 486.36 248.26 486.72 curveto
+243.65 486.72 233.71 487.08 231.77 493.92 curveto
+219.89 492.34 215.93 491.26 206.57 493.42 curveto
+196.63 489.67 183.24 506.16 174.53 502.20 curveto
+172.51 496.15 173.09 485.64 171.65 481.39 curveto
+169.34 474.77 171.14 467.14 171.14 456.41 curveto
+170.57 455.40 169.85 454.46 168.48 454.46 curveto
+168.48 453.10 169.34 450.86 168.62 449.42 curveto
+167.18 447.62 165.89 451.80 165.02 444.60 curveto
+163.15 443.74 157.75 442.22 155.59 445.18 curveto
+155.88 448.99 158.33 451.30 160.13 453.38 curveto
+161.42 456.91 160.99 458.28 160.70 461.81 curveto
+160.99 464.98 161.71 468.58 161.86 470.09 curveto
+161.86 473.04 162.50 479.30 161.14 481.18 curveto
+159.41 482.69 lineto
+157.18 487.22 158.33 494.64 157.61 500.26 curveto
+155.81 500.69 155.81 500.98 154.01 498.31 curveto
+154.01 494.42 153.50 486.36 152.35 483.84 curveto
+149.69 479.81 150.84 459.65 151.42 448.56 curveto
+151.78 446.47 149.69 447.70 149.76 444.74 curveto
+150.05 442.80 147.89 443.59 146.09 444.60 curveto
+145.15 445.18 146.59 439.78 145.37 439.56 curveto
+142.34 438.84 136.87 438.19 135.22 440.71 curveto
+134.57 444.60 137.88 448.06 140.62 451.01 curveto
+143.14 455.83 140.90 465.70 140.47 476.28 curveto
+138.89 478.22 lineto
+134.86 483.19 139.61 496.94 136.51 506.23 curveto
+120.02 514.87 122.11 519.19 118.73 537.62 curveto
+115.13 557.64 93.38 567.65 79.06 567.65 curveto
+73.44 563.04 66.24 563.62 58.54 567.65 curveto
+55.66 569.23 54.43 573.19 54.50 576.50 curveto
+52.63 580.75 55.22 582.19 59.62 583.49 curveto
+62.71 587.81 68.62 594.65 69.19 597.74 curveto
+70.34 601.92 75.53 608.11 77.76 609.77 curveto
+75.82 613.01 74.81 615.17 77.11 618.55 curveto
+79.56 620.14 81.79 616.61 84.38 618.55 curveto
+closepath stroke
+showpage
+%%EOF
diff --git a/doc/context/sources/general/manuals/metafun/hacker.png b/doc/context/sources/general/manuals/metafun/hacker.png
new file mode 100644
index 000000000..3a54696ee
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/hacker.png
Binary files differ
diff --git a/doc/context/sources/general/manuals/metafun/m-1.png b/doc/context/sources/general/manuals/metafun/m-1.png
new file mode 100644
index 000000000..ab020de9f
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/m-1.png
Binary files differ
diff --git a/doc/context/sources/general/manuals/metafun/m-2.png b/doc/context/sources/general/manuals/metafun/m-2.png
new file mode 100644
index 000000000..512d3eda0
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/m-2.png
Binary files differ
diff --git a/doc/context/sources/general/manuals/metafun/metafun-backgrounds.tex b/doc/context/sources/general/manuals/metafun/metafun-backgrounds.tex
new file mode 100644
index 000000000..200620cae
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-backgrounds.tex
@@ -0,0 +1,878 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-backgrounds
+
+\environment metafun-environment
+
+\startchapter[reference=sec:page,title={Page backgrounds}]
+
+\startintro
+
+Especially in interactive documents, adding backgrounds to the page and text
+areas not only enhances readability, but also makes it more convenient to
+identify header, footers and navigational areas. In this chapter we will
+demonstrate that with \METAPOST\ we can go beyond the \TEX\ based features
+present in \CONTEXT. One section is dedicated to graphics and printing,
+especially bleeding.
+
+\stopintro
+
+\startsection[title={The basic layout}]
+
+\index {layout}
+
+In the \CONTEXT\ manual you can find many details on the composition of the page.
+When \TEX\ typesets text, crossing the page boundary triggers \TEX's output
+routine. This routine is responsible for pasting the body text that goes onto a
+page in the correct area. A simple representation of such a page is:
+
+\startbuffer[a]
+\startuseMPgraphic{layout 1}
+ pickup pencircle scaled 1mm ;
+ fill unitsquare xyscaled (7cm,8cm)
+ withcolor .85white ;
+ fill unitsquare xyscaled (5cm,5cm) shifted (1cm,1.5cm)
+ withcolor .625yellow ;
+ fill unitsquare xyscaled (5cm,1cm) shifted (1cm,.5cm)
+ withcolor .625red ;
+ fill unitsquare xyscaled (5cm,1cm) shifted (1cm,6.5cm)
+ withcolor .625red ;
+ draw unitsquare xyscaled (5cm,7cm) shifted (1cm,.5cm)
+ withcolor .25white ;
+ drawarrow (2cm,8cm) -- top (2cm,7.5cm) ;
+ drawarrow (0cm,7cm) -- lft (1cm,7cm) ;
+ clip currentpicture to unitsquare xyscaled (7cm,8cm) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[b]
+\startuseMPgraphic{layout 2}
+ \includeMPgraphic{layout 1}
+ clip currentpicture to unitsquare scaled 3cm shifted (0,5cm) ;
+ currentpicture := currentpicture scaled 2 shifted (0,-8cm) ;
+ setbounds currentpicture to unitsquare xyscaled (6cm,8cm) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer[a,b]
+
+\startbuffer[c]
+\startlinecorrection[blank]
+\hbox
+ {\useMPgraphic{layout 1}\hskip1cm
+ \useMPgraphic{layout 2}}
+\stoplinecorrection
+\stopbuffer
+
+\getbuffer[c]
+
+The red areas are the header and footer, while the yellow areas contains the text
+flow. We can turn headers on and off and|/|or hide them. For this reason, the
+header, text and footer areas together make up the height of the text.
+
+A close look at the left picture will reveal that the two arrows point to the
+center of the lines. This is achieved by the \type {top} and \type {lft}
+directives. If we would not have clipped the picture, the arrow would have stuck
+half a line width outside the gray area that represents the page. When
+constructing such pictures, one should really pay attention to such details,
+since it pays off in the overall look and feel of the document.
+
+The vertical arrow represents the top space, while the horizontal arrow denotes
+the distance to the back of the cover (back space). By changing their values, you
+can shift the main body text on the page. In a double sided layout scheme, the
+back space is automatically mirrored on even pages.
+
+An advanced \METAPOST\ user may wonder why we hard code the dimensions, and avoid
+\METAPOST's powerful mechanisms for defining relations. Our experience has taught
+us that in pictures like this, providing a general solution seldom pays large
+dividents or savings in time.
+
+\typebuffer[a]
+
+As you can see, the left graphic is defined as a series of rectangles. The \type
+{xyscaled} macro is part of the \CONTEXT\ files, and saves some typing and space.
+It is defined as a primary, requiring both left and right operands.
+
+\starttyping
+primarydef p xyscaled q =
+ p xscaled (xpart q) yscaled (ypart q)
+enddef ;
+\stoptyping
+
+Zooming in on the top left corner only takes a few lines. First we clip the
+correct part, next we scale it up, and finally we let the bounding box suit the
+left picture.
+
+\typebuffer[b]
+
+This code demonstrates how you can reuse a graphic inside another one. This
+strategy can easily be used to stepwise build (or extend) graphics. The two
+graphics were put side by side with the following command. Watch the use of line
+correction commands. They optimize the white space around the graphic.
+
+\typebuffer[c]
+
+As soon as you want to make an electronic document, you will want to use
+different areas of the screen for different purposes: text, menus, buttons, etc.
+For this reason, \CONTEXT\ provides not only left and right margins, but also
+additional left and right edge areas and top and bottom margins. These areas are
+shown in the figure on the next page.
+
+\startbuffer[aa]
+pickup pencircle scaled 2pt ;
+
+numeric w[], h[], x[], y[], u ; u := .5cm ;
+
+numeric width ; width := \the\textwidth ;
+numeric height ; height := \the\textheight ;
+\stopbuffer
+
+\startbuffer[bb]
+w[1] = 2u ; w[2] = 3u ; w[4] = 3u ; w[5] = 2u ;
+h[1] = 1u ; h[2] = 1u ; h[4] = 1u ; h[5] = 1u ;
+
+w[1]+w[2]+w[3]+w[4]+w[5]+4u = width ;
+h[1]+h[2]+h[3]+h[4]+h[5]+4u = height ;
+
+x[1] = 1u ; y[1] = 1u ;
+x[2] = x[1] + w[1] + .5u ; y[2] = y[1] + h[1] + .5u ;
+x[3] = x[2] + w[2] + .5u ; y[3] = y[2] + h[2] + .5u ;
+x[4] = x[3] + w[3] + .5u ; y[4] = y[3] + h[3] + .5u ;
+x[5] = x[4] + w[4] + .5u ; y[5] = y[4] + h[4] + .5u ;
+\stopbuffer
+
+\startbuffer[cc]
+def do_it (expr xx, yy, cc) =
+ draw unitsquare
+ xyscaled (w[xx],h[yy]) shifted (x[xx],y[yy])
+ withcolor if cc : .625red else : .625yellow fi ;
+enddef ;
+
+fill unitsquare xyscaled (width,height) withcolor .85white;
+
+do_it (1,1,false) ; do_it (5,1,false) ;
+do_it (2,1,false) ; do_it (3,1,false) ; do_it (4,1,false) ;
+
+do_it (1,2,false) ; do_it (5,2,false) ;
+do_it (2,2,true ) ; do_it (3,2,true ) ; do_it (4,2,true ) ;
+
+do_it (1,3,false) ; do_it (5,3,false) ;
+do_it (2,3,true ) ; do_it (3,3,true ) ; do_it (4,3,true ) ;
+
+do_it (1,4,false) ; do_it (5,4,false) ;
+do_it (2,4,true ) ; do_it (3,4,true ) ; do_it (4,4,true ) ;
+
+do_it (1,5,false) ; do_it (5,5,false) ;
+do_it (2,5,false) ; do_it (3,5,false) ; do_it (4,5,false) ;
+\stopbuffer
+
+\startbuffer[dd]
+def do_it (expr yy, tt) =
+ path p ;
+ p := unitsquare xyscaled (w[1],h[yy]) shifted (x[1],y[yy]) ;
+ label.lft(tt, center p shifted (-w[1]/2-u-.25cm,0)) ;
+enddef ;
+
+do_it (1,btex bottom etex) ;
+do_it (2,btex footer etex) ;
+do_it (3,btex text etex) ;
+do_it (4,btex header etex) ;
+do_it (5,btex top etex) ;
+\stopbuffer
+
+\startbuffer[ee]
+def do_it (expr xx, tt) =
+ path p ;
+ p := unitsquare xyscaled (w[xx],h[1]) shifted (x[xx],y[1]) ;
+ label(tt, center p shifted (0,height-h[1]/2)) ;
+enddef ;
+
+do_it (1,btex edge etex) ;
+do_it (2,btex margin etex) ;
+do_it (3,btex text etex) ;
+do_it (4,btex margin etex) ;
+do_it (5,btex edge etex) ;
+\stopbuffer
+
+\startbuffer[ff]
+setbounds currentpicture to
+ unitsquare xyscaled (width,height) ;
+\stopbuffer
+
+% We use two chars for buffer names, otherwise we can get
+% get in conflict with the next buffers with similar names.
+
+\startpostponing
+\centerbox{\processMPbuffer[aa,bb,cc,dd,ee,ff]}
+\stoppostponing
+
+When defining this graphic, all areas have related dimensions. Here it makes
+sense to let \METAPOST\ calculate these dimensions as much as possible. First we
+define the five by five matrix of areas. We pass the width and height of the main
+text area. Because they are stored in \TEX\ dimension registers, we have to
+prefix them by \type {\the}.
+
+\typebuffer[aa]
+
+We now specify the lower left corners using \type {=} instead of the \type {:=},
+which means that \METAPOST\ will calculate \type {w[3]} and \type {h[3]} for us.
+
+\typebuffer[bb]
+
+Because we are going to repeat ourselves, we draw the areas using a macro.
+Depending on its importance, we color it red or yellow.
+
+\typebuffer[cc]
+
+This picture in itself is not yet explanatory, so we add some labels. Again, we
+use a macro, which we feed with a picture generated by \TEX. Since these pictures
+are filtered from the source and pre||processed, we cannot embed the \type
+{btex}||\type {etex} in the macro \type {do_it} and pass a string. It has to be
+done this way. \footnote {This is true only in a regular \METAPOST\ run. In
+\CONTEXT\ \MKIV\ we follow a different route.}
+
+\typebuffer[dd]
+
+In the horizontal direction we have edges, margins and text. There are left and
+right edges and margins, which are swapped on even pages when you typeset a
+double sided document.
+
+\typebuffer[ee]
+
+Since we want the graphic to match the dimensions of the text area of the current
+page, we have to make sure that the bounding box is adapted accordingly. By this
+action, the labels will fall outside the bounding box. When we directly embed a
+graphic, this works ok, but when we start scaling and reusing, due to the object
+reuse mechanism the graphic will be clipped to the bounding box.
+
+\typebuffer[ff]
+
+In the following sections we will demonstrate how you can put graphics behind
+these 25~areas, as well as behind the (left and right) page.
+
+\stopsection
+
+\startsection[title={Setting up backgrounds}]
+
+\index {overlays}
+\index {backgrounds}
+
+One way of protecting a document for unwanted usage is to put an annoying word in
+the background. If you like this, you may try the following. The macro \type
+{ysized} is part of the macros that come with \CONTEXT\ and scales a picture to a
+specific size.
+
+\startbuffer[a]
+\startuniqueMPgraphic{concept}
+ draw btex \colored[s=.8]{\bf CONCEPT} etex rotated 60 ;
+ currentpicture := currentpicture
+ ysized (\overlayheight-.5cm) ;
+\stopuniqueMPgraphic
+
+\defineoverlay[concept][\uniqueMPgraphic{concept}]
+\stopbuffer
+
+\typebuffer[a]
+
+You can now put this graphic in the page background by
+saying:
+
+\starttyping
+\setupbackgrounds[page][background=concept]
+\stoptyping
+
+You may consider the next alternative a bit better, but still it renders the text
+unreadable. Like \type {xysized}, the macro \type {enlarged} is not part of
+standard \METAPOST, but comes with \CONTEXT.
+
+\startbuffer[b]
+\startuniqueMPgraphic{copyright}
+ picture p ; p := btex \colored[s=.8]{COPYRIGHT} etex
+ rotated 90 ;
+ setbounds p to boundingbox p enlarged 1pt ;
+ draw p ;
+ currentpicture := currentpicture
+ xysized (\overlaywidth,\overlayheight) ;
+\stopuniqueMPgraphic
+
+\defineoverlay[copyright][\uniqueMPgraphic{copyright}]
+\stopbuffer
+
+\typebuffer[b]
+
+Again, we put this graphic in the background. By using a unique graphic, we make
+sure that it's rendered only once and reused when possible.
+
+\startbuffer[c]
+\setupbackgrounds[text][rightmargin][background=copyright]
+\stopbuffer
+
+\typebuffer[c]
+
+\doifnotmode{screen}{\getbuffer[b,c]}
+
+In both cases, we slightly scale down the graphic. We do so because otherwise a
+small portion of the text is clipped off. This is unrelated to \TEX\ or
+\METAPOST, but a characteristic of the font. Compare the following Pagella, Latin
+Modern and Termes gi's (the Pagella is the body font of this text).
+
+\startbuffer
+\hbox \bgroup
+ \hbox{\definedfont[file:texgyrepagella-regular at 6cm]gi}%
+ \hbox{\definedfont[file:lmroman10-regular at 6cm]gi}%
+ \hbox{\definedfont[file:texgyretermes-regular at 6cm]gi}%
+\egroup
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+{\showboxes \getbuffer}
+\stoplinecorrection
+
+Watch how the bounding boxes differ and sometimes cross the shape. So, in order
+not to loose part of a glyph when clipping, you need to add a bit of space. \in
+{Figure} [fig:annoying] shows the two backgrounds in action.
+
+\startbuffer
+\getbuffer[a,b]
+\def\ShowPage#1% % (yet) no image as background to image
+ {\framed % possible due to nested file problems
+ [background=#1,offset=overlay]
+ {\typesetfile[mfun-900.tex][page=1,width=.4\textwidth]}}
+\startcombination
+ {\ShowPage{concept}} {concept}
+ {\ShowPage{copyright}} {copyright}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:annoying]
+ {Two examples of annoying backgrounds.}
+ {\getbuffer}
+
+If you really want to add such texts to a document, in \CONTEXT\ we don't have to
+use the page background, but can use one of the layout areas instead (like \type
+{[text][text]} or \type {[text][leftmargin]})
+
+\typebuffer[d]
+
+There is one drawback: when your left and right margin have different dimensions,
+the text will be scaled differently on odd and even pages. Normally this is no
+problem for a draft.
+
+As an alternative you can use the \type {\setuptexts} command and wrap the
+graphic in a box with the right dimensions, using code like:
+
+\starttyping
+\startuniqueMPgraphic{copyright}
+ picture p ; p := btex COPYRIGHT etex rotated 90 ;
+ setbounds p to boundingbox p enlarged 1pt ;
+ draw p withcolor .8white ;
+ xyscale_currentpicture(\the\leftmarginwidth,\the\textheight) ;
+\stopuniqueMPgraphic
+
+\setuptexttexts [margin] [] [\uniqueMPgraphic{copyright}]
+\stoptyping
+
+The graphic goes into the outer margin. The second argument can be used to put
+something in the inner margin.
+
+\stopsection
+
+\startsection[title={Multiple overlays}]
+
+\index{overlays+stack}
+
+\setupbackgrounds[text][rightmargin][background=]
+
+You can stack overlays. Consider the next case, where we assume that you have
+enabled interaction support using \type {\setupinteraction[state=start]}:
+
+\starttyping
+\setupbackgrounds
+ [page]
+ [background={color,nextpage},
+ backgroundcolor=darkyellow]
+\stoptyping
+
+Here, the page gets a colored background and a hyperlink to the next page,
+previously defined by:
+
+\starttyping
+\defineoverlay[nextpage][\overlaybutton{nextpage}]
+\stoptyping
+
+An \type {\overlaybutton} is just a button, with all attributes (color, frame,
+etc) set to nothing, having the dimensions of the overlay. The argument is one of
+the permitted destinations, like \type {nextpage}, \type {firstpage}, \type
+{SearchDocument} and alike.
+
+For efficiency reasons, the background areas (like \type {[text][text]}) are
+calculated only when their definition has changed. When a background changes per
+page, we have to recalculate it on each page. In the next example, the macro
+\type {\overlaybutton} generates a different button on each page. But, since we
+don't explicitly set the background at each page, there is no way the background
+drawing mechanism can know that this button has changed. Therefore, we must force
+recalculation with:
+
+\starttyping
+\setupbackgrounds[state=repeat]
+\stoptyping
+
+You can test this concept yourself with the following code. Here we assume that
+you have a file called \type {tufte.tex} on your system, which is the case if you
+have \CONTEXT\ installed. However, you can just as easily use any file having a
+paragraph of two of text.
+
+\starttyping
+\starttext
+\setupinteraction[state=start]
+\setupbackgrounds[state=repeat]
+\defineoverlay[nextpage][\overlaybutton{nextpage}]
+\setupbackgrounds[text][text][background=nextpage]
+\dorecurse{20}{\input tufte \par}
+\stoptext
+\stoptyping
+
+Note that you can move forward from page to page in the resulting \PDF\ file by
+clicking on each page with the mouse. Now compile this file without setting the
+background state to \type {repeat} and note the difference as you click pages
+with the mouse.
+
+Setting the state was not needed when we used the page background:
+
+\starttyping
+\setupbackgrounds[page][background=nextpage]
+\stoptyping
+
+The \type {\dorecurse} macro is handy for testing since it saves us typing. One
+can nest this macro as in:
+
+\starttyping
+\dorecurse{20}{\dorecurse{10}{Hello World! }\par}
+\stoptyping
+
+The current step is available in \type {\recurselevel} and the depth (nesting
+level) in \type {\recursedepth}.
+
+\stopsection
+
+\startsection[title={Crossing borders}]
+
+\index{backgrounds}
+
+In many cases, the previously mentioned background areas will suffice, but in the
+case of more complicated backgrounds, you may wish to use \METAPOST\ to draw
+graphics that combine or span these areas.
+
+At runtime \CONTEXT\ saves information on the layout that can be picked up by
+\METAPOST. The framework for a page graphic is:
+
+\starttyping
+StartPage;
+ % all kind of commands
+StopPage ;
+\stoptyping
+
+Between the \type {StartPage} and \type {StopPage} command you have access to a
+wide range of variables:
+
+\starttabulate[|l|Tp|]
+\HL
+\NC page \NC PaperHeight PaperWidth \NC \NR
+\NC \NC PrintPaperHeight PrintPaperWidth \NC \NR
+\NC \NC PageOffset PageDepth \NC \NR
+\NC margins \NC TopSpace BackSpace \NC \NR
+\NC text \NC MakeupHeight MakeupWidth \NC \NR
+\NC vertical \NC TopHeight TopDistance \NC \NR
+\NC \NC HeaderHeight HeaderDistance \NC \NR
+\NC \NC TextHeight \NC \NR
+\NC \NC FooterDistance FooterHeight \NC \NR
+\NC \NC BottomDistance BottomHeight \NC \NR
+\NC horizontal \NC LeftEdgeWidth LeftEdgeDistance \NC \NR
+\NC \NC LeftMarginWidth LeftMarginDistance \NC \NR
+\NC \NC TextWidth \NC \NR
+\NC \NC RightMarginDistance RightMarginWidth \NC \NR
+\NC \NC RightEdgeDistance RightEdgeWidth \NC \NR
+\HL
+\stoptabulate
+
+Since using these variables to construct paths is not that handy because the
+areas are available as predefined paths, which we will demonstrate here.
+
+\placefigure
+ [here][fig:back 1]
+ {A background with combined areas.}
+ {\startcombination
+ {\typesetfile[mfun-900.tex][page=2,width=.4\textwidth]}{even}
+ {\typesetfile[mfun-900.tex][page=3,width=.4\textwidth]}{odd}
+ \stopcombination}
+
+In \in {figure} [fig:back 1] you see two pages (odd and even) with a background
+spanning the outer margin and the text area. You can access an area in two ways.
+The area itself is available as \type {Area}.
+
+\starttyping
+StartPage ;
+ fill Area[Text][Text] withcolor .85white ;
+StopPage ;
+\stoptyping
+
+If you use an area this way, you will notice that it is not positioned at the
+right place. An \type {Area} is just a rectangle. If you want a positioned area,
+you should use the \type {Field} array:
+
+\starttyping
+StartPage ;
+ fill Field[Text][Text] withcolor .85white ;
+StopPage ;
+\stoptyping
+
+The location of an area is available in \type {Location}, so the previous
+definition is the same as:
+
+\starttyping
+StartPage ;
+ fill Area[Text][Text] shifted Location[Text][Text]
+ withcolor .85white ;
+StopPage ;
+\stoptyping
+
+The following definition fills and draws the margin and text areas.
+
+\typebuffer[back-2]
+
+This background is assigned to the page layer by saying:
+
+\typebuffer[back-0]
+
+As you can see in \in {figure} [fig:back 2], the text is typeset rather tightly
+between the left and right margins.
+
+\placefigure
+ [here][fig:back 2]
+ {A background with split areas.}
+ {\startcombination
+ {\typesetfile[mfun-900.tex][page=4,width=.4\textwidth]}{even}
+ {\typesetfile[mfun-900.tex][page=5,width=.4\textwidth]}{odd}
+ \stopcombination}
+
+This can easily be solved by enlarging the areas a bit. The next example
+demonstrates this on the text area, which is shown in \in {figure} [fig:back 3].
+
+\typebuffer[back-3]
+
+\placefigure
+ [here][fig:back 3]
+ {A background with enlarged text area.}
+ {\startcombination
+ {\typesetfile[mfun-900.tex][page=6,width=.4\textwidth]}{even}
+ {\typesetfile[mfun-900.tex][page=7,width=.4\textwidth]}{odd}
+ \stopcombination}
+
+The \type {enlarged} macro can be used like \type {shifted} and accepts either a
+numeric or a pair.
+
+How do we define a background as in \in {figure} [fig:back 1]? Because \type
+{Field} provides us the positioned areas, we can use the corners of those.
+
+\typebuffer[back-1]
+
+In this definition we calculate a different path for odd and even pages. When
+done, we enlarge the path a bit. If you want to use different offsets in all
+directions, you can use moved corner points.
+
+\typebuffer[back-4]
+
+Here we displace the corners randomly which leads to backgrounds like \in
+{figure} [fig:back 4]. The following definition would have worked as well:
+
+\typebuffer[back-4x]
+
+\placefigure
+ [here][fig:back 4]
+ {A random text area.}
+ {\startcombination
+ {\typesetfile[mfun-900.tex][page=8,width=.4\textwidth]}{even}
+ {\typesetfile[mfun-900.tex][page=9,width=.4\textwidth]}{odd}
+ \stopcombination}
+
+The previous graphics are defined as usable ones, which means that they will be
+recalculated each page. This is rather inefficient when the shapes don't change.
+But, using a reusable graphic instead, would result in only one graphic for both
+pages. Since the layout for the left and right page differs, another method is
+needed.
+
+Instead of putting the same graphic on the page layer, we put two different ones
+on the left and right page layer.
+
+\starttyping
+\defineoverlay[left page] [\useMPgraphic{left page}]
+\defineoverlay[right page][\useMPgraphic{right page}]
+
+\setupbackgrounds[leftpage] [background=left page]
+\setupbackgrounds[rightpage][background=right page]
+\stoptyping
+
+Now we only have to split the previously defined graphic into two parts. In order
+to force consistency, we isolate the code that fills and draws. The left page
+code looks like:
+
+\starttyping
+\startreusableMPgraphic{left page}
+ StartPage ;
+ path Main ; Main :=
+ llcorner Field[OuterMargin][Text] --
+ lrcorner Field[Text] [Text] --
+ urcorner Field[Text] [Text] --
+ ulcorner Field[OuterMargin][Text] -- cycle ;
+ \includeMPgraphic{draw page}
+ StopPage ;
+\stopreusableMPgraphic
+\stoptyping
+
+The right page text looks similar:
+
+\starttyping
+\startreusableMPgraphic{right page}
+ StartPage ;
+ path Main ; Main :=
+ lrcorner Field[OuterMargin][Text] --
+ llcorner Field[Text] [Text] --
+ ulcorner Field[Text] [Text] --
+ urcorner Field[OuterMargin][Text] -- cycle ;
+ \includeMPgraphic{draw page}
+ StopPage ;
+\stopreusableMPgraphic
+\stoptyping
+
+Watch how we used a reusable graphic first and a simple usable one next.
+Actually, the next graphic is not a stand alone graphic.
+
+\starttyping
+\startuseMPgraphic{draw page}
+ Main := Main enlarged 6pt ;
+ pickup pencircle scaled 2pt ;
+ fill Page withcolor .625white ;
+ fill Main withcolor .850white ;
+ draw Main withcolor .625red ;
+\stopuseMPgraphic
+\stoptyping
+
+We have seen some predefined paths and locations. Apart from the \type {Page}
+path, they take two arguments that specify their position on the layout grid.
+
+\starttabulate[|lT|l|]
+\HL
+\NC path Area [][] \NC an area similar to a \CONTEXT\ one \NC \NR
+\NC pair Location [][] \NC the position of this area \NC \NR
+\NC path Field [][] \NC the area positioned at the right place \NC \NR
+\NC path Page \NC the page itself \NC \NR
+\HL
+\stoptabulate
+
+Some less used and more obscure variables are the following.
+
+\starttabulate[|lT|l|]
+\HL
+\NC numeric Hstep [] \NC the horizontal distance to the previous area \NC \NR
+\NC numeric Vstep [] \NC the vertical distance to the previous area \NC \NR
+\NC numeric Hsize [] \NC the width of an area \NC \NR
+\NC numeric Vsize [] \NC the height of an area \NC \NR
+\HL
+\stoptabulate
+
+The array variables are accessed by using constants:
+
+\starttabulate[|l|l|]
+\HL
+\NC horizontal \NC vertical \NC \NR
+\HL
+\NC LeftEdge \NC Top \NC \NR
+\NC LeftEdgeSeparator \NC TopSeparator \NC \NR
+\NC LeftMargin \NC Header \NC \NR
+\NC LeftMarginSeparator \NC HeaderSeparator \NC \NR
+\NC Text \NC Text \NC \NR
+\NC RightMarginSeparator \NC FooterSeparator \NC \NR
+\NC RightMargin \NC Footer \NC \NR
+\NC RightEdgeSeparator \NC BottomSeparator \NC \NR
+\NC RightEdge \NC Bottom \NC \NR
+\HL
+\stoptabulate
+
+In addition to these, there are \type {Margin}, \type {InnerMargin} and \type
+{OuterMargin} which adapt themselves to the current odd or even page. The same is
+true for \type {Edge}, \type {InnerEdge} and \type {OuterEdge}, although these
+will seldom be used, since interactive documents are always single sided.
+
+We started this chapter with spending a lot of code to simulate the page areas.
+It will be clear now that in practice this is much easier using the mechanism
+described here.
+
+\placefigure
+ [here][fig:back 5]
+ {A quick way to draw all used areas.}
+ {\setupexternalfigures[background=color,backgroundcolor=white]%
+ \startcombination
+ {\typesetfile[mfun-900.tex][page=10,width=.4\textwidth]}{even}
+ {\typesetfile[mfun-900.tex][page=11,width=.4\textwidth]}{odd}
+ \stopcombination}
+
+In \in {figure} [fig:back 5] we see all used areas. Areas that are not used are
+not drawn (which saves some testing). This background was defined as:
+
+\typebuffer[back-5]
+
+We use two nested \type {for} loops to step over the areas. A \type {for} loop
+with a step of~1 will fail, because the indices are defined in a rather special
+way. On the other hand, the mechanism is rather tolerant, in the sense that \type
+{[i][j]} and \type {[j][i]} are both accepted.
+
+\stopsection
+
+\startsection[title={Bleeding}]
+
+\index {bleeding}
+
+If you want to share your document all over the world, it makes sense to use a
+paper format like {\em letter} or {\em A4}. In that case, the layout often
+matches the paper size.
+
+\startlinecorrection[blank]
+\startMPcode
+ path p ; p := fullcircle xyscaled (21mm,29.7mm) ;
+ path q ; q := boundingbox p ;
+ fill q withcolor .625white ;
+ fill p withcolor .625yellow ;
+ currentpicture := currentpicture shifted (-31mm,0) ;
+ fill q withcolor .625white ;
+ fill p xsized (bbwidth(p)-2mm) withcolor .625yellow ;
+ currentpicture := currentpicture shifted (-31mm,0) ;
+ fill q withcolor .625white ;
+ fill p withcolor .625yellow ;
+ draw q enlarged -1mm withpen pencircle scaled 2mm withcolor .625white ;
+\stopMPcode
+\stoplinecorrection
+
+The left picture demonstrates what happens when you have a printer that is
+capable of printing from edge to edge. If you have such a printer, you're lucky.
+The middle picture demonstrates what happens if you have a properly set up
+printing program and|/|or printer: the page is scaled down so that the content
+fits into the non printable area of the printer. One reason why printers don't
+print from edge to edge is that the engine is not that happy when toner or ink
+ends up next to the page. The third picture shows what happens when a printer
+simply ignores content that runs over the non printable area. In many cases it's
+best to make sure that the content leaves a margin of 5mm from the edges.
+
+Books and magazines seldom use the popular desk||top paper sizes. Here the
+designer determined the paper size and layout more or less independent from the
+size of the sheet on which the result is printed. Instead of one page per sheet,
+arrangements of 2 upto 32 or more pages per sheet are made. The process of
+arranging pages in such a way that these sheets can be folded and combined into
+books is called page imposition. \CONTEXT\ supports a wide range of page
+imposition schemes. More information on this can be found in the \CONTEXT\
+manuals.
+
+The fact that the sheet on which a page is printed is larger than the page itself
+opens the possibility to use the full page for content. In that case, especially
+when you use background graphics, you need to make sure that indeed the page is
+covered completely. Where in desk top printing you can get away with imperfection
+simply because the printing engines have their limitations, in professional
+output you need to be more considerate.
+
+\startlinecorrection[blank]
+\startMPcode
+ path p ; p := fullsquare xyscaled (4cm,5cm) ;
+ path q ; q := fullsquare xyscaled (3cm,4cm) ;
+ path r ; r := fullsquare xyscaled (2cm,3cm) shifted (-.5cm,.5cm) ;
+ fill p withcolor .625white ;
+ fill q withcolor .850white ;
+ currentpicture := currentpicture shifted (-45mm,0) ;
+ fill p withcolor .625white ;
+ fill q withcolor .850white ;
+ fill r withcolor transparent(1,.5,.625yellow) ;
+ currentpicture := currentpicture shifted (-45mm,0) ;
+ fill p withcolor .625white ;
+ fill q withcolor .850white ;
+ r := r topenlarged 2mm leftenlarged 2mm ;
+ fill r withcolor transparent(1,.5,.625yellow) ;
+\stopMPcode
+\stoplinecorrection
+
+Slightly enlarging a graphic so that it exceeds the natural page limits is called
+bleeding. Because quite often layout elements have a rectangular nature,
+\METAFUN\ provides a couple of operations that can save you some work in defining
+bleeding boxes.
+
+\startbuffer
+path p, q ;
+def ShowPath =
+ fill p withcolor transparent(1,.5,.625yellow) ;
+ fill q withcolor transparent(1,.5,.625yellow) ;
+ currentpicture := currentpicture shifted (-25mm,0) ;
+enddef ;
+p := q := fullsquare xyscaled (2cm,3cm) ; ShowPath ;
+p := p leftenlarged 2mm ; ShowPath ;
+p := p topenlarged 2mm ; ShowPath ;
+p := p rightenlarged 2mm ; ShowPath ;
+p := p bottomenlarged 2mm ; ShowPath ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+This graphic is generated as follows:
+
+\typebuffer
+
+The trick is in the last couple of lines. In addition to the general \type
+{enlarged} operator, we have 4~operators that enlarge a rectangle in a certain
+direction. This means that we can define the original path using dimensions
+related to the layout, and add bleed strips independently.
+
+\startbuffer
+path p ; p := fullsquare xyscaled (4cm,1cm) ;
+path q ; q := p leftenlarged 2mm topenlarged 2mm ;
+fill p withcolor transparent(1,.5,.625yellow) ;
+fill q withcolor transparent(1,.5,.625yellow) ;
+draw boundingbox currentpicture withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+This example demonstrates that when we enlarge a graphic, the bounding box also
+gets larger. Because this can interfere with the placement of such a graphic, we
+need to make sure that the bleeding is there but not seen.
+
+\startbuffer
+path p ; p := fullsquare xyscaled (4cm,1cm) ;
+path q ; q := p leftenlarged 2mm topenlarged 2mm ;
+fill p withcolor transparent(1,.5,.625yellow) ;
+fill q withcolor transparent(1,.5,.625yellow) ;
+setbounds currentpicture to p ;
+draw boundingbox currentpicture withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+There are two more operators: \type {innerenlarged} and \type {outerenlarged}.
+These expand to either \type {leftenlarged} or \type {rightenlarged}, depending
+on the page being left or right hand.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-backpage.tex b/doc/context/sources/general/manuals/metafun/metafun-backpage.tex
new file mode 100644
index 000000000..82931d756
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-backpage.tex
@@ -0,0 +1,53 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\doifmode{book}{\endinput}
+
+\startcomponent metafun-backpage
+
+\environment metafun-environment
+
+\startstandardmakeup[doublesided=no,page=right]
+ % back page
+\stopstandardmakeup
+
+\setupbackgrounds
+ [leftpage]
+ [background=back page]
+
+\definecolor[twhite][s=1,t=.80,a=1]
+
+\setupbackgrounds
+ [text][text]
+ [background=color,
+ backgroundcolor=twhite,
+ backgroundoffset=.5cm]
+
+\setuplayout
+ [cutspace=2cm,
+ backspace=8cm,
+ header=0pt,
+ footer=0pt,
+ topspace=17cm,
+ bottomspace=2cm]
+
+\startstandardmakeup[doublesided=no,page=left,top=,bottom=]
+
+ \switchtobodyfont[big]
+
+ \setupinterlinespace[stretch=.5]
+
+ \getbuffer[backtext]
+
+ \blank
+
+ \getbuffer[backbanner]
+
+\stopstandardmakeup
+
+\setupbackgrounds
+ [rightpage]
+ [background=]
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-basics.tex b/doc/context/sources/general/manuals/metafun/metafun-basics.tex
new file mode 100644
index 000000000..df556e239
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-basics.tex
@@ -0,0 +1,3587 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-basics
+
+\environment metafun-environment
+
+\startchapter[title={A few more details}]
+
+\startintro
+
+In this chapter we will see how to define a \METAPOST\ graphic, and how to
+include it in a document. Since the exact dimensions of graphics play an
+important role in the placement of a graphic, we will explore the way a bounding
+box is constructed.
+
+We will also pay attention to the usage of units and the side effects of scaling
+and shifting, since they can contradict our expectations in unexpected ways.
+Furthermore we will explore a few obscure areas.
+
+\stopintro
+
+\startsection[title={Making graphics}]
+
+\index{graphics}
+
+In this manual we will use \METAPOST\ in a rather straightforward way, and we
+will try to avoid complicated math as much as possible. We will do a bit of
+drawing, clipping, and moving around. Occasionally we will see some more
+complicated manipulations.
+
+When defined as stand||alone graphic, a \METAPOST\ file looks like this:
+
+\starttyping
+% Let's draw a circle.
+
+beginfig (7) ;
+ draw fullcircle scaled 3cm withpen pencircle scaled 1cm ;
+endfig ;
+
+end .
+\stoptyping
+
+The main structuring components in such a file are the \type {beginfig} and \type
+{endfig} macros. Like in a big story, the file has many sub||sentences, where
+each sub||sentence ends with a semi||colon. Although the \type {end} command at
+the end of the file concludes the story, putting a period there is a finishing
+touch. Actually, after the \type {end} command you can put whatever text you
+wish, your comments, your grocery list, whatever. Comments in \METAPOST, prefixed
+by a percent sign, as in \typ {% Let's draw a circle}, are ignored by the
+interpreter, but useful reminders for the programmer.
+
+If the file is saved as \type {yourfile.mp}, then the file is processed by
+\METAPOST\ by issuing the following command:
+
+\starttyping
+mpost yourfile
+\stoptyping
+
+after which you will have a graphic called \type {yourfile.7}, which contains a
+series of \POSTSCRIPT\ commands. Because \METAPOST\ does all the work, this file
+is efficient and compact. The number of distinct \POSTSCRIPT\ operators used is
+limited, which has the advantage that we can postprocess this file rather easily.
+Alternatively \METAPOST\ can generate \SVG\ output. It does when you say
+
+\starttyping
+outputformat := "svg" ;
+\stoptyping
+
+Here we will not go into details about this format. Even \POSTSCRIPT\ is not
+covered in detail as we use \METAPOST\ mostly in embedded form.
+
+We can view this file in a \POSTSCRIPT\ viewer like \GHOSTVIEW\ or convert the
+graphic to \PDF\ (using \type {mptopdf}) and view the result in a suitable \PDF\
+viewer like \ACROBAT. Of course, you can embed such a file in a \CONTEXT\
+document, using a command like:
+
+\starttyping
+\externalfigure[yourfile.7]
+\stoptyping
+
+We will go in more detail about embedding graphics in \in {chapter}
+[sec:embedding].
+
+If you have installed \CONTEXT, somewhere on your system there resides a file
+\type {mp-tool.mp}. If you make a stand||alone graphic, it's best to put the
+following line at the top of your file:
+
+\starttyping
+input mp-tool ; % or input metafun ;
+\stoptyping
+
+By loading this file, the resulting graphic will provide a high resolution
+bounding box, which enables more accurate placement. The file also sets the \typ
+{prologues := 1} so that viewers like \GHOSTVIEW\ can refresh the file when it is
+changed.
+
+Next we will introduce some more \METAPOST\ commands. From now on, we will omit
+the encapsulating \type {beginfig} and \type {endfig} macros. If you want to
+process these examples yourself, you should add those commands yourself, or if
+you use \CONTEXT\ you don't need them at all.
+
+\startbuffer
+pickup pencircle scaled .5cm ;
+draw unitsquare xscaled 8cm yscaled 1cm withcolor .625white ;
+draw origin withcolor .625yellow ;
+pickup pencircle scaled 1pt ;
+draw bbox currentpicture withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+In this example we see a mixture of so called primitives as well as macros. A
+primitive is something hard coded, a built||in command, while a macro is a
+collection of such primitives, packaged in a way that they can be recalled
+easily. Where \type {scaled} is a primitive and \type {draw} a macro, \type
+{unitsquare} is a path variable, an abbreviation for:
+
+\starttyping
+unitsquare = (0,0) -- (1,0) -- (1,1) -- (0,1) -- cycle ;
+\stoptyping
+
+The double dash (\type {--}) is also a macro, used to connect two points with a
+straight line segment. However, \type {cycle} is a primitive, which connects the
+last point of the unitsquare to the first on unitsquare's path. Path variables
+must first be declared, as in:
+
+\starttyping
+path unitsquare ;
+\stoptyping
+
+A large collection of such macros is available when you launch \METAPOST. Consult
+the \METAPOST\ manual for details.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+In the first line of our example, we set the drawing pen to \type {.5cm}. You can
+also specify such a dimension in other units, like points (\type {pt}). When no
+unit is provided, \METAPOST\ will use a big point (\type {bp}) , the \POSTSCRIPT\
+approximation of a point.
+
+The second line does just as it says: it draws a rectangle of certain dimensions
+in a certain color. In the third line we draw a colored dot at the origin of the
+coordinate system in which we are drawing. Finally, we set up a smaller pen and
+draw the bounding box of the current picture, using the variable \type
+{currentpicture}. Normally, all drawn shapes end up in this picture variable.
+
+\stopsection
+
+\startsection[title={Bounding boxes}]
+
+\index{boundingbox}
+
+If you take a close look at the last picture in the previous section, you will
+notice that the bounding box is larger than the picture. This is one of the nasty
+side effects of \METAPOST's \type {bbox} macro. This macro draws a box, but with
+a certain offset. The next example shows how we can manipulate this offset.
+Personally I never use the \type {bbox} macro because this offset is rather
+annoying. Also, the \type {boundingbox} operator combined with \type {enlarged}
+can provide any offset you want.
+
+\startbuffer
+pickup pencircle scaled .5cm ;
+draw unitsquare xscaled 8cm yscaled 1cm withcolor .625white ;
+path bb ; bboxmargin := 0pt ; bb := bbox currentpicture ;
+draw bb withpen pencircle scaled 1pt withcolor .625red ;
+draw origin withpen pencircle scaled 5pt withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+In the third line we define a path variable. We assign the current bounding box
+to this variable, but first we set the offset to zero. The last line demonstrates
+how to draw such a path. Instead of setting the pen as we did in the first line,
+we pass the dimensions directly.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Where \type {draw} draws a path, the \type {fill} macro fills one. In order to be
+filled, a path should be closed, which is accomplished by the \type {cycle}
+primitive, as we saw in constructing the \type {unitsquare} path.
+
+\startbuffer
+pickup pencircle scaled .5cm ;
+fill unitsquare xscaled 8cm yscaled 1cm withcolor .625white ;
+path bb ; bboxmargin := 0pt ; bb := bbox currentpicture ;
+draw bb withpen pencircle scaled 1pt withcolor .625red ;
+draw origin withpen pencircle scaled 5pt withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+This example demonstrates that when we fill the path, the resulting graphic is
+smaller. Where \type {draw} follows the center of a path, \type {fill} stays
+inside the path.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+A third alternative is the \type {filldraw} macro. From the previous examples, we
+would expect a bounding box that matches the one of the drawn path.
+
+\startbuffer
+pickup pencircle scaled .5cm ;
+filldraw unitsquare xscaled 8cm yscaled 1cm withcolor .625white ;
+path bb ; bboxmargin := 0pt ; bb := bbox currentpicture ;
+draw bb withpen pencircle scaled 1pt withcolor .625red ;
+draw origin withpen pencircle scaled 5pt withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+% The resulting graphic has the bounding box of the fill. Note
+% how the path, because it is stroked with a .5cm pen, extends
+% beyond the border of the bounding box. The way this image
+% shows up depends on the viewer (settings) you use to render
+% the graphic. For example, in \GHOSTVIEW, if you disable
+% clipping to the bounding box, only the positive quadrant of
+% the graphic is shown. Further, if you enable clipping to the
+% bounding box, this image will look exactly like the previous
+% image created with the fill command. In many cases, it may
+% be best to avoid the \type {filldraw} command.
+
+The resulting graphic has the bounding box of the fill. Note how the path,
+because it is stroked with a .5cm pen, extends beyond the border of the previous
+bounding box. The way this image shows up depends on the viewer (settings) you
+use to render the graphic. For example, in \GHOSTVIEW, if you disable clipping to
+the bounding box, only the positive quadrant of the graphic is shown. \footnote
+{Old versions of \METAPOST\ calculated the boundingbox differently for a \type
+{filldraw}: through the middle of the penpath.}
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+From the previous examples, you can conclude that the following alternative
+results in a proper bounding box:
+
+\startbuffer
+pickup pencircle scaled .5cm ;
+path p ; p := unitsquare xscaled 8cm yscaled 1cm ;
+fill p withcolor .625white ;
+draw p withcolor .625white ;
+path bb ; bboxmargin := 0pt ; bb := bbox currentpicture ;
+draw bb withpen pencircle scaled 1pt withcolor .625red ;
+draw origin withpen pencircle scaled 5pt withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The \CONTEXT\ distribution comes with a set of \METAPOST\ modules, one of which
+contains the \type {drawfill} macro, which provides the outer bounding box.
+\footnote {Starting from version 1.0 \METAPOST\ calculates the boundingbox
+differently and the distinction between \type {drawfill} and \type {filldraw} is
+gone. We keep them around both for compatibility.} Next we demonstrate its use in
+another, more complicated example.
+
+\startbuffer
+picture finalpicture ; finalpicture := nullpicture ;
+numeric n ; n := 0 ; bboxmargin := 0pt ;
+pickup pencircle scaled .5cm ;
+
+def shape =
+ unitsquare scaled 2cm withcolor .625white ;
+ draw bbox currentpicture
+ withpen pencircle scaled .5mm withcolor .625red ;
+ addto finalpicture also currentpicture shifted(n*3cm,0) ;
+ currentpicture := nullpicture ; n := n+1 ;
+enddef ;
+
+fill shape ; draw shape ; filldraw shape ; drawfill shape ;
+
+currentpicture := finalpicture ;
+\stopbuffer
+
+\typebuffer
+
+Here we introduce a macro definition, \type {shape}. In \METAPOST, the start of a
+macro definition is indicated with the keyword \type {def}. Thereafter, you can
+insert other variables and commands, even other macro definitions. The keyword
+\type {enddef} signals the end of the macro definition. The result is shown in
+\in {figure} [fig:draws and fills]; watch the bounding boxes. Close reading of
+the macro will reveal that the \type {fill}, \type {draw}, \type {filldraw} and
+\type {drawfill} macros are applied to the first \type {unitsquare} path in the
+macro.
+
+\placefigure
+ [here]
+ [fig:draws and fills]
+ {A \type {fill}, \type {draw}, \type {filldraw} and \type
+ {drawfill} applied to the same square.}
+ {\processMPbuffer}
+
+In this macro, \type {bbox} calls a macro that returns the enlarged bounding box
+of a path. By setting \type {bboxmargin} we can influence how much the bounding
+box is enlarged. Since this is an existing variable, we don't have to allocate
+it, like we do with~\type{numeric n}. Unless you take special precautions,
+variables are global by nature and persistent outside macros.
+
+\starttyping
+picture finalpicture ; finalpicture := nullpicture ;
+\stoptyping
+
+Just as \type {numeric} allocates an integer variable, the \type {picture}
+primitive allocates a picture data structure. We explicitly have to set this
+picture to nothing using the built||in primitive \type {nullpicture}.
+
+Later on, we will add the drawn paths as accumulated in \type {currentpicture} to
+this \type {finalpicture} in the following manner.
+
+\starttyping
+addto finalpicture also currentpicture shifted(n*3cm,0) ;
+\stoptyping
+
+Since we want to add a few more and don't want them to overlap, we shift them.
+Therefore we have to erase the current picture as well as increment the shift
+counter.
+
+\starttyping
+currentpicture := nullpicture ; n := n+1 ;
+\stoptyping
+
+The \type {drawfill} macro is one of the \METAFUN\ macros. Another handy macro is
+\type {boundingbox}. When used instead of \type {bbox}, you don't have to set the
+margin to zero.
+
+\startbuffer
+drawoptions (withcolor .625white) ;
+path p ; p := unitsquare scaled 2cm ;
+fill p shifted (3cm,0) ;
+pickup pencircle scaled .5cm ; fill p shifted (6cm,0) ;
+fill p shifted (9cm,0) withpen pencircle scaled .5cm ;
+\stopbuffer
+
+\placefigure
+ [here]
+ [fig:more draws and fills]
+ {The influence of pens on \type {fill}.}
+ {\processMPbuffer}
+
+There is a subtle point in filling a shape. In \in {figure} [fig:more draws and
+fills] you see the influence of the pen on a \type {fill} operation. An indirect
+specification has no influence, and results in a filled rectangle with sharp
+corners. The third rectangle is drawn with a direct pen specification which
+results in a larger shape with rounds corners. However, the bounding box is the
+same in all three cases. The graphic is defined as follows. This time we don't
+use a (complicated) macro.
+
+\typebuffer
+
+When a graphic is constructed, its components end up in an internal data
+structure in a more or less layered way. This means that as long as a graphic is
+not flushed, you may consider it to be a stack of paths and texts with the paths
+being drawn or filled shapes or acting as clipping paths or bounding boxes.
+
+When you ask for the dimensions of a graphic the lower left and upper right
+corner are calculated using this stack. Because you can explicitly set bounding
+boxes, you can lie about the dimensions of a graphic. This is a very useful
+feature. In the rare case that you want to know the truth and nothing but the
+truth, you can tweak the \type {truecorners} numeric variable. We will
+demonstrate this with a few examples.
+
+\startbuffer
+fill fullcircle scaled 1cm withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\ruledhbox{\processMPbuffer}\stoplinecorrection
+
+\startbuffer
+fill fullcircle scaled 1cm withcolor .625yellow ;
+setbounds currentpicture to boundingbox currentpicture enlarged 2mm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\ruledhbox{\processMPbuffer}\stoplinecorrection
+
+\startbuffer
+fill fullcircle scaled 1cm withcolor .625yellow ;
+setbounds currentpicture to boundingbox currentpicture enlarged 2mm ;
+interim truecorners := 1 ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\ruledhbox{\processMPbuffer}\stoplinecorrection
+
+\startbuffer
+fill fullcircle scaled 1cm withcolor .625yellow ;
+interim truecorners := 1 ;
+setbounds currentpicture to boundingbox currentpicture enlarged 2mm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\ruledhbox{\processMPbuffer}\stoplinecorrection
+
+As you can see here, as soon as we set \type {truecorners} to~1, the bounding box
+settings are ignored. \footnote {Normally you will use grouping to keep the
+interim local. In \METAFUN\ each figure restores this variable at the beginning.}
+
+There are two related macros: \type {bbwidth} and \type {bbheight} that you can
+apply to a path.
+
+\startbuffer
+fill unitcircle xscaled 4cm yscaled 2cm
+ withpen pencircle scaled 1mm withcolor .625red ;
+draw origin -- (bbwidth(currentpicture),0)
+ withpen pencircle scaled 1mm withcolor .625yellow ;
+draw origin -- (0,bbheight(currentpicture))
+ withpen pencircle scaled 1mm withcolor .625white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+\stopsection
+
+Yet another helper is \type {boundingcircle}. Its effect can best be demonstrated with
+a few examples:
+
+\startbuffer[a]
+path p ; p := fullsquare scaled 2cm ;
+
+draw p withpen pencircle scaled 3mm withcolor .625white ;
+draw center p withpen pencircle scaled 3mm withcolor .625white ;
+draw boundingbox p withpen pencircle scaled 1mm withcolor .625red ;
+draw boundingcircle p withpen pencircle scaled 1mm withcolor .625yellow ;
+\stopbuffer
+
+\startbuffer[b]
+path p ; p := fullcircle scaled 2cm ;
+
+draw p withpen pencircle scaled 3mm withcolor .625white ;
+draw center p withpen pencircle scaled 3mm withcolor .625white ;
+draw boundingbox p withpen pencircle scaled 1mm withcolor .625red ;
+draw boundingcircle p withpen pencircle scaled 1mm withcolor .625yellow ;
+\stopbuffer
+
+\startbuffer[c]
+path p ; p := fulltriangle scaled 2cm ;
+
+draw p withpen pencircle scaled 3mm withcolor .625white ;
+draw center p withpen pencircle scaled 3mm withcolor .625white ;
+draw boundingbox p withpen pencircle scaled 1mm withcolor .625red ;
+draw boundingcircle p withpen pencircle scaled 1mm withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer[a,b,c]
+
+You can consider the \type {boundingcircle} to be a round boundingbox.
+
+\startlinecorrection
+\startcombination[nx=3,ny=1,location=middle]
+ {\processMPbuffer[a]} {square}
+ {\processMPbuffer[b]} {circle}
+ {\processMPbuffer[c]} {triangle}
+\stopcombination
+\stoplinecorrection
+
+\startsection[title={Units}]
+
+\index{units}
+
+Like \TEX, \METAPOST\ supports multiple units of length. In \TEX, these units are
+hard coded and handled by the parser, where the internal unit of length is the
+scaled point (\type {sp}), something on the nanometer range. Because \METAPOST\
+is focused on \POSTSCRIPT\ output, its internal unit is the big point (\type
+{bp}). All other units are derived from this unit and available as numeric
+instead of hard coded.
+
+\starttyping
+mm = 2.83464 ; pt = 0.99626 ; dd = 1.06601 ; bp := 1 ;
+cm = 28.34645 ; pc = 11.95517 ; cc = 12.79213 ; in := 72 ;
+\stoptyping
+
+Careful reading reveals that only the \type {bp} and \type {in} are fixed, while
+the rest of the dimensions are scalar multiples of \type {bp}.
+
+Since we are dealing with graphics, the most commonly used dimensions are \type
+{pt}, \type {bp}, \type {mm}, \type {cm} and~\type {in}.
+
+\startuseMPgraphic{pt}
+ fill fullsquare scaled 72.27pt withcolor .625yellow ;
+ fill fullcircle scaled 72.27pt withcolor white ;
+ label("72.27pt", center currentpicture) ;
+\stopuseMPgraphic
+\startuseMPgraphic{bp}
+ fill fullsquare scaled 72bp withcolor .625yellow ;
+ fill fullcircle scaled 72bp withcolor white ;
+ label("72bp", center currentpicture) ;
+\stopuseMPgraphic
+\startuseMPgraphic{mm}
+ fill fullsquare scaled 25.4mm withcolor .625yellow ;
+ fill fullcircle scaled 25.4mm withcolor white ;
+ label("25.4mm", center currentpicture) ;
+\stopuseMPgraphic
+\startuseMPgraphic{cm}
+ fill fullsquare scaled 2.54cm withcolor .625yellow ;
+ fill fullcircle scaled 2.54cm withcolor white ;
+ label("2.54cm", center currentpicture) ;
+\stopuseMPgraphic
+\startuseMPgraphic{in}
+ fill fullsquare scaled 1in withcolor .625yellow ;
+ fill fullcircle scaled 1in withcolor white ;
+ label("1in", center currentpicture) ;
+\stopuseMPgraphic
+
+\startlinecorrection[blank]
+\hbox to \hsize
+ {\useMPgraphic{pt}\hss
+ \useMPgraphic{bp}\hss
+ \useMPgraphic{mm}\hss
+ \useMPgraphic{cm}\hss
+ \useMPgraphic{in}}
+\stoplinecorrection
+
+The text in the center of the leftmost graphic is typeset by \METAPOST\ as a
+label.
+
+\starttyping
+fill fullsquare scaled 72.27pt withcolor .625yellow ;
+fill fullcircle scaled 72.27pt withcolor white ;
+label("72.27pt", center currentpicture) ;
+\stoptyping
+
+In \METAPOST\ the following lines are identical:
+
+\starttyping
+draw fullcircle scaled 100 ;
+draw fullcircle scaled 100bp ;
+\stoptyping
+
+You might be tempted to omit the unit, but this can be confusing, particularly if
+you also program in a language like \METAFONT, where the \type {pt} is the base
+unit. This means that a circle scaled to 100 in \METAPOST\ is not the same as a
+circle scaled to 100 in \METAFONT. Consider the next definition:
+
+\startbuffer
+pickup pencircle scaled 0 ;
+fill unitsquare
+ xscaled 400pt yscaled -.5cm withcolor .625red ;
+fill unitsquare
+ xscaled 400bp yscaled +.5cm withcolor .625yellow ;
+drawoptions(withcolor white) ;
+label.rt("400 pt", origin shifted (0, -.25cm)) ;
+label.rt("400 bp", origin shifted (0, +.25cm)) ;
+\stopbuffer
+
+\typebuffer
+
+When processed, the difference between a \type {pt} and \type {bp} shows rather
+well. Watch how we use \type {.rt} to move the label to the right; you can
+compare this with \TEX's macro \type {\rlap}. You might want to experiment with
+\type {.lft}, \type {.top}, \type {.bot}, \type {.ulft}, \type {.urt}, \type
+{.llft} and \type {.lrt}.
+
+The difference between both bars is exactly \scratchdimen = 400 bp
+\advance\scratchdimen by -400 pt \the \scratchdimen \space (as calculated by
+\TEX).
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Where \TEX\ is anchored in tradition, and therefore more or less uses the \type
+{pt} as the default unit, \METAPOST, much like \POSTSCRIPT, has its roots in the
+computer sciences. There, to simplify calculations, an inch is divided in 72 big
+points, and .72pt is sacrificed.
+
+When you consider that \POSTSCRIPT\ is a high end graphic programming language,
+you may wonder why this sacrifice was made. Although the difference between \type
+{1bp} and \type {1pt} is miniscule, this difference is the source of much
+(unknown) confusion. When \TEX\ users talk about a \type {10pt} font, a desktop
+publisher hears \type {10bp}. In a similar vein, when we define a papersize
+having a width of \type {600pt} and a height of \type {450pt}, which is papersize
+\type {S6} in \CONTEXT, a \POSTSCRIPT\ or \PDF\ viewer will report slightly
+smaller values as page dimensions. This is because those programs claim the \type
+{pt} to be a \type {bp}. [This confusion can lead to interesting discussions with
+desktop publishers when they have to use \TEX. They often think that their demand
+of a baseline distance of \type {13.4} is met when we set it to \type {13.4pt},
+while actually they were thinking of \type {13.4bp}, which of course in other
+programs is specified using a \type {pt} suffix.]
+
+Therefore, when embedding graphics in \CONTEXT, we strongly recommend that you
+use \type {pt} as the base unit instead. The main reason why we spend so many
+words on this issue is that, when neglected, large graphics may look inaccurate.
+Actually, when taken care of, it is one of the (many) reasons why \TEX\ documents
+always look so accurate. Given that the eye is sensitive to distortions of far
+less than \type {1pt}, you can be puzzled by the fact that many drawing programs
+only provide a bounding box in rounded units. Thereby, they round to the next
+position, to prevent unwanted cropping. For some reason this low resolution has
+made it into the high end \POSTSCRIPT\ standard.
+
+In \CONTEXT\ we try to deal with these issues as well as possible.
+
+\stopsection
+
+\startsection[title={Scaling and shifting}]
+
+\index{scaling}
+\index{shifting}
+
+When we draw a shape, \METAPOST\ will adapt the bounding box accordingly. This
+means that a graphic has its natural dimensions, unless of course we adapt the
+bounding box manually. When you limit your graphic to a simple shape, say a
+rectangle, shifting it to some place can get obscured by this fact. Therefore,
+the following series of shapes appear to be the same.
+
+\startbuffer
+draw
+ unitsquare xscaled 6cm yscaled 1.5cm
+ withpen pencircle scaled 2mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+\startbuffer
+draw
+ unitsquare shifted (.5,.5) xscaled 6cm yscaled 1.5cm
+ withpen pencircle scaled 2mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+\startbuffer
+draw
+ unitsquare shifted (-.5,-.5) xscaled 6cm yscaled 1.5cm
+ withpen pencircle scaled 2mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+\startbuffer
+draw
+ unitsquare xscaled 6cm yscaled 1.5cm shifted (1cm,1cm)
+ withpen pencircle scaled 2mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+\startbuffer
+draw
+ unitsquare xscaled 6cm yscaled 1.5cm shifted (1.5cm,1cm)
+ withpen pencircle scaled 2mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+However, when we combine such graphics into one, we will see in what respect the
+scaling and shifting actually takes place.
+
+\startbuffer
+draw
+ unitsquare xscaled 6cm yscaled 2cm
+ withpen pencircle scaled 3.0mm withcolor .625yellow ;
+draw
+ unitsquare shifted (.5,.5) xscaled 6cm yscaled 2cm
+ withpen pencircle scaled 3.0mm withcolor .625red ;
+draw
+ unitsquare xscaled 6cm yscaled 2cm shifted (1cm,1cm)
+ withpen pencircle scaled 3.0mm withcolor .625white ;
+draw
+ unitsquare xscaled 6cm yscaled 2cm shifted (1.5cm,1cm)
+ withpen pencircle scaled 1.5mm withcolor white ;
+draw
+ unitsquare shifted (-.5,-.5) xscaled 6cm yscaled 2cm
+ withpen pencircle scaled 1mm withcolor black ;
+draw origin withpen pencircle scaled 1mm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+As you can see, the transformations are applied in series. Sometimes this is not
+what we want, in which case we can use parentheses to force the desired
+behaviour. The lesson learned is that {\em scaling and shifting} is not always
+the same as {\em shifting and scaling}.
+
+\startbuffer
+draw
+ origin -- origin shifted ((4cm,0cm) shifted (4cm,0cm))
+ withpen pencircle scaled 1cm withcolor .625white ;
+draw
+ origin -- origin shifted (4cm,0cm) shifted (4cm,0cm)
+ withpen pencircle scaled 8mm withcolor .625yellow ;
+draw
+ (origin -- origin shifted (4cm,0cm)) shifted (4cm,0cm)
+ withpen pencircle scaled 6mm withcolor .625red ;
+draw
+ origin -- (origin shifted (4cm,0cm) shifted (4cm,0cm))
+ withpen pencircle scaled 4mm withcolor white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+Especially when a path results from a call to a macro, using parentheses around a
+path may help, as in the following example.
+
+\startbuffer
+def unitslant = origin -- origin shifted (1,1) enddef ;
+draw
+ unitslant xscaled 5cm yscaled 1cm
+ withpen pencircle scaled 1cm withcolor .625red ;
+draw
+ (unitslant) xscaled 5cm yscaled 1cm
+ withpen pencircle scaled 5mm withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+The next definition of \type {unitslant} is therefore better.
+
+\startbuffer
+def unitslant = (origin -- origin shifted (1,1)) enddef ;
+draw
+ unitslant xscaled 5cm yscaled 1cm
+ withpen pencircle scaled 5mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]\processMPbuffer\stoplinecorrection
+
+An even better alternative is:
+
+\startbuffer
+path unitslant ; unitslant = origin -- origin shifted (1,1) ;
+draw
+ unitslant xscaled 5cm yscaled 1cm
+ withpen pencircle scaled 5mm withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Curve construction}]
+
+\index{curves}
+
+\doifmodeelse{screen}
+ {\def\Xcom{3}\def\Ycom{2}\def\Zcom{\the\textheight}}
+ {\def\Xcom{2}\def\Ycom{3}\def\Zcom{\the\textwidth }}
+
+Chapter 3 of the \METAFONT\ book explains the mathematics behind the construction
+of curves. Both \METAFONT\ and \METAPOST\ implement B\'ezier curves. The fact
+that these curves are named after Pierre B\'ezier obscures the fact that the math
+behind them originates with Serge\u{\i} Bernshte\u{\i}n.
+
+The points on the curve are determined by the following formula:
+
+\placeformula[-]
+\startformula
+z(t) = (1-t)^3 z_1 + 3 (1-t)^2 t z_2 + 3 (1-t) t^2 z_3 + t^3 z_4
+\stopformula
+
+Here, the parameter $t$ runs from $[0,1]$. As you can see, we are dealing with
+four points. In practice this means that when we construct a curve from multiple
+points, we act on two points and the two control points in between. So, the
+segment that goes from $z_1$ to $z_4$ is calculated using these two points and
+the points that \METAFONT|/|\METAPOST\ calls post control point and pre control
+point.
+
+\startbuffer[a]
+vardef dodrawmidpoints (expr a, b, c, d, n, col, m) =
+ save e, f, g, h, i, j ; pair e, f, g, h, i, j ;
+ e := .5[a,b] ; f := .5[b,c] ; g := .5[c,d] ;
+ h := .5[e,f] ; i := .5[f,g] ; j := .5[h,i] ;
+ if m= 0 : drawpoints j elseif
+ m= 1 : draw a--b--c--d elseif
+ m= 2 : draw e--f--g elseif
+ m= 3 : draw h--i elseif
+ m= 4 : draw a--e--h--j elseif
+ m= 5 : draw j--i--g--d elseif
+ m=11 : drawpoints a--b--c--d elseif
+ m=12 : drawpoints e--f--g elseif
+ m=13 : drawpoints h--i elseif
+ m=14 : drawpoints a--e--h--j elseif
+ m=15 : drawpoints j--i--g--d fi withcolor col ;
+ if n>1 :
+ dodrawmidpoints(a, e, h, j, n-1, col, m) ;
+ dodrawmidpoints(j, i, g, d, n-1, col, m) ;
+ fi ;
+enddef ;
+
+vardef drawmidpoints (expr p, n, col, m) =
+ save a, b, c, d ; pair a, b, c, d ;
+ for x=0 upto length(p)-1 :
+ a := point x of p ; b := postcontrol x of p ;
+ d := point x+1 of p ; c := precontrol x+1 of p ;
+ dodrawmidpoints(a,b,c,d,n,col,m) ;
+ endfor ;
+enddef ;
+\stopbuffer
+
+\startbuffer[b]
+path p ; p := (4cm,4cm)..(6cm,0cm)..(1cm,2cm) ;
+\stopbuffer
+
+\startbuffer[c]
+drawpath p ;
+drawcontrollines p withcolor .625yellow ;
+drawcontrolpoints p withcolor .625red ;
+drawpoints p withcolor .625red ;
+freelabel(btex $z_1$ etex, point 0 of p, center p) ;
+freelabel(btex $z_2$ etex, postcontrol 0 of p, center p) ;
+freelabel(btex $z_3$ etex, precontrol 1 of p, center p) ;
+freelabel(btex $z_4$ etex, point 1 of p, center p) ;
+freelabel(btex $z_5$ etex, postcontrol 1 of p, center p) ;
+freelabel(btex $z_6$ etex, precontrol 2 of p, center p) ;
+freelabel(btex $z_7$ etex, point 2 of p, center p) ;
+\stopbuffer
+
+\startbuffer[x]
+draw boundingbox p enlarged 1cm ;
+setbounds currentpicture to boundingbox p enlarged 1cm ;
+currentpicture := currentpicture xsized (.45*\Zcom) ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,x]
+\stoplinecorrection
+
+The previous curve is constructed from the three points $z_1$, $z_4$ and $z_7$.
+The curve is drawn in \METAPOST\ by \type {z1..z4..z7} and is made up out of two
+segments. The first segment is determined by the following points:
+
+\startitemize[packed,n]
+\item point $z_1$ of the curve
+\item the postcontrol point $z_2$ of $z_1$
+\item the precontrol point $z_3$ of $z_4$
+\item point $z_4$ of the curve
+\stopitemize
+
+On the next pages we will see how the whole curve is constructed from these
+quadruples of points. The process comes down to connecting the mid points of the
+straight lines to the points mentioned. We do this three times, which is why
+these curves are classified as third order approximations.
+
+The first series of graphics demonstrates the process of determining the mid
+points. The third order midpoint is positioned on the final curve. The second
+series focuses on the results: new sets of four points that will be used in a
+next stage. The last series only shows the third order midpoints. As you can see,
+after some six iterations we have already reached a rather good fit of the final
+curve. The exact number of iterations depends on the resolution needed. You will
+notice that the construction speed (density) differs per segment.
+
+\startpostponing
+
+% cc .. hh in order to avoid conflicts with c-...
+
+\startbuffer[cc]
+drawpath p ; drawpoints p ; drawcontrolpoints p ;
+\stopbuffer
+
+\startbuffer[dd]
+drawmidpoints(p,1,.625red, 11) ; drawmidpoints(p,1,.625yellow, 1) ;
+\stopbuffer
+
+\startbuffer[ee]
+drawmidpoints(p,1,.625red, 12) ; drawmidpoints(p,1,.625yellow, 2) ;
+\stopbuffer
+
+\startbuffer[ff]
+drawmidpoints(p,1,.625red, 13) ; drawmidpoints(p,1,.625yellow, 3) ;
+\stopbuffer
+
+\startbuffer[gg]
+drawmidpoints(p,1,.625red, 14) ; drawmidpoints(p,1,.625yellow, 4) ;
+\stopbuffer
+
+\startbuffer[hh]
+drawmidpoints(p,1,.625red, 15) ; drawmidpoints(p,1,.625yellow, 5) ;
+\stopbuffer
+
+\startbuffer
+\startcombination[\Xcom*\Ycom]
+ {\processMPbuffer[a,b,cc,x]} {points}
+ {\processMPbuffer[a,b,cc,dd,x]} {first order curve}
+ {\processMPbuffer[a,b,cc,dd,ee,x]} {second order curve}
+ {\processMPbuffer[a,b,cc,dd,ee,ff,x]} {third order curve}
+ {\processMPbuffer[a,b,cc,dd,ee,gg,x]} {left side curves}
+ {\processMPbuffer[a,b,cc,dd,ee,hh,x]} {right side curves}
+\stopcombination
+\stopbuffer
+
+\getbuffer \page
+
+\startbuffer[dd]
+drawmidpoints(p,1,.625red, 11) ;
+drawmidpoints(p,1,.625yellow, 1) ;
+\stopbuffer
+
+\startbuffer[ee]
+for i=11, 12 : drawmidpoints(p,1,.625red, i) ; endfor ;
+drawmidpoints(p,1,.625yellow, 2) ;
+\stopbuffer
+
+\startbuffer[ff]
+for i=11, 12, 13 : drawmidpoints(p,1,.625red, i) ; endfor ;
+drawmidpoints(p,1,.625yellow, 3) ;
+\stopbuffer
+
+\startbuffer[gg]
+for i=11,12,13,14 : drawmidpoints(p,1,.625red, i) ; endfor ;
+drawmidpoints(p,1,.625yellow, 4) ;
+\stopbuffer
+
+\startbuffer[hh]
+for i=11, 12, 13, 14, 15 : drawmidpoints(p,1,.625red, i) ; endfor ;
+drawmidpoints(p,1,.625yellow, 5) ;
+\stopbuffer
+
+\startbuffer
+\startcombination[\Xcom*\Ycom]
+ {\processMPbuffer[a,b,cc,x]} {points}
+ {\processMPbuffer[a,b,cc,dd,x]} {first order points}
+ {\processMPbuffer[a,b,cc,ee,x]} {second order points}
+ {\processMPbuffer[a,b,cc,ff,x]} {third order points}
+ {\processMPbuffer[a,b,cc,gg,x]} {left side points}
+ {\processMPbuffer[a,b,cc,hh,x]} {right side points}
+\stopcombination
+\stopbuffer
+
+\getbuffer \page
+
+\startbuffer[cc]
+drawpath p ; drawmidpoints (p,1,.625yellow, 0) ;
+\stopbuffer
+
+\startbuffer[dd]
+drawpath p ; drawmidpoints (p,2,.625yellow, 0) ;
+\stopbuffer
+
+\startbuffer[ee]
+drawpath p ; drawmidpoints (p,3,.625yellow, 0) ;
+\stopbuffer
+
+\startbuffer[ff]
+drawpath p ; drawmidpoints (p,4,.625yellow, 0) ;
+\stopbuffer
+
+\startbuffer[gg]
+drawpath p ; drawmidpoints (p,5,.625yellow, 0) ;
+\stopbuffer
+
+\startbuffer[hh]
+drawpath p ; drawmidpoints (p,6,.625yellow, 0) ;
+\stopbuffer
+
+\startbuffer
+\startcombination[\Xcom*\Ycom]
+ {\processMPbuffer[a,b,cc,x]} {first iteration}
+ {\processMPbuffer[a,b,cc,dd,x]} {second iteration}
+ {\processMPbuffer[a,b,cc,dd,ee,x]} {third iteration}
+ {\processMPbuffer[a,b,cc,dd,ee,ff,x]} {fourth iteration}
+ {\processMPbuffer[a,b,cc,dd,ee,ff,gg,x]} {fifth iteration}
+ {\processMPbuffer[a,b,cc,dd,ee,ff,gg,hh,x]} {sixths iteration}
+\stopcombination
+\stopbuffer
+
+\getbuffer \page
+
+\stoppostponing
+
+% here we pick up the thread, if we would not flush the
+% pages before the next text, the reader could become
+% confused
+
+The path in these examples is defined as follows:
+
+\typebuffer[b]
+
+If you are playing with graphics like this, the \METAFUN\ macro \type {randomize}
+may come in handy:
+
+\startbuffer[bb]
+p := p randomized (1cm,.5cm) ;
+\stopbuffer
+
+\typebuffer[bb]
+
+If we apply this operation a couple of times we can see how the (control) points
+vary. (Using the randomizer saves us the troubles of finding nice example
+values.) The angle between the tangent as well as the distance from the parent
+point determine the curve.
+
+\startbuffer[xx]
+currentpicture := currentpicture scaled .5 ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\hbox to \hsize
+ {\processMPbuffer[a,b,bb,c,x,xx]\hss
+ \processMPbuffer[a,b,bb,c,x,xx]\hss
+ \processMPbuffer[a,b,bb,c,x,xx]\hss
+ \processMPbuffer[a,b,bb,c,x,xx]}
+\stoplinecorrection
+
+% new thread
+
+Just in case you are interested in how such graphical simulations can be
+organized, we show simplified versions of the macros used here. (In the previous
+examples we minimized the complexity of the code by using buffers, but describing
+this mechanism is out of the scope of this section.)
+
+\startbuffer[demo]
+vardef dodrawmidpoints (expr a, b, c, d, n) =
+ save e, f, g, h, i, j ; pair e, f, g, h, i, j ;
+ e := .5[a,b] ; f := .5[b,c] ; g := .5[c,d] ;
+ h := .5[e,f] ; i := .5[f,g] ; j := .5[h,i] ;
+ draw j ;
+ if n>1 :
+ dodrawmidpoints(a, e, h, j, n-1) ;
+ dodrawmidpoints(j, i, g, d, n-1) ;
+ fi ;
+enddef ;
+
+vardef drawmidpoints (expr p, n) =
+ save a, b, c, d ; pair a, b, c, d ;
+ for x=0 upto length(p)-1 :
+ a := point x of p ; b := postcontrol x of p ;
+ d := point x+1 of p ; c := precontrol x+1 of p ;
+ dodrawmidpoints(a, b, c, d, n) ;
+ endfor ;
+enddef ;
+\stopbuffer
+
+We need to loop over all segments of a curve, where for each segment the left and
+right side sub curves are handled recursively, upto the requested depth (denoted
+as \type {n}). For this we define the following macros.
+
+\typebuffer[demo]
+
+\startbuffer[zero]
+drawoptions (withpen pencircle scaled 5pt withcolor .625red);
+\stopbuffer
+
+\startbuffer[extra]
+drawoptions (withpen pencircle scaled 5pt withcolor .625yellow);
+\stopbuffer
+
+We apply this macro to a simple shape:
+
+\startbuffer[one]
+drawmidpoints (fullcircle xscaled 300pt yscaled 50pt, 1) ;
+\stopbuffer
+
+\typebuffer[one]
+
+When drawn, this results in the points that makes up the
+curve:
+
+\startlinecorrection[blank]
+\processMPbuffer[demo,zero,one]
+\stoplinecorrection
+
+We now add an extra iteration (resulting in the yellow points):
+
+\startbuffer[two]
+drawmidpoints (fullcircle xscaled 300pt yscaled 50pt, 2) ;
+\stopbuffer
+
+\typebuffer[two]
+
+and get:
+
+\startlinecorrection[blank]
+\processMPbuffer[demo,zero,two,extra,one]
+\stoplinecorrection
+
+We don't even need that much iterations to get a good result. The depth needed to
+get a good result depends on the size of the pen and the resolution of the device
+on which the curve is visualized.
+
+\startbuffer[zero]
+drawoptions (withpen pencircle scaled 2pt withcolor .625red) ;
+\stopbuffer
+
+\startbuffer[three]
+for i=1 upto 7 :
+ drawmidpoints (fullcircle
+ xscaled (300pt+i*10pt) yscaled (50pt+i*10pt), i) ;
+endfor ;
+\stopbuffer
+
+\typebuffer[three]
+
+Here we show 7 iterations in one graphic.
+
+\startlinecorrection[blank]
+\processMPbuffer[demo,zero,three]
+\stoplinecorrection
+
+In practice it is not that trivial to determine the depth needed. The next
+example demonstrates how the resolution of the result depends on the length and
+nature of the segment.
+
+\startbuffer[four]
+drawmidpoints (fullsquare
+ xscaled 300pt yscaled 50pt randomized (20pt,10pt), 5) ;
+\stopbuffer
+
+\typebuffer[four]
+
+\startlinecorrection[blank]
+\processMPbuffer[demo,zero,four]
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Inflection, tension and curl}]
+
+\index{inflection}
+\index{tension}
+\index{curl}
+
+The \METAPOST\ manual describes the meaning of \type {...} as \quotation {choose
+an inflection||free path between these points unless the endpoint directions make
+this impossible}. To use the words of David Arnold: a point of inflection is
+where a path switches concavity, from concave up to concave down, for example.
+
+It is surprisingly difficult to find nice examples that demonstrate the
+difference between \type {..} and \type {...}, as it is often \quote {impossible}
+to honour the request for less inflection. We will demonstrate this with a few
+graphics.
+
+In the four figures on the next pages, you will see that \type {...} is not
+really suited for taming wild curves. If you really want to make sure that a
+curve stays within certain bounds, you have to specify it as such using control
+or intermediate points. In the figures that follow, the gray curves draw the
+random path using \type {..} on top of yellow curves that use the \type {...}
+connection. As you can see, in only a few occasions do the yellow \quote
+{inflection} free curves show up.
+
+For those who asked for the code that produces these pictures, we now include it
+here. We use a macro \type {sample} which we define as a usable graphic (nearly
+all examples in this manual are coded in the document source).
+
+\startbuffer
+\startuseMPgraphic{sample}
+def sample (expr rx, ry) =
+ path p, q ; numeric n, m, r, a, b ;
+ color c ; c := \MPcolor{lightgray} ;
+ a := 3mm ; b := 2mm ; r := 2cm ; n := 7 ; m := 5 ;
+ q := unitsquare scaled r xyscaled (n,m) shifted (.5r,.5r) ;
+ draw q withpen pencircle scaled (b/4) withcolor .625yellow;
+ for i=1 upto n : for j=1 upto m :
+ p := (fullcircle scaled r randomized (r/rx,r/ry))
+ shifted ((i,j) scaled r) ;
+ pickup pencircle scaled a ;
+ draw for k=0 upto length(p) :
+ point k of p .. endfor cycle withcolor c ;
+ draw for k=0 upto length(p) :
+ point k of p ... endfor cycle withcolor c ;
+ pickup pencircle scaled b ;
+ draw for k=0 upto length(p) :
+ point k of p .. endfor cycle withcolor .625yellow ;
+ draw for k=0 upto length(p) :
+ point k of p ... endfor cycle withcolor .625white ;
+ for k=0 upto length(p) :
+ draw point k of p withcolor .625red ;
+ endfor ;
+ endfor ; endfor ;
+ setbounds currentpicture to q ;
+enddef ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+As you see, not so much code is needed. The graphics themselves were produced
+with a couple of commands like:
+
+\startbuffer
+\placefigure
+ {Circles with minimized inflection and 25\% randomized points.}
+ {\startMPcode
+ \includeMPgraphic{sample} ; sample(4,4) ;
+ \stopMPcode}
+\stopbuffer
+
+\typebuffer
+
+\startpostponing
+
+\placefigure
+ {Circles with minimized inflection and 25\% randomized points.}
+ {\startMPcode\includeMPgraphic{sample} ; sample(4,4) ; \stopMPcode}
+
+\placefigure
+ {Circles with minimized inflection and 33\% randomized points.}
+ {\startMPcode\includeMPgraphic{sample} ; sample(3,3) ; \stopMPcode}
+
+\page
+
+\placefigure
+ {Circles with minimized inflection and 50\% randomized points.}
+ {\startMPcode\includeMPgraphic{sample} ; sample(2,2) ; \stopMPcode}
+
+\placefigure
+ {Circles with minimized inflection and 100\% randomized points.}
+ {\startMPcode\includeMPgraphic{sample} ; sample(1,1) ; \stopMPcode}
+
+\page
+
+\stoppostponing
+
+The tension specifier can be used to influence the curvature. To quote the
+\METAPOST\ manual once more: \quotation {The tension parameter can be less than
+one, but it must be at least $3/4$}. The following paths are the same:
+
+\starttyping
+z1 .. z2
+z1 .. tension 1 .. z2
+z1 .. tension 1 and 1 .. z2
+\stoptyping
+
+The triple dot command \type {...} is actually a macro that makes the following
+commands equivalent. Both commands will draw identical paths.
+
+\starttyping
+z1 ... z2
+z1 .. tension atleast 1 .. z2
+\stoptyping
+
+The \type {atleast} directive tells \METAPOST\ to do some magic behind the
+screens. Both the $3/4$ and the \type {atleast} lead directly to the question:
+\quotation {What, exactly, is the influence of the tension directive?} We will
+try to demystify the \type {tension} specifier through a sequence of graphics.
+
+\startbuffer
+u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
+def sample (expr p, c) =
+ draw p withpen pencircle scaled 2.5mm withcolor white ;
+ draw p withpen pencircle scaled 2.0mm withcolor c ;
+enddef ;
+for i=.75 step .05 until 1 :
+ sample (z1 .. tension i .. z2 .. z3, .625red) ;
+endfor ;
+for i=1 step .05 until 2 :
+ sample (z1 .. tension i .. z2 .. z3, .625yellow) ;
+endfor ;
+sample (z1 .. z2 .. z3, .625white) ;
+sample (z1 ... z2 ... z3, .625white) ;
+\stopbuffer
+
+\typebuffer
+
+Indeed values less than .75 give an error message, but large values are okay. As
+you can see, the two gray curves are the same. Here, \type {atleast 1} means~1,
+even if larger values are useful.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\startbuffer
+u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
+def sample (expr p, c) =
+ draw p withpen pencircle scaled 2.5mm withcolor white ;
+ draw p withpen pencircle scaled 2.0mm withcolor c ;
+enddef ;
+for i=.75 step .05 until 1 :
+ sample (z1 .. tension i and 2i .. z2 .. z3, .625red) ;
+endfor ;
+for i=1 step .05 until 2 :
+ sample (z1 .. tension i and 2i .. z2 .. z3, .625yellow) ;
+endfor ;
+sample (z1 .. z2 .. z3, .625white) ;
+sample (z1 ... z2 ... z3, .625white) ;
+\stopbuffer
+
+Curves finally are made up out of points, and each point has two control points.
+Since the \type {tension} specifier finally becomes a control point, it is not
+surprising that you may specify two tension values. If we replace the tension in
+the previous example by
+
+\starttyping
+.. tension i and 2i ..
+\stoptyping
+
+we get the following graphic:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\startbuffer
+u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
+def sample (expr p, c) =
+ draw p withpen pencircle scaled 2.5mm withcolor white ;
+ draw p withpen pencircle scaled 2.0mm withcolor c ;
+enddef ;
+for i=.75 step .05 until 1 :
+ sample (z1 .. tension 2i and i .. z2 .. z3, .625red) ;
+endfor ;
+for i=1 step .05 until 2 :
+ sample (z1 .. tension 2i and i .. z2 .. z3, .625yellow) ;
+endfor ;
+sample (z1 .. z2 .. z3, .625white) ;
+sample (z1 ... z2 ... z3, .625white) ;
+\stopbuffer
+
+If we swap both values (\type {.. tension 2i and i ..}) we get:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\startbuffer[a]
+u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
+def sample (expr p, c) =
+ drawpath p withpen pencircle scaled 2.5mm withcolor c ;
+ drawcontrollines p withcolor c ;
+ drawpoints p ;
+ drawcontrolpoints p ;
+enddef ;
+\stopbuffer
+
+We mentioned control points. We will now draw a few extreme tensions and show the
+control points as \METAPOST\ calculates them.
+
+\startbuffer[b]
+sample (z1 .. tension 0.75 .. z2 .. z3, .625red) ;
+sample (z1 .. tension 2.00 .. z2 .. z3, .625yellow) ;
+sample (z1 .. z2 .. z3, .625white) ;
+\stopbuffer
+
+\typebuffer[b]
+
+First we will show the symmetrical tensions.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+The asymetrical tensions are less prominent. We use the following values:
+
+\startbuffer[b]
+sample (z1 .. tension .75 and 10 .. z2 .. z3, .625red) ;
+sample (z1 .. tension 10 and .75 .. z2 .. z3, .625yellow) ;
+sample (z1 .. z2 .. z3, .625white) ;
+\stopbuffer
+
+\typebuffer[b]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+What happens when you use the \METAPOST\ maximum value of \type {infinity}
+instead of 10? Playing with this kind of graphic can be fun, especially when we
+apply a few tricks.
+
+\startbuffer
+def sample (expr p, c) =
+ draw p withpen pencircle scaled 2.5mm withcolor white ;
+ draw p withpen pencircle scaled 2.0mm withcolor c ;
+enddef;
+
+u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
+
+for i=0 step .05 until 1 :
+ sample(z1 .. tension (.75+i) .. z2 .. z3, i[.625red,.625yellow]) ;
+endfor;
+\stopbuffer
+
+\typebuffer
+
+Here we change the color along with the tension. This clearly demonstrates that
+we're dealing with a non linear phenomena.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+We can (misuse) transparant colors to illustrate how the effect becomes less with
+growing tension.
+
+\startbuffer
+def sample (expr p) (text c)=
+ draw p withpen pencircle scaled 2.0mm withcolor c ;
+enddef;
+
+u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
+
+for i=0 step .05 until 1 :
+ sample(z1 .. tension (.75+i) .. z2 .. z3, transparent(1,1-i,.625red)) ;
+endfor;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+A third magic directive is \type {curl}. The curl is attached to a point between
+\type {{ }}, like \type {{curl 2}}. Anything between curly braces is a direction
+specifier, so instead of a \type {curl} you may specify a vector, like \type
+{{(2,3)}}, a pair of numbers, as in \type {{2,3}}, or a direction, like \type
+{{dir 30}}. Because vectors and angles are straightforward, we will focus a bit
+on \type {curl}.
+
+\starttyping
+z0 .. z1 .. z2
+z0 {curl 1} .. z1 .. {curl 1} z2
+\stoptyping
+
+So, a \type {curl} of~1 is the default. When set to~1, the begin and|/|or end
+points are approached. Given the following definitions:
+
+\startbuffer[a]
+u := 1cm ; z1 = (0,0) ; z2 = (2u,4u) ; z3 = (4u,0) ;
+def sample (expr p, c) =
+ draw p withpen pencircle scaled 2.5mm withcolor white ;
+ draw p withpen pencircle scaled 2.0mm withcolor c ;
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+We can draw three curved paths.
+
+\startbuffer[b]
+sample (z1 {curl 0} .. z2 .. {curl 0} z3, .625red) ;
+sample (z1 {curl 2} .. z2 .. {curl 2} z3, .625yellow) ;
+sample (z1 {curl 1} .. z2 .. {curl 1} z3, .625white) ;
+\stopbuffer
+
+\typebuffer[b]
+
+The third (gray) curve is the default situation, so we could have left the \type
+{curl} specifier out of the expression.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+\startbuffer[b]
+sample (z1 {curl 0} .. z2 .. {curl 0} z3, .625red) ;
+sample (z1 {curl infinity} .. z2 .. {curl infinity} z3, .625yellow) ;
+sample (z1 {curl 1} .. z2 .. {curl 1} z3, .625white) ;
+\stopbuffer
+
+The curly specs have a lower bound of zero and no upper bound. When we use
+\METAPOST\ maximum value of \type {infinity} instead of~2, we get:
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+These curves were defined as:
+
+\typebuffer[b]
+
+It may sound strange, but internally \METAPOST\ can handle
+larger values than \type {infinity}.
+
+\startbuffer[b]
+sample (z1 {curl infinity} .. z2 .. {curl infinity} z3, .625red) ;
+sample (z1 {curl 4infinity} .. z2 .. {curl 4infinity} z3, .625yellow) ;
+sample (z1 {curl 8infinity} .. z2 .. {curl 8infinity} z3, .625white) ;
+\stopbuffer
+
+\typebuffer[b]
+
+Although this is quite certainly undefined behaviour, interesting effects can be
+achieved. When you turn off \METAPOST's first stage overflow catcher by setting
+\type {warningcheck} to zero, you can go upto 8 times \type {infinity}, which,
+being some $2^{15}$, is still far from what today's infinity is supposed to be.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+As the built||in \METAPOST\ command \type {..} accepts the \type {curl} and \type
+{tension} directives as described in this section, you will now probably
+understand the following plain \METAPOST\ definitions:
+
+\starttyping
+def -- = {curl 1} .. {curl 1} enddef ;
+def --- = .. tension infinity .. enddef ;
+def ... = .. tension atleast 1 .. enddef ;
+\stoptyping
+
+These definitions also point out why you cannot add directives to the left or
+right side of \type {--}, \type {---} and \type {...}: they are directives
+themselves!
+
+\stopsection
+
+\startsection[title={Transformations}]
+
+\index{transformations}
+
+A \type {transform} is a vector that is used in what is called an affine
+transformation. To quote the \METAPOST\ manual:
+
+\startquotation
+If $p=(p_x,p_y)$ is a pair and $T$ is a transform, then
+\type {p transform T} is a pair of the form:
+
+\startformula
+(t_x + t_{xx} p_x + t_{xy} p_y, t_y + t_{yx} p_x + t_{yy} p_y)
+\stopformula
+
+where the six numeric quantities $(t_x, t_y, t_{xx}, t_{xy},
+t_{yx}, t_{yy})$ determine T.
+\stopquotation
+
+In literature concerning \POSTSCRIPT\ and \PDF\ you will find many references to
+such transformation matrices. A matrix of $(s_x,0,0,s_y,0,0)$ is scaling by $s_x$
+in the horizontal direction and $s_y$ in the vertical direction, while
+$(1,0,t_x,1,0,t_y)$ is a shift over $t_x,t_y$. Of course combinations are also
+possible.
+
+Although these descriptions seem in conflict with each other in the nature and
+order of the transform components in the vectors, the concepts are the same. You
+normally populate transformation matrices using \type {scaled}, \type {shifted},
+\type {rotated}.
+
+\starttyping
+transform t ; t := identity shifted (a,b) rotated c scaled d ;
+path p ; p := fullcircle transformed t ;
+\stoptyping
+
+The previous lines of code are equivalent to:
+
+\starttyping
+path p ; p := fullcircle shifted (a,b) rotated c scaled d ;
+\stoptyping
+
+You always need a starting point, in this case the identity matrix \type
+{identity}: $(0,0,1,0,0,1)$. By the way, in \POSTSCRIPT\ the zero vector is
+$(1,0,0,1,0,0)$. So, unless you want to extract the components using \type
+{xpart}, \type {xypart}, \type {xxpart}, \type {ypart}, \type {yxpart} and|/|or \
+\type {yypart}, you may as well forget about the internal representation.
+
+You can invert a transformation using the \type {inverse} macro, which is defined
+as follows, using an equation:
+
+\starttyping
+vardef inverse primary T =
+ transform T_ ; T_ transformed T = identity ; T_
+enddef ;
+\stoptyping
+
+Using transform matrices makes sense when similar transformations need to be
+applied on many paths, pictures, pens, or other transforms. However, in most
+cases you will use the predefined commands \type {scaled}, \type {shifted}, \type
+{rotated} and alike. We will now demonstrate the most common transformations in a
+text example.
+
+\startbuffer[a]
+draw btex \bfd MetaFun etex ;
+draw boundingbox currentpicture withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer[a]
+
+Before an independent \METAPOST\ run, the \typ {btex ... etex}'s are filtered
+from the file and passed on to \TEX. After that, the \DVI\ file is converted to a
+list of pictures, which is consulted by \METAPOST. This is no longer the case in
+\LUATEX\ where we use \MPLIB, so users don't have to worry about these issues:
+just ignore what is mentioned in the official \METAPOST\ manual.
+
+We can manipulate the pictures representing text like any graphic as well as draw
+it with \type {draw}.
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+We show the transformations in relation to the origin and make the origin stand
+out a bit more by painting it a bit larger in white first.
+
+\startbuffer[c]
+draw origin withpen pencircle scaled 1.5mm withcolor white ;
+draw origin withpen pencircle scaled 1mm withcolor .625red
+\stopbuffer
+
+\typebuffer[c]
+
+The origin is in the lower left corner of the picture.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,c]
+\stoplinecorrection
+
+Because the transformation keywords are proper english, we let the pictures speak
+for themselves.
+
+% shifted
+
+\startbuffer[b]
+currentpicture := currentpicture shifted (0,-1cm) ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% rotated
+
+\startbuffer[b]
+currentpicture := currentpicture rotated 180 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% rotatedaround
+
+\startbuffer[b]
+currentpicture := currentpicture rotatedaround(origin,30) ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% scaled
+
+\startbuffer[b]
+currentpicture := currentpicture scaled 1.75 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% scaled
+
+\startbuffer[b]
+currentpicture := currentpicture scaled -1 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% xscaled
+
+\startbuffer[b]
+currentpicture := currentpicture xscaled 3.50 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% xscaled
+
+\startbuffer[b]
+currentpicture := currentpicture xscaled -1 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% yscaled
+
+\startbuffer[b]
+currentpicture := currentpicture yscaled .5 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% yscaled
+
+\startbuffer[b]
+currentpicture := currentpicture yscaled -1 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% slanted
+
+\startbuffer[b]
+currentpicture := currentpicture slanted .5 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% slanted
+
+\startbuffer[b]
+currentpicture := currentpicture slanted -.5 ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% zscaled
+
+\startbuffer[b]
+currentpicture := currentpicture zscaled (.75,.25) ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% reflectedabout
+
+\startbuffer[b]
+currentpicture := currentpicture
+ reflectedabout(llcorner currentpicture,urcorner currentpicture) ;
+\stopbuffer
+
+\page[preference] \typebuffer[b] \page[no]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+% reverse counterclockwise turningnumber
+
+A path has a certain direction. When the \type {turningnumber} of a path is
+larger than zero, it runs in clockwise direction. The \METAPOST\ primitive \type
+{reverse} changes the direction, while the macro \type {counterclockwise} can be
+used to get a path running in a well defined direction.
+
+\startbuffer
+drawoptions(withpen pencircle scaled 2pt withcolor .625red) ;
+path p ; p := fullcircle scaled 1cm ;
+drawarrow p ;
+drawarrow reverse p shifted (2cm,0) ;
+drawarrow counterclockwise p shifted (4cm,0) ;
+drawarrow counterclockwise reverse p shifted (6cm,0) ;
+drawarrow reverse counterclockwise p shifted (8cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Only this far}]
+
+When you take a close look at the definitions of the Computer Modern Roman fonts,
+defined in the \METAFONT\ book, you will notice a high level of abstraction.
+Instead of hard coded points you will find points defined in terms of \quote
+{being the same as this point} or \quote {touching that point}. In this section
+we will spend some time on this touchy aspect.
+
+\startbuffer[a]
+pickup pencircle scaled 2mm ;
+path p ; p := fullsquare scaled 2cm ;
+draw p withcolor .625white ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+This rectangle is a scaled instance of the predefined \METAFUN\ path \type
+{fullsquare} which is centered around the origin.
+
+\typebuffer[a]
+
+On this path, halfway between two of its corners, we define a point \type {q}:
+
+\startbuffer[b]
+pair q ; q := .5[llcorner p, lrcorner p] ;
+\stopbuffer
+
+\typebuffer[b]
+
+We draw this point in red, using:
+
+\startbuffer[c]
+draw q withcolor .625red ;
+\stopbuffer
+
+\typebuffer[c]
+
+As you can see, this point is drawn on top of the path.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+There are four of those midpoints, and when we connect them, we get:
+
+\startbuffer[c]
+draw q -- q rotated 90 -- q rotated 180 --
+ q rotated 270 -- cycle withcolor .625red ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+Because path \type {p} is centered around the origin, we can simply rotate point
+\type {q} a few times.
+
+\typebuffer[c]
+
+There are situations, where you don't want the red path to be drawn inside
+another path, or more general: where you want points to touch instead of being
+overlayed.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+We can achieve this by defining point \type {q} to be located on top of the
+midpoint.
+
+\startbuffer[b]
+pair q ; q := top .5[llcorner p, lrcorner p] ;
+\stopbuffer
+
+\typebuffer[b]
+
+The predefined macro \type {top} moves the point over the distance similar to the
+current pen width.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+Because we are dealing with two drawing operations, and since the path inside is
+drawn through the center of points, we need to repeat this move in order to draw
+the red path really inside the other one.
+
+\startbuffer[b]
+pair q ; q := top top .5[llcorner p, lrcorner p] ;
+\stopbuffer
+
+\typebuffer[b]
+
+Operations like \type {top} and its relatives \type {bot}, \type {lft} and \type
+{rt} can be applied sequentally.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+We already showed that \type {q} was defined as a series of rotations.
+
+\typebuffer[c]
+
+As an intermezzo we will show an alternative definition of \type {q}. Because
+each point is rotated 90 degrees more, we can define a macro that expands into
+the point and rotates afterwards. Because each consecutive point on the path is
+rotated an additional 90 degrees, we use the \METAPOST\ macro \type {hide} to
+isolate the assignment. The \type {hide} command executes the hidden command and
+afterwards continues as if it were never there. You must not confuse this with
+grouping, since the hidden commands are visible to its surroundings.
+
+\startbuffer[c]
+def qq = q hide(q := q rotated 90) enddef ;
+draw qq -- qq -- qq -- qq -- cycle withcolor .625red ;
+\stopbuffer
+
+\typebuffer[c]
+
+The macro \type {top} uses the characteristics of the current pen to determine
+the displacement. However, for the more complicated pen shapes we need a
+different trick to get an inside path. Let's start by defining an elliptical
+path.
+
+\startbuffer[a]
+pickup pencircle xscaled 3mm yscaled 5mm rotated 30 ;
+path p ; p := fullcircle xscaled 6cm yscaled 3cm ;
+draw p withcolor .625white ;
+\stopbuffer
+
+\typebuffer[a]
+
+We draw this path using a non standard pen. In the \METAFONT\ manual you will
+find methods to draw shapes with similar pens, where the pen is also turning, as
+it does in real calligraphy. Here we stick to a more simple one.
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+We construct the inner path from the points that make up the curve. Watch how we
+use a for loop to compose the new path. When used this way, no semi colon may be
+used to end the loop, since it would isolate the color directive.
+
+\startbuffer[b]
+draw point 0 of p
+ for i=1 upto length(p) : -- point (i) of p endfor
+ withcolor .625red ;
+\stopbuffer
+
+\typebuffer[b]
+
+The points are still located on the original path.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+We can move the points to the inside by shifting them over the penwidth in the
+direction perpendicular to the point. Because we use this transformation more
+than once, we wrap it into a macro. This also keeps the code readable.
+
+\startbuffer[b]
+vardef inside expr pnt of p =
+ (point pnt of p shifted
+ -(penoffset direction pnt of p of currentpen))
+enddef ;
+draw inside 0 of p
+ for i=1 upto length(p) : -- inside i of p endfor
+ withcolor .625red ;
+\stopbuffer
+
+\typebuffer[b]
+
+Whenever you define a pen, \METAPOST\ stores its characteristics in some private
+variables which are used in the \type {top} and alike directives. The \type
+{penoffset} is a built in primitive and is defined as the \quotation {point on
+the pen furthest to the right of the given direction}. Deep down in \METAPOST\
+pens are actually simple paths and therefore \METAPOST\ has a notion of a point
+on the penpath. In the \METAFONT\ book and \METAPOST\ manual you can find in
+depth discussions on pens.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+We're still not there. Like in a previous example, we need to shift over twice
+the pen width. To get good results, we should determine the width of the pen at
+that particular point, which is not trivial. The more general solution, which
+permits us to specify the amount of shifting, is as follows.
+
+\startbuffer[b]
+vardef penpoint expr pnt of p =
+ save n, d ; numeric n, d ;
+ (n,d) = if pair pnt : pnt else : (pnt,1) fi ;
+ (point n of p shifted
+ ((penoffset direction n of p of currentpen) scaled d))
+enddef ;
+\stopbuffer
+
+\typebuffer[b]
+
+When the point specification is extended with a distance, in which case we have a
+pair expression, the point and distance are derived from this specification.
+First we demonstrate the simple case:
+
+\startbuffer[c]
+draw penpoint 0 of p
+ for i=1 upto length(p)-1 : .. penpoint i of p endfor .. cycle
+ withcolor .625red ;
+\stopbuffer
+
+\typebuffer[c]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+In the next graphic, we draw both an inner and and outer path.
+
+\startbuffer[c]
+draw penpoint (0,-2) of p
+ for i=1 upto length(p)-1 : .. penpoint (i,-2) of p endfor .. cycle
+ withcolor .625red ;
+draw penpoint (0,+2) of p
+ for i=1 upto length(p)-1 : .. penpoint (i,+2) of p endfor .. cycle
+ withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer[c]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c]
+\stoplinecorrection
+
+\startbuffer[a]
+path p, q, r ;
+
+p := fullcircle scaled 3cm ;
+q := p shifted (7cm,0cm) ;
+r := center p -- center q ;
+\stopbuffer
+
+\startbuffer[b]
+pair pr, qr ;
+
+pr := p intersectionpoint r ;
+qr := q intersectionpoint r ;
+
+r := r cutbefore pr cutafter qr ;
+\stopbuffer
+
+\startbuffer[c]
+r := r cutbefore (point 5pt on r) ;
+r := r cutafter (point -5pt on r) ;
+\stopbuffer
+
+\startbuffer[cc]
+r := r cutends 5pt ;
+\stopbuffer
+
+\startbuffer[d]
+draw p withpen pencircle scaled 10pt withcolor .625red ;
+draw q withpen pencircle scaled 10pt withcolor .625yellow ;
+draw r withpen pencircle scaled 20pt withcolor .625white ;
+\stopbuffer
+
+\startbuffer[dd]
+draw r withpen pencircle scaled 20pt withcolor .625white ;
+draw p withpen pencircle scaled 10pt withcolor .625red ;
+draw q withpen pencircle scaled 10pt withcolor .625yellow ;
+\stopbuffer
+
+Another case when \type {top} and friends cannot be applied in a general way is
+the following. Consider the three paths:
+
+\typebuffer[a]
+
+We draw these paths with:
+
+\typebuffer[d]
+
+The line is drawn from center to center and since the line has a non zero width
+and a round line cap, it extends beyond this point.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,d]
+\stoplinecorrection
+
+If we want the line to stop at the circular paths, we can cut off the pieces that
+extend beyond those paths.
+
+\typebuffer[b]
+
+This time we get:
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,d]
+\stoplinecorrection
+
+Due to the thicker line width used when drawing the straight line, part of that
+line is still visible inside the circles. So, we need to clip off a bit more.
+
+\typebuffer[c]
+
+The \type {point ... on} operation is a \METAFUN\ macro that takes a dimension.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d]
+\stoplinecorrection
+
+In order to save you some typing, \METAFUN\ provides a macro \type {cutends} that
+does the same job:
+
+\typebuffer[cc]
+
+This time we draw the path in a different order:
+
+\typebuffer[dd]
+
+That way we hide the still remaining overlapping part of the line.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,cc,dd]
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Directions}]
+
+\index{directions}
+
+Quite often you have to tell \METAPOST\ in what direction a line should be drawn.
+A direction is specified as a vector. There are four predefined vectors: \type
+{up}, \type {down}, \type {left}, \type {right}. These are defined as follows:
+
+\starttyping
+pair up, down, left, right ;
+up = -down = (0,1) ; right = -left = (1,0) ;
+\stoptyping
+
+We can use these predefined pairs as specifications and in calculations.
+
+\startbuffer
+dotlabel.top("up" , up * 1cm) ;
+dotlabel.bot("down" , down * 1cm) ;
+dotlabel.lft("left" , left * 1cm) ;
+dotlabel.rt ("right", right * 1cm) ;
+
+drawoptions (withpen pencircle scaled .25mm withcolor .625 red) ;
+
+drawarrow origin -- up * 1cm ;
+drawarrow origin -- down * 1cm ;
+drawarrow origin -- left * 1cm ;
+drawarrow origin -- right * 1cm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+This graphic can also be defined in a more efficient (but probably more cryptic)
+way. The next definition demonstrates a few nice tricks. Instead of looping over
+the four directions, we loop over their names. Inside the loop we convert these
+names, or strings, into a pair by scanning the string using \type {scantokens}.
+The \type {freedotlabel} macro is part of \METAFUN\ and takes three arguments: a
+label string (or alternatively a picture), a point (location), and the \quote
+{center of gravity}. The label is positioned in the direction opposite to this
+center of gravity.
+
+\startbuffer
+pair destination ;
+for whereto = "up", "down", "left", "right" :
+ destination := scantokens(whereto) * 1cm ;
+ freedotlabel(whereto, destination, origin) ;
+ drawarrow origin -- destination
+ withpen pencircle scaled .25mm withcolor .625 red ;
+endfor ;
+\stopbuffer
+
+\typebuffer
+
+So, in this code fragment, we use the string as string and (by means of \type
+{scantokens}) as a point or vector.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The previous definition is a stepping stone to the next one. This time we don't
+use points, but the \type {dir} command. This command converts an angle into an
+unitvector.
+
+\startbuffer
+pair destination ;
+for whereto = 0 step 30 until 330 :
+ destination := dir(whereto) * 1.5cm ;
+ freedotlabel(decimal whereto, destination, origin) ;
+ drawarrow origin -- destination
+ withpen pencircle scaled .25mm withcolor .625 red ;
+endfor ;
+\stopbuffer
+
+\typebuffer
+
+In \METAPOST\ the angles go counter clockwise, which is not that illogical if you
+look at it from the point of view of vector algebra.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Analyzing pictures}]
+
+\index{pictures+analyzing}
+
+{\em Unless you really want to know all details, you can safely skip this
+section. The \METAPOST\ features discussed here are mainly of importance when you
+write (advanced) macros.}
+
+% Later we will discuss in detail how you can use either \METAPOST\ or \TEX\ to
+% typeset text (\in {section} [sec:text] and \in {chapter} [sec:typesetting]), so
+% here we limit our exploration to a quick introduction. The most direct way of
+% processing text in \METAPOST\ is using the \type {infont} operator.
+%
+% \startbuffer[mp]
+% draw "this string will become a sequence of glyphs (MP)"
+% infont defaultfont scaled defaultscale ;
+% \stopbuffer
+%
+% \typebuffer[mp]
+%
+% The text between \type {"} is passed to \TEX, and the resulting \DVI\ will be
+% converted into a picture with textual components. So, we get:
+%
+% \startlinecorrection[blank]
+% \midaligned{\processMPbuffer[mp]}
+% \stoplinecorrection
+%
+% The same string typeset by \TEX\ shows up as:
+%
+% \blank
+% \midaligned{this string will become a sequence of glyphs (\TeX)}
+% \blank
+%
+% The following \METAPOST\ features are not covered by the \METAPOST\ manual, but
+% most of them are discussed in the appendix of the \type {graph} package written
+% by John Hobby.
+%
+%It is possible to disassemble a picture by means of a special for loop using the
+%\type {within} specifier. The following code walks over a picture and draws the
+%components with their bounding boxes.
+%
+% \startbuffer[show]
+% for i within currentpicture :
+% draw boundingbox i withcolor .625yellow ;
+% endfor ;
+% \stopbuffer
+%
+% \typebuffer[show]
+%
+% We can use the disassemble loop feature to look into the previously shown
+% example text.
+%
+% \startlinecorrection[blank]
+% \processMPbuffer[mp,show]
+% \stoplinecorrection
+%
+% The second line is typeset by \TEX. The resulting \DVI\ code is converted into a
+% series of pictures, which \METAPOST\ pastes into one picture. You may also notice
+% that in the set of pictures that originate in \TEX, the space is replaced by a
+% shift (this is because \TEX\ knows no space).
+%
+% An interesting aspect of this \quote {loop over a picture} feature, is that it
+% can provide insight in how \TEX\ is composing a paragraph.
+%
+% \startbuffer
+% draw btex \framed[width=fit,align=middle]{\input tufte \relax} etex ;
+% for i within currentpicture :
+% draw boundingbox i withpen pencircle scaled .2pt withcolor .625yellow ;
+% endfor ;
+% \stopbuffer
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% You may also notice, that rules produced by \TEX\ are converted to straight line
+% segments. Because the line extends 50\% of its linewidth beyond a point, there is
+% a slight overshoot. This picture was defined in a few lines:
+%
+% \typebuffer
+%
+% If we use a Times Roman instead of a Palatino, we get quite
+% different results.
+%
+% \startlinecorrection[blank]
+% \startMPenvironment
+% %\let\fontclass\empty
+% \usetypescript[times][texnansi]
+% \switchtobodyfont[times,10pt]
+% \stopMPenvironment
+% \processMPbuffer
+% \stoplinecorrection
+%
+% In \CONTEXT, you can easily change the body font for
+% \METAPOST\ graphics with directives like:
+%
+% \starttyping
+% \startMPenvironment
+% \usetypescript[times][texnansi]
+% \switchtobodyfont[times,10pt]
+% \stopMPenvironment
+% \stoptyping
+%
+% This font has far less kerning. Even more interesting is the Lucida Bright
+% Handwriting font, which is defined in such a way that no kerning is needed at
+% all.
+%
+% \startlinecorrection[blank]
+% \resetMPenvironment
+% \startMPenvironment
+% %\let\fontclass\empty
+% \usetypescript[lucida][texnansi]
+% \switchtobodyfont[lucida,hw,10pt]
+% \stopMPenvironment
+% \processMPbuffer
+% \stoplinecorrection
+%
+% You can ask for the number of components with \type {length}. A component can be
+% a stroked or filled path, or a text resulting from an \type {infont} operation.
+% If the (last) path is a clip path, or when the whole picture has a forced
+% boundingbox, the picture is treated as a whole. We will demonstrate this later.
+
+We can decompose \METAPOST\ pictures using a \type {within} loop. You may wonder
+if such a \type {within} loop construct has any real application, and as you can
+expect, it has. In \in {section} [sec:color circles] a macro is defined that
+draws a colored circle. If you want the inverted alternative, you can pass the
+inverted color specification, but wouldn't it be more convenient if there was an
+operator that did this for you automatically? Unfortunately there isn't one so we
+have to define one ourselves in a macro.
+
+\startbuffer
+colorcircle(4cm,(.4,.6,.8),(.4,.8,.6),(.6,.4,.8)) ;
+addto currentpicture also inverted currentpicture shifted (5cm,0) ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+These circles were drawn using:
+
+\typebuffer
+
+When we \type {draw} a path, or stroke a path, as it is called officially, we
+actually perform an addition:
+
+\starttyping
+addto currentpicture doublepath somepath
+\stoptyping
+
+The \type {fill} command is actually:
+
+\starttyping
+addto currentpicture contour somepath
+\stoptyping
+
+We will need both \type {doublepath} and \type {contour} operations in the
+definition of \type {inverted}.
+
+When \METAPOST\ has digested a path into a picture, it keeps track of some
+characteristics. We can ask for them using \type {part...} operators. The
+following operators can be applied to a transform vector (one of \METAPOST's data
+types), but also to a picture. Say that we have drawn a circle:
+
+\startbuffer[a]
+draw fullcircle
+ xscaled 3cm yscaled 2cm
+ dashed dashpattern(on 3mm off 3mm)
+ withpen pencircle scaled 1mm
+ withcolor .625red ;
+picture p ; p := currentpicture ;
+\stopbuffer
+
+\typebuffer[a]
+
+This circle looks like:
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+We can now ask for some of the characteristics of \type {currentpicture}, like
+its color. We could write the values to the log file, but it is more convenient
+to put them on paper.
+
+\startbuffer[b]
+label.rt("redpart: " & decimal redpart p, (4cm,+.5cm)) ;
+label.rt("greenpart: " & decimal greenpart p, (4cm, 0cm)) ;
+label.rt("bluepart: " & decimal bluepart p, (4cm,-.5cm)) ;
+\stopbuffer
+
+\typebuffer[b]
+
+Here the \type {&} glues strings together, while the decimal operator converts a
+number into a string.
+
+The result has no typographic beauty |<|keep in mind that here we use \METAPOST\
+to typeset the text|>|but the result serves its purpose.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+We can also ask for the path itself (\type {pathpart}), the pen (\type {penpart})
+and the dashpattern (\type {dashpart}), but these can only be assigned to
+variables of the corresponding type.
+
+A path can be stroked or filled, in which case it is a cyclic path. It can have a
+non natural bounding box, be a clip path, consist of line segments or contain
+text. All these characteristics can be tested.
+
+\startbuffer[b]
+label.rt("filled: " & condition filled p, (4cm,+1.25cm)) ;
+label.rt("stroked: " & condition stroked p, (4cm,+0.75cm)) ;
+label.rt("textual: " & condition textual p, (4cm,+0.25cm)) ;
+label.rt("clipped: " & condition clipped p, (4cm,-0.25cm)) ;
+label.rt("bounded: " & condition bounded p, (4cm,-0.75cm)) ;
+label.rt("cycle: " & condition cycle pathpart p, (4cm,-1.25cm)) ;
+\stopbuffer
+
+\typebuffer[b]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+In this code snippet, \type {condition} is a macro that takes care of translating
+a boolean value into a string (like \type {decimal} does with a numeric value).
+
+\starttyping
+def condition primary b =
+ if b : "true" else : "false" fi
+enddef ;
+\stoptyping
+
+Clip paths and bounding boxes are kind of special in the sense that they can
+obscure components. The following examples demonstrate this. In case of a clip
+path or bounding box, the \type {pathpart} operator returns this path. In any
+case that asking for a value does not make sense |<|a clipping path for instance
+has no color|>| a zero (null) value is returned.
+
+\startbuffer[b]
+n := 1 ;
+for i within currentpicture : n := n + 1 ;
+ label("n: " & decimal n & " / " &
+ "length: " & decimal length i & " / " &
+ "stroked: " & condition stroked i & " / " &
+ "clipped: " & condition clipped i & " / " &
+ "bounded: " & condition bounded i , (0,-n*.5cm)) ;
+endfor ;
+\stopbuffer
+
+\startbuffer[c]
+\startlinecorrection[blank]
+\framed[offset=overlay,frame=off,background=color,backgroundcolor=gray]{\processMPbuffer[a,b]}
+\stoplinecorrection
+\stopbuffer
+
+\startbuffer[a]
+draw fullcircle withpen pencircle scaled 6mm ;
+clip currentpicture to fullcircle ;
+setbounds currentpicture to fullcircle ;
+\stopbuffer
+
+\typebuffer[a] \getbuffer[c]
+
+\startbuffer[a]
+draw fullcircle withpen pencircle scaled 6mm ;
+setbounds currentpicture to fullcircle ;
+clip currentpicture to fullcircle ;
+\stopbuffer
+
+\typebuffer[a] \getbuffer[c]
+
+\startbuffer[a]
+clip currentpicture to fullcircle ;
+draw fullcircle withpen pencircle scaled 6mm ;
+setbounds currentpicture to fullcircle ;
+\stopbuffer
+
+\typebuffer[a] \getbuffer[c]
+
+\startbuffer[a]
+clip currentpicture to fullcircle ;
+setbounds currentpicture to fullcircle ;
+draw fullcircle withpen pencircle scaled 6mm ;
+\stopbuffer
+
+\typebuffer[a] \getbuffer[c]
+
+\startbuffer[a]
+setbounds currentpicture to fullcircle ;
+clip currentpicture to fullcircle ;
+draw fullcircle withpen pencircle scaled 6mm ;
+\stopbuffer
+
+\typebuffer[a] \getbuffer[c]
+
+\startbuffer[a]
+setbounds currentpicture to fullcircle ;
+draw fullcircle withpen pencircle scaled 6mm ;
+clip currentpicture to fullcircle ;
+\stopbuffer
+
+\typebuffer[a] \getbuffer[c]
+
+The description lines were generated by the following loop:
+
+\typebuffer[b]
+
+% % The following is no longer valid in MetaFun:
+%
+% If we have a textual picture, we can also ask for the text and font. Take the
+% following picture:
+%
+% \startbuffer[a]
+% picture p ;
+% p := "MetaFun" normalinfont "rm-lmr10" scaled 2 rotated 30 slanted .5 ;
+% p := p shifted (0,-ypart center p) ;
+% currentpicture := p ;
+% \stopbuffer
+%
+% \typebuffer[a]
+%
+% Here we can ask for:
+%
+% \startbuffer[b]
+% label.rt("textpart: " & textpart p, (4cm,+0.25cm)) ;
+% label.rt("fontpart: " & fontpart p, (4cm,-0.25cm)) ;
+% \stopbuffer
+%
+% \typebuffer[b]
+%
+% and get:
+%
+% \startlinecorrection[blank]
+% \processMPbuffer[a,b]
+% \stoplinecorrection
+%
+% We use \type {normalinfont} instead of \type {infont} because in \METAFUN\ this
+% operator is overloaded and follows another route for including text.
+%
+% If we're dealing with a path, the transformations have ended up in the path
+% specification. If we have a text picture, we can explicitly ask for the transform
+% components.
+%
+% \startbuffer[b]
+% label.rt("xpart: " & decimal xpart p, (4cm,+1.25cm)) ;
+% label.rt("ypart: " & decimal ypart p, (4cm,+0.75cm)) ;
+% label.rt("xxpart: " & decimal xxpart p, (4cm,+0.25cm)) ;
+% label.rt("xypart: " & decimal xypart p, (4cm,-0.25cm)) ;
+% label.rt("yxpart: " & decimal yxpart p, (4cm,-0.75cm)) ;
+% label.rt("yypart: " & decimal yypart p, (4cm,-1.25cm)) ;
+% \stopbuffer
+%
+% \typebuffer[b]
+%
+% \startlinecorrection[blank]
+% \processMPbuffer[a,b]
+% \stoplinecorrection
+%
+% We will now define the \type {inverted} macro using these primitives. Because we
+% have to return a picture, we cannot use \type {draw} and \type {fill} but need to
+% use the low level operators. Because a picture can consist of more than one path,
+% we need a temporary picture \type {pp}.
+%
+% \starttyping
+% vardef inverted expr p =
+% save pp ; picture pp ; pp := nullpicture ;
+% for i within p :
+% addto pp
+% if stroked i or filled i :
+% if filled i : contour else : doublepath fi pathpart i
+% dashed dashpart i withpen penpart i
+% else :
+% also i
+% fi
+% withcolor white-(redpart i, greenpart i, bluepart i) ;
+% endfor ;
+% pp
+% enddef ;
+% \stoptyping
+%
+% We probably need to handle a few more border cases, but for general purposes,
+% this macro works as expected.
+
+The textual capabilities built in \METAPOST\ are rather limited but in \CONTEXT\
+we have overloaded the relevant operators. There we hook into the normal font
+handler. The native text related operators are:
+
+\starttyping
+draw "MetaFun" infont "somefont" scaled 2 rotated 30 slanted .5 ;
+draw btex MetaFun etex scaled 2 rotated 30 slanted .5 ;
+\stoptyping
+
+The \type {infont} operator directly calls for a font and in stock \METAPOST\ is
+limited to (eight bit) \TYPEONE\ fonts. In \CONTEXT\ you can do this:
+
+\startbuffer[a]
+draw "MetaFun" infont "SerifBold*default" xscaled 5 rotated 5 slanted .5 ;
+\stopbuffer
+
+\typebuffer[a]
+
+The specification is a regular \CONTEXT\ font specification.
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+The \type {btex ... etex} variant in normal \METAPOST\ delegates to \TEX\ and in \MKII\
+indeed we filter them and process them between runs (or at runtime). In \MKIV\ they are
+also handled by \TEX\ but in an even more integrated and immediate way.
+
+The two primitives \type {textpart} and \type {fontpart} that can be used to disassemble
+a picture don't apply to \METAFUN\ as contrary to \METAPOST\ we don't convert the result
+to a picture. In later chapters we will discuss text in more detail.
+
+From the previous examples it may be clear that each picture has some associated
+data stored with it. From the \type {bounded} boolean test we can conclude that
+the bounding box is part of this data. Internally \METAPOST\ keeps track of two
+bounding boxes: the natural one, and the forced one. The forced one is actually a
+component of the picture which applies to all previously added graphics. You can
+calculate the bounding box from the \type {llcorner} and \type {urcorner} or if
+you like \type {ulcorner} and \type {lrcorner} and the \METAFUN\ command \type
+{boundingbox} does so.
+
+The four corners that make up the bounding box are either the natural ones, or
+the ones forced by \type {setbounds}. You can force \METAPOST\ to report the
+natural ones by setting \type {truecorners} to~1. The next example demonstrates
+this feature.
+
+\startbuffer
+pickup pencircle scaled 2mm ; path p, q ;
+draw fullcircle
+ scaled 4cm slanted .5 withcolor .625white ;
+setbounds currentpicture to
+ boundingbox currentpicture enlarged -5mm ;
+interim truecorners := 0 ; p := boundingbox currentpicture ;
+interim truecorners := 1 ; q := boundingbox currentpicture ;
+pickup pencircle scaled 1mm ;
+draw p withcolor .625red ;
+draw q withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+We use \type {interim} because \type {truecorners} is an internal \METAPOST\
+variable.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+% % we already redefined infont so it's kind of dangerous to provide this example
+%
+% Since \METAPOST\ can handle fonts (it can even generate font metric files) it is
+% no surprise that we can also ask for the natural size of a font. For this we use
+% \type {fontsize}. However, you should beware of the fact that the size reported
+% is in base points. Since this is \METAPOST's native unit, this is no problem in
+% calculations, but it may look confusing when you \type {show} this size on your
+% terminal and get less that 10 reported for a \type {cmr10} font.
+%
+% \starttyping
+% show fontsize "cmr10" ;
+% \stoptyping
+%
+% In order to demonstrate that \type {fontsize} is useful, we extend the \type
+% {infont} command. In the process we show a few macro definition tricks. What we
+% want is a \TEX\ like specification of a font size:
+%
+% \startbuffer[txt]
+% draw "MetaFun" infont defaultfont at 20pt ;
+% \stopbuffer
+%
+% \typebuffer[txt]
+%
+% We can store the current meaning of a primitive or macro in a new macro. We do so
+% with \type {infont}:
+%
+% \startbuffer[a]
+% let normalinfont = infont ;
+% \stopbuffer
+%
+% \typebuffer[a]
+%
+% We can only know the size if we know the name of the font, so we have to redefine
+% \type {infont} to pick up this name.
+%
+% \startbuffer[b]
+% numeric lastfontsize ; lastfontsize = fontsize defaultfont ;
+% \stopbuffer
+%
+% \startbuffer[c]
+% primarydef infont primary name = % patched: def should work too
+% hide(lastfontsize := fontsize name)
+% normalinfont name
+% enddef ;
+% \stopbuffer
+%
+% \typebuffer[c]
+%
+% Because we are replacing an operator, and since \METAPOST\ expects one, we have
+% to use \type {def} instead of \type {vardef} (which is actually a kind of
+% variable). For the same reason, we have to pick up a \type {primary}. If we would
+% use a \typ {expr name}, we would end up in an unwanted look ahead. The \type
+% {hide} macro hides the assignment and makes this macro behave like a \type
+% {vardef} with respect to hiding expressions. We may not put a semi colon after
+% the \type {)} because it would stop \METAPOST\ from reading on, and thereby
+% invoke an error message.
+%
+% We can now define \type {at}. This macro picks up an expression (which can be
+% more than just a number) and return a scale transform that normalizes the given
+% size to the design size.
+%
+% \startbuffer[d]
+% def at expr size =
+% scaled (size/lastfontsize)
+% enddef ;
+% \stopbuffer
+%
+% \typebuffer[d]
+%
+% Because this macro is defined global, and therefore can be used apart from \type
+% {infont}, we predefine the size:
+%
+% \typebuffer[b]
+%
+% When defined this way \type {at} a comfortable 20 points, the string \type
+% {MetaFun} comes out as follows:
+%
+% \startlinecorrection[blank]
+% \processMPbuffer[a,b,c,d,txt]
+% \stoplinecorrection
+
+\stopsection
+
+\startsection[title={Filling}]
+
+\index{filling}
+\index{reversing}
+
+In most cases a path ends up being drawn or filled. When filling a path, it
+doesn't matter in what direction the path runs, as long as it's closed you're
+fine. You can however change the direction any time along the path. Here is an
+example of what happens when you fill a path that is partially reversed.
+
+\startbuffer
+fill fullsquare rotated 45 scaled 2cm
+ withcolor .625 red ;
+fill fullcircle scaled 2cm -- reverse fullcircle scaled 1cm -- cycle
+ withcolor .625 yellow ;
+\stopbuffer
+
+\typebuffer
+
+You'll notice that the inner circle is not filled:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Now watch the following:
+
+\startbuffer
+fill
+ fullsquare rotated 45 scaled 2cm
+ -- fullcircle scaled 2cm
+ -- cycle
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+This results in:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Compare this with:
+
+\startbuffer
+fill
+ fullsquare rotated 45 scaled 2cm
+ -- reverse fullcircle scaled 2cm -- cycle
+ -- cycle
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+giving:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The normal filling happens according to the non||zero winding rule. An alternative is the
+odd||even rule. There we don't need the reverse trick:
+
+\startbuffer
+eofill fullsquare rotated 45 scaled 2cm
+ -- fullcircle scaled 2cm -- cycle
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+The \type {eofill} is a \METAFUN\ extension. Hopefully the next explains a bit
+how this works (you can find explanations zon the internet).
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\startuseMPgraphic{demo}
+ def DrawIt(text how) =
+ path p ; p := ((0,0) .. (1,0) .. (1,1) .. (0,1) .. (1,0) .. (2,1) .. cycle) scaled 2cm ;
+ how p withcolor .625 yellow ;
+ draw p withcolor .625 red ;
+ for i=0 step 0.05 until 1 :
+ fill arrowheadonpath (p,i)
+ withcolor .625 red ;
+ endfor ;
+ draw (0.5,0.5) scaled 2cm withpen pencircle scaled .5mm withcolor .375 white ;
+ draw ((0.5,0.5) scaled 2cm -- llcorner p) withpen pencircle scaled .5mm withcolor .375 white ;
+ draw (1.5,1.5) scaled 2cm withpen pencircle scaled .5mm withcolor .375 white ;
+ draw ((1.5,1.5) scaled 2cm -- urcorner p) withpen pencircle scaled .5mm withcolor .375 white ;
+ enddef ;
+\stopuseMPgraphic
+
+\startlinecorrection[blank]
+ \startcombination[distance=4em]
+ {\startMPcode \includeMPgraphic{demo} DrawIt(eofill) \stopMPcode} {\type{eofill}}
+ {\startMPcode \includeMPgraphic{demo} DrawIt(fill) \stopMPcode} {\type{fill}}
+ \stopcombination
+\stoplinecorrection
+
+In the case of a normal fill, the non||zero winding rule is applied: a winding
+number is calculated by subtracting 1 each time the line (from inside an area to
+someplace outside) is crossed clockwise while 1 is added each time we cross
+anti||clockwise. When the total is non zero the area is filled. Here we run in one
+direction and therefore we always get a fill. In the previous example where we
+used a reverse, an anti||clockwise crossing was nilled by a clockwise one.
+
+The leftmost shape uses \type {eofill} and therefore the odd||even rule gets
+applied. This time we follow the line and when it gets crossed en even number of
+times the area will not be filled.
+
+A glyph is often constructed from more than one path and eventually the shape is
+filled with an odd||even fill (\type {eofill}) operation. Take the following
+sequence:
+
+\startbuffer
+pickup pencircle scaled 1mm ;
+draw fullsquare scaled 2cm ;
+draw fullsquare scaled 2cm shifted (1cm,0) ;
+draw fullsquare scaled 2cm shifted (0,1cm) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+We can use a sequence of \type {nofill} ending with a \type {eofill} to create
+a combined shape. This is not done in \METAPOST\ but in the backend.
+
+\startbuffer
+nofill fullsquare scaled 2cm ;
+nofill fullsquare scaled 2cm shifted (1cm,0) ;
+eofill fullsquare scaled 2cm shifted (0,1cm) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+As this is used for glyphs, we demonstrate this mechanism with a simple \type {O}
+shape:
+
+\startbuffer
+nofill fullcircle xyscaled (2cm,3cm) ;
+eofill fullcircle xyscaled (1cm,2cm) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Another backend related feature is \type {fillup}. This is just a combination
+of a fill and a draw in one go. It can save some bytes in the output file.
+
+\startbuffer
+draw image (
+ pickup pencircle scaled 5mm ;
+ fill fullsquare scaled 2cm ;
+ draw fullsquare scaled 2cm ;
+ fillup fullsquare scaled 2cm shifted (4cm,0) ;
+) withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Pitfalls}]
+
+When writing macros, you need to be careful in what
+operations apply to what object. There is for instance a
+difference between the following code:
+
+\startbuffer
+pickup pencircle scaled 2pt ;
+draw (0,0)--(0,1)--(1,1) scaled 1cm withcolor .625 red ;
+draw ((0,0)--(0,1)--(1,1)) scaled 2cm withcolor .625 yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The \type {scaled} operates on the previous expression which in the first case is
+the point \type {(1,1)} and in the second case the whole path.
+
+\startbuffer
+pickup pencircle scaled 2pt ;
+draw (0,0)--(0,1)--(1,1)--cycle scaled 1cm withcolor .625 red ;
+draw ((0,0)--(0,1)--(1,1)--cycle) scaled 2cm withcolor .625 yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Here the last element in the first case is not the cycle, and the next
+alternative does not help us much in discovering what is going on. (Well, at
+least something {\em is} going on, because the result seems to have some
+dimensions.)
+
+\startbuffer
+pickup pencircle scaled 2pt ;
+draw (1,1)--cycle scaled 1cm withcolor .625 red ;
+draw ((1,1)--cycle) scaled 1cm withcolor .625 yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The next lines demonstrate that we're dealing with the dark sides of \METAPOST,
+and from that we may conclude that in case of doubt it's best to add parenthesis
+when such fuzzy situations threaten to occur.
+
+\startbuffer
+pickup pencircle scaled 2pt ;
+draw (0,1)--(1,1)--cycle scaled 1cm withcolor .625 red ;
+draw ((0,1)--(1,1)--cycle) scaled 1cm withcolor .625 yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+There are more cases where the result may surprise you. Take the following code:
+
+\startbuffer
+drawarrow ((0,0)--(10,0))
+ withpen pencircle scaled 2pt
+ withcolor red randomized (.4,.9) ;
+currentpicture := currentpicture scaled 8 ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The arrow is made up out of two pieces and each piece gets a different shade of
+red. This is because the attributes are collected and applied to each of the
+components that make up the arrow. Because for each component the attribute code
+is expanded again, we get two random colors. One way around this is to apply the
+color afterwards.
+
+\startbuffer
+draw
+ image (drawarrow ((0,0)--(10,0)) withpen pencircle scaled 2pt)
+ scaled 8 withcolor red randomized (.4,.9) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Here the \type {image} macro creates a picture and as you can see, this provides
+a way to draw within a draw operation.
+
+Once you see the benefits of \type {image}, you will use it frequently. Another
+handy (at first sight strange) macro is \type {hide}. You can use this in
+situations where you don't want code to interfere.
+
+\starttyping
+def mydraw text t =
+ boolean error ; error := false ;
+ def withpencil expr p = hide (error := true) enddef ;
+ draw t ;
+ if error : message "pencils are not supported here" fi ;
+enddef ;
+mydraw fullcircle scaled 10cm withpencil sharp ;
+\stoptyping
+
+Here, setting the boolean normally interferes with the draw operation, but by
+hiding the assignment, this code becomes valid. This code will bring the message
+to your terminal and log file.
+
+Once you start using expressions you have a good chance of encountering messages
+with regard to redundant expressions. The following code is for instance a
+recipe for problems:
+
+\starttyping
+z1 = (1,0) ; z1 = (2,0) ;
+\stoptyping
+
+Changing the \type {=} into \type {:=} helps, but this may not be what you want.
+
+Because the \type {z}||variables are used frequently, they are reset each figure.
+You can also reset them yourself, using the \type {clearxy} macro. The \METAFUN\
+version clears all \type {z}||variables, unless you explictly specify what
+variables to reset. \footnote {This version resulted from a discussion on the
+\METAFONT\ discussion list and is due to Bogus\l{}aw Jackowski.} If you want to
+play with this macro, see what happens when you run the following code:
+
+\starttyping
+show x0 ; z0 = (10,10) ;
+show x0 ; x0 := whatever ; y0 := whatever ;
+show x0 ; z0 = (20,20) ;
+show x0 ; clearxy 0 ;
+show x0 ; z0 = (30,30) ;
+\stoptyping
+
+So, the following calls are all legal:
+
+\starttyping
+clearxy ; clearxy 1 ; clearxy 1, 8, 10 ;
+\stoptyping
+
+Keep in mind that for each figure a full clear is done anyway. You should not
+confuse this command with \type {clearit}, which clears \type {currentpicture}.
+
+\stopsection
+
+\startsection[title={\TeX\ versus \MetaPost}]
+
+If you are defining your own \TEX\ and \METAPOST\ macros, you will notice that
+there are a couple of essential differences between the two macro languages. In
+\TEX\ the following code is invalid. \footnote {In \ETEX\ the calculation can be
+done in less lines using a \type {\numexpr}.}
+
+\starttyping
+\def\fancyplied#1%
+ {\ifnum#1=0
+ \message{zero argument}%
+ \fi
+ \count0=#1 \multiply \count0 by \count0
+ \count2=#1 \multiply \count2 by 2
+ \count4=#1 \divide \count4 by 2
+ \advance \count0 by \count2
+ \advance \count0 by \count4
+ \count4 }
+\hskip \fancyplied{3} pt
+\stoptyping
+
+This is because \TEX\ is very strict in what tokens it expects next. In
+\METAPOST\ however, you can use \type {vardef}'d macros to hide nasty
+intermediate calculations.
+
+\starttyping
+vardef fancyplied expr x =
+ if x=0 : message "x is zero" ; (x*x+2x+x/2)
+enddef ;
+a := a shifted (fancyplied 3pt,0) ;
+\stoptyping
+
+Hiding intermediate calculations and manipulations is a very strong point of
+\METAPOST.
+
+Another important difference between both languages is the way grouping is
+implemented. Because \TEX\ is dealing with a flow of information, strong grouping
+is a must and therefore part of the language. Occasionally you run into
+situations where you wished that you could reach over a group (for instance in
+order to pass a value).
+
+In \METAPOST\ grouping behaves quite different. First of all, it provides the
+mechanism that hides processing from the current flow. The previously mentioned
+\type {vardef} is implicitly grouped. Contrary to \TEX, in \METAPOST\ all
+assignments are global by default, even in a group. If you assign a variable
+inside a group it is persistent unless you first save the variable (or macro)
+using the \type {save} operator.
+
+So, in the next code snippet, the value of \type {\value} inside the box is {\em
+no} but after the box is typeset, it will be {\em yes} again.
+
+\starttyping
+\def\value{yes} \hbox{\def\value{no}\value} \value
+\stoptyping
+
+To make a value local in \METAPOST, the following code is needed.
+
+\starttyping
+string value ; value := "yes" ;
+def intermezzo
+ begingroup ;
+ save value ; string value ; value := "no" ;
+ endgroup ;
+enddef ;
+\stoptyping
+
+Once you start writing your own \METAPOST\ macros, you will appreciate this
+\quote {always global} behaviour. As with other differences between the two
+languages, they make sense if you look at what the programs are supposed to do.
+
+\stopsection
+
+\startsection[title={Internals and Interims}]
+
+\index{internals}
+\index{interims}
+
+Related to grouping is the internal numeric datatype. When numeric variables are
+defined as interim, you can quickly overload them inside a group.
+
+\starttyping
+newinternal mynumber ; mynumber := 1 ;
+
+begingroup ; ... interim mynumber := 0 ; ... ; endgroup ;
+\stoptyping
+
+You can only \type {interim} a variable if it is already defined using \type
+{newinternal}.
+
+Among the \METAPOST\ macros is one called \type {drawdot}. This macro is kind of
+redundant because, at least at first sight, you can use draw to achieve the same
+result. There is however a very subtle difference: a dot is slightly larger than
+a drawn point. We guess that it's about the device pixel, so you may not even
+notice it. It may even be due to differences in accuracy of the methods to render
+them.
+
+\startbuffer
+pickup pencircle scaled 50pt ;
+drawdot origin shifted (-120pt,0) ; draw origin shifted (-60pt,0) ;
+drawdot origin ; draw origin withcolor white ;
+setbounds currentpicture to boundingbox currentpicture enlarged 1pt ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=Named colors]
+
+The \type {withcolor} operator accepts a color expression but in \METAFUN\ it
+also accepts a string indicating a color defined at the \TEX\ end. Most helpers
+that deal with colors are able to deal with named colors as well. Here are some
+examples. First we define a few colors:
+
+\startbuffer
+\definecolor[MyColor1][r=.5]
+\definecolor[MyColor2][g=.5]
+\definecolor[MyColor3][b=.5]
+\definecolor[MyColor4][s=.8]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Here we access them:
+
+\startbuffer
+fill fullcircle scaled 12 withcolor "MyColor1" ;
+fill fullcircle scaled 10 withcolor "MyColor2" ;
+fill fullcircle scaled 8 withcolor complementary "MyColor3" ;
+fill fullcircle scaled 6 withcolor complemented "MyColor3" ;
+fill fullcircle scaled 4 withcolor "MyColor4" randomized 2 ;
+fill fullcircle scaled 2 withcolor "MyColor4" randomized 2 ;
+addbackground
+ withcolor .5[resolvedcolor("MyColor4"),resolvedcolor("MyColor2")] ;
+currentpicture := currentpicture ysized 4cm ;
+\stopbuffer
+
+\typebuffer
+
+And get:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=Formatted text]
+
+Text support in \METAFUN\ has evolved quite a bit over years. For compatibility
+reasons we keep old methods around but in practice one can probably do all with
+the following:
+
+\starttabulate[|T|p|]
+\NC textext[.anchor](str) \NC position a text relative to the origin \NC \NR
+\NC thetextext[.anchor](str,pos) \NC position a text relative to the given position \NC \NR
+\NC rawtextext[.anchor](str,pos) \NC idem but with less checking \NC \NR
+\stoptabulate
+
+If needed all functionality could be combined in one call (textext) but we keep
+it this way.
+
+You need to keep in mind that text in \METAPOST\ is not a first class object but
+something virtual that is known to \METAFUN\ as something with path like properties
+but is actually dealt with in the backend. This means that timing is important.
+
+\starttyping
+\startMPinitializations
+picture p ; p := image(draw textext("Foo"););
+\stopMPinitializations
+
+\startMPcode
+ picture q ; q := image(draw textext("Bar"););
+ picture r ; r := image(draw textext("Gnu"););
+ draw p ;
+ draw q shifted (2cm,0) ;
+ draw r shifted (4cm,0) ;
+\stopMPcode
+\stoptyping
+
+This will work out well because an initialization is part of a figure, but
+this will fail:
+
+\starttyping
+\startMPinclusions
+picture p ; p := image(draw textext("Foo"););
+\stopMPinclusions
+\stoptyping
+
+because inclusions happen before the local textexts get initialized and
+due to the multipass implementation are not seeN a second time. The order of
+processing is:
+
+\starttabulate[|l|c|c|]
+\BC action \BC first pass \BC second pass \NC \NR
+\NC definitions \NC yes \NC \NC \NR
+\NC extensions \NC yes \NC \NC \NR
+\NC inclusions \NC yes \NC \NC \NR
+\NC begin figure \NC yes \NC yes \NC \NR
+\NC initializations \NC yes \NC yes \NC \NR
+\NC metapost code \NC yes \NC yes \NC \NR
+\NC end figure \NC yes \NC yes \NC \NR
+\stoptabulate
+
+The graph package (that comes with \METAPOST) has some pseudo typesetting on
+board needed to format numbers. Because we don't want to interfere with the
+definitions of macros used in that package we provide another set of macros for
+formatting: \type {fmttext}, \type {thefmttext} and \type {rawfmttext}.
+
+\startbuffer
+\startMPcode
+draw thefmttext("\bf@3.2f done",123.45678) withcolor darkred ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+Here we pass one variable to the format but there can be more: \inlinebuffer. In
+\LUA\ the \type {%} is used as format directive but that does not work well in
+\TEX\ and \LUA\ which is why we use \type {@} instead. The formatting is done
+with the formatters subsystem which is an extension to the regular \LUA\ \type
+{format} function. More information can be found in \type {clf-mkiv.pdf} but one
+extension is not mentioned there: \type {%!texexp!}. This directive takes one
+argument by default but optionally can take one or two extra arguments: the
+format of the base number and one for the exponent. The following code
+demonstrates this:
+
+\startbuffer
+\startMPcode{doublefun}
+draw image (
+ draw thefmttext.rt("@!texexp!", 10.4698E30, (0,-1LineHeight)) ;
+ draw thefmttext.rt("@1!texexp!",10.4698E30, (0,-2LineHeight)) ;
+ draw thefmttext.rt("@2!texexp!",10.4698E30,"@2.3f", (0,-3LineHeight)) ;
+ draw thefmttext.rt("@3!texexp!",10.4698E30,false,"@2i", (0,-4LineHeight)) ;
+ draw thefmttext.rt("@3!texexp!",10.4698E30,"@2.3f","@2i",(0,-5LineHeight)) ;
+) withcolor darkblue ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+We switch to double mode because we use large numbers.
+
+\startlinecorrection[blank]
+ \getbuffer
+\stoplinecorrection
+
+Of course this extra formatter is also supported in the \type {context}
+command:
+
+\startbuffer
+\startluacode
+context("%!texexp!, ", 10.4698E30)
+context("%1!texexp!, ", 10.4698E30)
+context("%2!texexp!, ", 10.4698E30,"@2.3f")
+context("%3!texexp! and ",10.4698E30,false,"@2i")
+context("%3!texexp!", 10.4698E30,"@2.3f","@2i")
+\stopluacode
+\stopbuffer
+
+\typebuffer
+
+This gives: \inlinebuffer .
+
+\stopsection
+
+\startsection[title=Lists (aka suffixed variables)]
+
+Sometimes graphics are constructed using lists. There are a few helpers (and
+maybe there will be some more) that can make things a bit easier. Say that we
+do this:
+
+\startbuffer
+pair a[] ;
+a[1] := (0,0) ; a[2] := (1,0) ;
+a[3] := (1,1) ; a[4] := (0,1) ;
+a[5] := (1,1) ; a[6] := (2,0) ;
+
+draw topath(a,--) ysized 2cm
+ withpen pencircle scaled 1mm
+ withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The \type {topath} macro converts the list into a path, in this case an ugly one.
+
+Say that we want to get rid of the sixth entry. For that we can use the \type
+{dispose} macro. You can use the dispose for any type (except a macro).
+
+\startbuffer
+dispose(a[6]) ;
+draw topath(a,--) ysized 2cm
+ withpen pencircle scaled 1mm
+ withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+We still have some duplicate entries here:
+
+\startbuffer
+dispose(a[6]) ;
+drawpoints topath(a,--) ysized 2cm
+ withpen pencircle scaled 1mm
+ withcolor .625red ;
+drawpointlabels topath(a,--) ysized 2cm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+These can be removed with:
+
+\startbuffer
+uniquelist(a) ;
+draw topath(a,--) ysized 2cm
+ withpen pencircle scaled 1mm
+ withcolor .625yellow ;
+drawpoints topath(a,--) ysized 2cm
+ withpen pencircle scaled 1mm
+ withcolor .625red ;
+drawpointlabels topath(a,--) ysized 2cm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Sometimes a list needs to be sorted and here is the solution:
+
+\startbuffer
+sortlist(a,nothing) ;
+draw topath(a,--) ysized 2cm
+ withpen pencircle scaled 1mm
+ withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The second argument can be an operator that takes a pair variable:
+
+\startbuffer
+sortlist(a,xpart) ;
+draw topath(a,--) ysized 2cm
+ withpen pencircle scaled 3mm
+ withcolor .625red ;
+sortlist(a,ypart) ;
+draw topath(a,--) ysized 2cm
+ withpen pencircle scaled 2mm
+ withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Constructing a list can be sped up with the \type {tolist} macro.
+
+\startbuffer
+pair a[], b[], c[], d[] ;
+tolist(a,1,(0,0),(1,0),(1,1),(0,1)--(1,1)--(2,2)) ;
+tolist(b,0,(0,0),(1,0),(1,1),(0,1)--(1,1)--(2,2)) ;
+tolist(c,(0,0),(1,0),(1,1),(0,1)--(1,1)--(2,2)) ;
+tolist(d,(0,0),(1,0),(1,1)) ;
+
+draw image (
+ draw topath(a,--) shifted (0,0) ;
+ draw topath(b,--) shifted (3,0) ;
+ draw topath(c,--) shifted (6,0) ;
+ draw topath(d,--) shifted (9,0) ;
+) ysized 2cm withpen pencircle scaled 1mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=Segmented paths]
+
+\index {segmented paths}There are all kind of helpers in \METAFUN\ and some are
+discussed here. In \in {figure} [fig:segmentedpaths] we see a few macros that
+return a (smooth) path made from segments. You can for instance use these to do
+things that use the points on a path, like anchoring text.
+
+\startbuffer
+def DrawSomePath(text t) =
+ drawpath t withcolor .625red ;
+ drawpoints t withcolor white ;
+ drawpointlabels t ;
+enddef ;
+
+DrawSomePath(circularpath(5) scaled 12cm) ;
+DrawSomePath(squarepath (5) scaled 8cm) ;
+DrawSomePath(linearpath (5) scaled 4cm) ;
+\stopbuffer
+
+\typebuffer
+
+\startplacefigure[title={A few segmented paths.},reference=fig:segmentedpaths]
+ \processMPbuffer
+\stopplacefigure
+
+\index {crossing paths}The following examples demonstrates two mechanisms. In the
+image two paths are drawn on top of each other but one of them has holes where
+the other one crosses. The \type {crossingunder} macro was written by Alan
+Braslau as part of the node based diagram builder. In the process the arrow
+drawing code was adapted to accept a picture.
+
+\startbuffer[a]
+drawarrow image (
+ draw ((fullcircle scaled 2.25cm) crossingunder (fullsquare scaled 2cm))
+ withpen pencircle scaled 1mm withcolor .625green ;
+ draw (fullsquare scaled 2cm)
+ withpen pencircle scaled 1mm withcolor .625blue ;
+) ;
+drawarrow image (
+ draw (fullsquare scaled 4cm)
+ withpen pencircle scaled 1mm withcolor .625red ;
+ draw ((fullcircle scaled 5cm) crossingunder (fullsquare scaled 4cm))
+ withpen pencircle scaled 1mm withcolor .625yellow ;
+) ;
+\stopbuffer
+
+\startbuffer[b]
+drawarrow image (
+ draw ((fullsquare scaled 2cm) crossingunder (fullcircle scaled 2.25cm))
+ withpen pencircle scaled 1mm withcolor .625blue ;
+ draw (fullcircle scaled 2.25cm)
+ withpen pencircle scaled 1mm withcolor .625green ;
+) ;
+drawarrow image (
+ draw (fullcircle scaled 5cm)
+ withpen pencircle scaled 1mm withcolor .625yellow ;
+ draw ((fullsquare scaled 4cm) crossingunder (fullcircle scaled 5cm))
+ withpen pencircle scaled 1mm withcolor .625red ;
+) ;
+\stopbuffer
+
+\typebuffer[a]
+
+The next variant uses a different order:
+
+\typebuffer[b]
+
+The results are shown in \in {figure} [fig:crossingunder]. The internal variable
+\type {crossingscale} can be used to make the gap wider or narrower. The gap has
+a default value of 20.
+
+\startplacefigure[title=Crossing paths without touching,reference=fig:crossingunder]
+ \startcombination
+ {\processMPbuffer[a]} {}
+ {\processMPbuffer[b]} {}
+ \stopcombination
+\stopplacefigure
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-colofon-paper.tex b/doc/context/sources/general/manuals/metafun/metafun-colofon-paper.tex
new file mode 100644
index 000000000..1a611a325
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-colofon-paper.tex
@@ -0,0 +1,19 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-colofon-paper
+
+\environment metafun-environment
+
+\startstandardmakeup
+
+ \vfill
+
+ \setupalign[flushright,broad]
+
+ \component metafun-colofon
+
+\stopstandardmakeup
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-colofon-screen.tex b/doc/context/sources/general/manuals/metafun/metafun-colofon-screen.tex
new file mode 100644
index 000000000..590c7725f
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-colofon-screen.tex
@@ -0,0 +1,21 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-colofon-screen
+
+\environment metafun-environment
+
+\page
+
+\start
+
+ \setupalign[flushright,broad]
+
+ \component metafun-colofon
+
+\stop
+
+\page
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-colofon.tex b/doc/context/sources/general/manuals/metafun/metafun-colofon.tex
new file mode 100644
index 000000000..b4c162a89
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-colofon.tex
@@ -0,0 +1,56 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-colofon
+
+\environment metafun-environment
+
+\introsubject{For them}
+
+I owe much inspiration to both my parents. My mother Jannie constantly
+demonstrated me that computer graphics will never improve nature. She also
+converted one of my first \METAPOST\ graphics into a patchwork that will remind
+me forever that handcraft is more vivid than computer artwork. My father Hein has
+spent a great deal of his life teaching math, and I'm sure he would have loved
+\METAPOST. I inherited his love for books. I therefore dedicate this document to
+them.
+
+\introsubject{Colofon}
+
+This manual is typeset with \CONTEXT\ \MKIV. No special tricks are used and
+everything you see in here, is available for \CONTEXT\ users. The text is typeset
+in Palatino and Computer Modern Typewriter. We used \LUATEX\ as \TEX\ processing
+engine. Since this document is meant to be printed in color, some examples will
+look sub||optimal when printed in black and white.
+
+\introsubject{Graphics}
+
+The artist impression of one of Hasselts canals at \at {page} [canal] is made by
+Johan Jonker. The \CDROM\ production process graphic at \at {page} [hacker] is a
+scan of a graphic made by Hester de Weert.
+
+\introsubject{Copyright}
+
+\startlines
+Hans Hagen, PRAGMA Advanced Document Engineering, Hasselt NL
+copyright: 1999-\currentdate[year] / version 4: \currentdate
+\stoplines
+
+\introsubject{Publisher}
+
+\startlines
+publisher: Boekplan, NL
+isbn-ean: 978-94-90688-02-8
+website: www.boekplan.nl
+\stoplines
+
+\introsubject{Info}
+
+\startlines
+internet: www.pragma-ade.com
+support: ntg-context@ntg.nl
+context: www.contextgarden.net
+\stoplines
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-contents.tex b/doc/context/sources/general/manuals/metafun/metafun-contents.tex
new file mode 100644
index 000000000..0767a0248
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-contents.tex
@@ -0,0 +1,17 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-contents
+
+\environment metafun-environment
+
+\starttitle[reference=content,title={Content}]
+
+ \startcolumns
+ \placelist[chapter,section]
+ \stopcolumns
+
+\stoptitle
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-conventions.tex b/doc/context/sources/general/manuals/metafun/metafun-conventions.tex
new file mode 100644
index 000000000..6a6072c56
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-conventions.tex
@@ -0,0 +1,117 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-conventions
+
+\environment metafun-environment
+
+\startchapter[title={Conventions}]
+
+\index {running}
+\index {processing}
+
+When reading this manual, you may be tempted to test the examples shown. This can
+be done in several ways. You can make a file and process that file by \METAPOST.
+Such a file looks like:
+
+\starttyping
+beginfig(1) ;
+ fill fullcircle scaled 5cm withcolor red ; % a graphic
+endfig ;
+
+end .
+\stoptyping
+
+Don't forget the semi||colons that end the statements. If the file is saved as
+\type {yourfile.mp}, then the file can be processed. Before we process this file,
+we first need to load some basic \METAPOST\ definitions, because the built in
+repertoire of commands is rather limited. Such a set is called a format. The
+standard format is called {metapost} but we will use a more extensive set of
+macros \type {metafun}. In the past such a set was converted into a \type {mem}
+file and running the above file was done with:
+
+\starttyping
+mpost --mem=metafun.mem yourfile
+\stoptyping
+
+However, this is no longer the case and macros need to be loaded at startup as
+follows:
+
+\starttyping
+mpost --ini metafun.mpii yourfile.mp
+\stoptyping
+
+Watch the suffix \type {mpii}: this refers to the stand alone, the one that
+doesn't rely on \LUATEX.
+
+After the run the results are available in \type {yourfile.1} and can be viewed
+with \GHOSTSCRIPT. You don't need to close the file so reprocessing is very
+convenient.
+
+Because we will go beyond standard \METAPOST, we will use the \type {mpiv} files.
+These work with the library which in turn means that we will run from within
+\CONTEXT. This has the advantage that we also have advanced font support at our
+hands. In that case, a simple file looks like:
+
+\starttyping
+\starttext
+ \startMPpage
+ fill fullcircle scaled 5cm withcolor red ;
+ \stopMPpage
+ \startMPpage
+ fill unitsquare scaled 5cm withcolor red ;
+ \stopMPpage
+\stoptext
+\stoptyping
+
+If the file is saved as \type {yourfile.tex}, then you can produce a \PDF\ file
+with: \footnote {In fact, you could also process the \METAPOST\ file directly
+because the \type {context} script will recognize it as such and wrap it into
+a page.}
+
+\starttyping
+context yourfile
+\stoptyping
+
+The previous call will use \LUATEX\ and \CONTEXT\ \MKIV\ to produce a file with
+two pages using the built in \METAPOST\ library with \METAFUN. When you use this
+route you will automatically get the integrated text support shown in this
+manual, including \OPENTYPE\ support. If one page is enough, you can also say:
+
+\starttyping
+\startMPpage
+fill fullcircle scaled 5cm withcolor red ;
+\stopMPpage
+\stoptyping
+
+So when you have a running \CONTEXT\ on your system you don't need to bother
+about installing \METAPOST\ and running \METAFUN.
+
+We will use lots of color. Don't worry if your red is not our red, or your yellow
+does not match ours. We've made color definitions to match the overall design of
+this document, but you should feel free to use any color of choice in the
+upcoming examples.
+
+By default, \CONTEXT\ has turned its color mechanism on. If you don't want your
+graphics to have color, you should say:
+
+\starttyping
+\setupcolors[state=stop]
+\stoptyping
+
+but in todays documents color is so normal that you will probably never do that.
+Because \METAFUN\ hooks into the \CONTEXT\ color mechanism, you can also use its
+color space and conversion related features.
+
+You need to keep in mind that just like \CONTEXT\ \MKII\ is frozen, the \type
+{mpii} macros are also not extended. From now on we assume that you use \CONTEXT\
+\MKIV\ which exclusively uses \type {mpiv} macros.
+
+Even if you want to use \METAFUN\ but not \CONTEXT, you can still best use the
+mentioned page method as it will give you decent text processing. You need to
+know (and use) only a few \CONTEXT\ commands then.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-debugging.tex b/doc/context/sources/general/manuals/metafun/metafun-debugging.tex
new file mode 100644
index 000000000..4174d34e1
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-debugging.tex
@@ -0,0 +1,383 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent mfun-debugging
+
+\environment metafun-environment
+
+\startchapter[reference=sec:debugging,title={Debugging}]
+
+\index{debugging}
+
+\startintro
+
+Those familiar with \CONTEXT\ will know that it has quite some visual debugging
+features build in. So, what can you expect of the \METAPOST\ macros that come
+with \CONTEXT ? In this chapter we will introduce a few commands that show some
+insight in what \METAPOST\ is doing.
+
+\stopintro
+
+\startsection[title=Showing paths]
+
+Since the outcome of \METAPOST\ code is in many respects more predictable than
+that of \TEX\ code, we don't need that advanced visual debugging features.
+Nevertheless we provide a few, that are all based on visualizing paths.
+
+\startbuffer
+path p ; p := fullcircle scaled 4cm ;
+drawpath p ; drawpoints p ; drawpointlabels p ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+This visualization is achieved by using dedicated drawing commands:
+
+\typebuffer
+
+Since control points play an important role in defining the shape, visualizing
+them may shed some insight in what \METAPOST\ is doing.
+
+\startbuffer
+path p ; p := fullcircle xscaled 4cm yscaled 3cm ;
+drawpath p ; drawcontrollines p ;
+drawpoints p ; drawcontrolpoints p ; drawpointlabels p ;
+\stopbuffer
+
+\typebuffer
+
+The pre and post control points show up as small dots and are connected to their
+parent point with thin lines.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+You can deduce the direction of a path from the way the
+points are numbered, but using an arrow to indicate the
+direction is more clear.
+
+\startbuffer
+path p ; p := fullcircle xscaled 4cm yscaled 3cm ;
+drawarrowpath p ; drawcontrollines p ;
+drawpoints p ; drawcontrolpoints p ; drawpointlabels p ;
+\stopbuffer
+
+\typebuffer
+
+The \type {drawarrowpath} is responsible for the arrow. Especially when you are
+in the process of defining macros that have to calculate intersections or take
+subpaths, knowing the direction may be of help.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The next table summarizes the special drawing commands:
+
+\starttabulate[|lT|l|]
+\HL
+\NC drawpath \NC the path \NC \NR
+\NC drawarrowpath \NC the direction of the path \NC \NR
+\NC drawcontrollines \NC the lines to the control points \NC \NR
+\NC drawpoints \NC the points that make up the path \NC \NR
+\NC drawcontrolpoints \NC the control points of the points \NC \NR
+\NC drawpointlabels \NC the numbers of the points \NC \NR
+\HL
+\stoptabulate
+
+You can set the characteristics of these like you set \type {drawoptions}. The
+default settings are as follows:
+
+\starttyping
+drawpathoptions (withpen pencircle scaled 5 withcolor .8white) ;
+drawpointoptions (withpen pencircle scaled 4 withcolor black) ;
+drawcontroloptions(withpen pencircle scaled 2.5 withcolor black) ;
+drawlineoptions (withpen pencircle scaled 1 withcolor .5white) ;
+drawlabeloptions () ;
+\stoptyping
+
+Two more options are \type {draworiginoptions} and \type {drawboundoptions} which
+are used when visualizing the bounding box and origin.
+
+\startbuffer
+swappointlabels := true ;
+path p ; p := fullcircle xscaled 4cm yscaled 3cm ;
+drawarrowpath p ; drawcontrollines p ;
+drawpoints p ; drawcontrolpoints p ; drawpointlabels p ;
+drawboundingbox p ; draworigin ;
+\stopbuffer
+
+\typebuffer
+
+In this example we have set \type {swappointlabels} to change the place of the
+labels. You can set the variable \type {originlength} to tune the appearance of
+the origin.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+You can pass options directly, like you do with \type {draw} and \type {fill}.
+Those options override the defaults.
+
+\startbuffer
+path p ; p := fullcircle xscaled 6cm yscaled 3cm rotated 15 ;
+drawarrowpath p ;
+drawcontrollines p withcolor .625red ;
+drawpoints p withcolor .625yellow ;
+drawcontrolpoints p withcolor .625yellow ;
+drawpointlabels p withcolor .625yellow ;
+drawboundingbox p ;
+draworigin withcolor .625red ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Here we used the options:
+
+\typebuffer
+
+Sometimes it makes sense to draw a simple coordinate system, and for that purpose
+we have three more macros. They draw axis and tickmarks.
+
+\startbuffer
+drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ;
+\stopbuffer
+
+\typebuffer
+
+The system drawn is based on the bounding box specification of the path passed to
+the macro. You can also draw one axis, using \type {drawxticks} or \type
+{drawyticks}. Here we show the previous command.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+By default, the ticks are placed at .5cm distance, but you can change this by
+setting \type {tickstep} to a different value.
+
+\startbuffer
+tickstep := 1cm ; ticklength := 2mm ;
+drawticks fullsquare xscaled 4cm yscaled 3cm ;
+tickstep := tickstep/2 ; ticklength := ticklength/2 ;
+drawticks fullsquare xscaled 4cm yscaled 3cm ;
+\stopbuffer
+
+\typebuffer
+
+The \type {ticklength} variable specifies the length of a tick. Here we
+manipulated both the variables to get a more advanced system.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+If visualizing a path would mean that we would have to key in al those
+draw||commands, you could hardly call it a comfortable tool. Therefore, we can
+say:
+
+\startbuffer
+drawwholepath fullsquare scaled 3cm rotated 30 randomized 5mm ;
+\stopbuffer
+
+\typebuffer
+
+The \type {drawwholepath} command shows everything except the axis.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+If even this is too much labour, you may say:
+
+\starttyping
+visualizepaths ;
+\stoptyping
+
+This redefines the \type {draw} and \type {fill} command in such a way that they
+also show all the information.
+
+\startbuffer
+visualizepaths ;
+draw fullsquare scaled 3cm rotated 30 randomized 2mm ;
+\stopbuffer
+
+\typebuffer
+
+You may compare this feature to the \type {\showmakeup} command available in
+\CONTEXT, that redefines the \TEX\ primitives that deal with boxes, glues,
+penalties, and alike.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Of course you may want to take a look at the \METAPOST\ manual for its built in
+(more verbose) tracing options. One command that may prove to be useful is \type
+{show}, that you can apply to any variable. This command reports the current
+value (if known) to the terminal and log file.
+
+\startlinecorrection[blank]
+{\showmakeup\processMPbuffer}
+\stoplinecorrection
+
+The previous picture shows what is typeset when we also say \type {\showmakeup}.
+This command visualizes \TEX's boxes, skips, kerns and penalties. As you can see,
+there are some boxes involved, which is due to the conversion of \METAPOST\
+output to \PDF.
+
+\starttyping
+\startlinecorrection[blank]
+... the graphic ...
+\stoplinecorrection
+\stoptyping
+
+The small bar is a kern and the small rectangles are penalties. More details on
+this debugger can be found in the \CONTEXT\ manuals and the documentation of the
+modules involved.
+
+\stopsection
+
+\startsection[title=Comments]
+
+Sometimes, when trouble strikes, you might want to peek in the \PDF\ file to see
+what gets written there. Each graphic is marked with a number but when you
+have many it might make sense to add a comment to help you locate the code.
+
+\startbuffer
+\startMPcode
+ comment("test graphic") ;
+ message("processing a test graphic") ;
+ draw fullsquare scaled 1cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+This renders as:
+
+\startlinecorrection[blank]
+ \getbuffer
+\stoplinecorrection
+
+On the console we get these messages:
+
+\starttyping
+metapost > message : processing a test graphic
+metapost > warning : processing a test graphic
+\stoptyping
+
+And in the \PDF\ file we will find:
+
+\starttyping
+% mps graphic 1: begin
+% mps graphic 1: test graphic
+q 0 g 0 G 10 M 1 j 1 J
+0.500000000 w
+-14.173233032 -14.173233032 m
+14.173233032 -14.173233032 l
+14.173233032 14.173233032 l
+-14.173233032 14.173233032 l
+-14.173233032 -14.173233032 l
+h S
+0 g 0 G Q
+% mps graphic 1: end
+\stoptyping
+
+Here are some examples of constructed messages:
+
+\starttyping
+message "2: okay (done)" ;
+message "1: " & dq & "okay" & dq & " (done)" ;
+message "3: " & quotation "okay" & " (done)" ;
+message "3: " & quote "okay" & " (done)" ;
+message "4: " & quotation 123 & " (done)" ;
+message "5: " & quotation true & " (done)" ;
+message "6: " & quote true & " (done)" ;
+message "7: " & tostring true & " (done)" ;
+message "8: " & tostring (1,2) & " (done)" ;
+message "9: " & topair (1,2) & " (done)" ;
+\stoptyping
+
+and this is what you get:
+
+\starttyping
+metapost > message : 2: okay (done)
+metapost > message : 1: "okay" (done)
+metapost > message : 3: "okay" (done)
+metapost > message : 3: 'okay' (done)
+metapost > message : 4: "123" (done)
+metapost > message : 5: "true" (done)
+metapost > message : 6: 'true' (done)
+metapost > message : 7: true (done)
+metapost > message : 8: 1 2 (done)
+metapost > message : 9: (1,2) (done)
+\stoptyping
+
+\stopsection
+
+\startsection[title=Pens]
+
+A circular pen is applied to a path in a different way than for instance a
+square pen. Circular pens are mapped onto \POSTSCRIPT\ pens while for other
+pens an outline is calculated that gets filled. Take this code:
+
+\startbuffer[a]
+\startMPcode
+ draw fullcircle xscaled 6cm yscaled 3cm
+ withpen pensquare scaled 5mm rotated 30
+ withcolor .625yellow ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[b]
+\startMPcode
+ draw envelope pensquare scaled 5mm rotated 30 of
+ (fullcircle xscaled 6cm yscaled 3cm)
+ withpen pencircle scaled 1mm
+ withcolor .375white ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[c]
+\enabletrackers[metapost.forcestroke]
+\startMPcode
+ draw fullcircle xscaled 6cm yscaled 3cm
+ withpen pensquare scaled 5mm rotated 30
+ withcolor .625red ;
+\stopMPcode
+\disabletrackers[metapost.forcestroke]
+\stopbuffer
+
+\typebuffer[a]
+
+and this:
+
+\typebuffer[b]
+
+and:
+
+\typebuffer[c]
+
+When we overlay these three we get. The envelope only returns the outer curve.
+
+\startlinecorrection[blank]
+\startoverlay
+ {\getbuffer[a]}
+ {\getbuffer[b]}
+ {\getbuffer[c]}
+\stopoverlay
+\stoplinecorrection
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-document.tex b/doc/context/sources/general/manuals/metafun/metafun-document.tex
new file mode 100644
index 000000000..bb5540850
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-document.tex
@@ -0,0 +1,118 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-document
+
+\environment metafun-environment
+
+\startchapter[title={This document}]
+
+\startintro
+
+This document is produced in \CONTEXT\ and can serve as an example of how to
+integrate \METAPOST\ graphics into \TEX. In this appendix we will discuss some
+details of producing this document.
+
+\stopintro
+
+We did not use any special tricks, so most of the examples you have seen are
+coded just as shown. We used buffers to ensure that the code used to produce the
+accompanying graphic is identical to the typeset code in the document. Here is an
+example.
+
+\starttyping
+\startbuffer[dummy]
+draw fullcircle
+ xscaled 3cm yscaled 2cm
+ rotatedaround(origin,30)
+ withcolor .625red ;
+\stopbuffer
+\stoptyping
+
+Instead of using \type {\getbuffer}, we used the following command:
+
+\starttyping
+\startlinecorrection[blank]
+\processMPbuffer[dummy]
+\stoplinecorrection
+\stoptyping
+
+The line correction commands take care of proper spacing around the graphic. If
+you want to process more buffers at once, you can pass their names as a comma
+separated list. Alternatively, we could have said:
+
+\starttyping
+\startuseMPgraphic{dummy}
+ draw fullcircle
+ xscaled 3cm yscaled 2cm
+ rotatedaround(origin,30)
+ withcolor .625red ;
+\stopuseMPgraphic
+\stoptyping
+
+When including this graphic, we again take care of spacing.
+
+\starttyping
+\startlinecorrection[blank]
+\useMPgraphic{dummy}
+\stoplinecorrection
+\stoptyping
+
+The first version of this manual was produced with \PDFTEX\ and call|-|outs to
+\METAPOST. Because the number of graphics is large, we processed that version
+using the \type {--automp} directive (at that moment we were using \TEXEXEC). And
+even then runtime was so unconveniently long that updating this manual became
+less and less fun. The current version is produced with \LUATEX\ and \CONTEXT\
+\MKIV, which brings down the runtime (including runtime calls to independent
+\CONTEXT\ runs for the outline examples) to some 45 seconds on a 2.2 Gig Dell
+M90. Given that (at the time of writing this) over 1700 graphics are generated on
+the fly, this is not bad at all. On my current machine, a Dell M6700 with an
+Intel Core i7|-|3840QM running at 2.8 (3.9) Ghz (and Windows~8) the runtime of
+the third version was just above 20 seconds all|-|in and some 25\percent\ less
+when using \LUAJITTEX. When I started with updating to version 4 of this manual,
+I timed about 15 seconds on the same machine (but with Windows-10) which means
+that in the meantime the \CONTEXT|/|\LUATEX\ combination gained some 25\%
+performance. Using the new Bash|-|On|-|Windows subsystem gives the same
+performance. Of course each update adds pages so in the end we need more time
+with each update but it remains a nice test case. The tight integration of \TEX,
+\METAPOST\ and \LUA\ pays off.
+
+The document style is not that complicated. The main complication in such a
+document is to make sure that \METAPOST\ is operating under the same font regime,
+but in \MKIV\ this happens automatically. As document font we use the URW
+Palatino for the running text combined with Computer Modern Typewriter. Because
+this document is available as paper and screen document, some large graphics are
+scaled down in the screen version.
+
+We don't use any special tricks in typesetting this document, but when we added
+the section about transparency, a dirty trick was needed in a few cases in order to
+get the described results. Because the screen document has gray backgrounds,
+exclusive transparencies come out \quote {wrong}. In the function drawing example
+we use the following trick to get a black background behind the graphics only. We
+have a buffer that contains a few lines of code:
+
+% buffer only available in screen mode
+
+\starttyping
+picture savedpicture ;
+savedpicture := currentpicture ;
+currentpicture := nullpicture ;
+draw savedpicture withcolor black ;
+draw savedpicture ;
+\stoptyping
+
+Since we use buffers for the graphics as well, we can now process a buffer with
+name \type {example} as follows:
+
+\starttyping
+\processbuffer[example,wipe]
+\stoptyping
+
+This means that the example code is included two times. After it is processed, we
+recolor the currentpicture black, and after that we add the original picture once
+again.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-effects.tex b/doc/context/sources/general/manuals/metafun/metafun-effects.tex
new file mode 100644
index 000000000..74e7d487e
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-effects.tex
@@ -0,0 +1,2596 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+% graphic text takes 5 sec on 21
+
+\startcomponent metafun-effects
+
+\environment metafun-environment
+
+\useMPlibrary[outlines]
+
+\startchapter[reference=sec:effects,title={Special effects}]
+
+\startintro
+
+Sometimes we want to go beyond \METAPOST's native features. Examples of such an
+extension are \CMYK\ colors, shading and transparency. Although features like
+this should be used with care, sometimes the documents look and feel can profit
+from it.
+
+If you don't want the whole graphic, but only a part of it, clipping comes into
+play. In addition to the standard clipping features, we can use \METAPOST\ to
+provide a decent clipping path. In this chapter we will uncover the details.
+
+We will also introduce ways to include externally defined graphics and outline
+fonts. We will demonstrate that within reasonable bounds you can manipulate such
+graphics.
+
+\stopintro
+
+\startsection[title={Spot colors}]
+
+You can define spot and multitone colors directly in \METAFUN, although normally
+you will do it at the \TEX\ end for consistency. At the \TEX\ end we define this:
+
+\startbuffer
+\definecolor [SpotBlue] [c=1,m=.38,y=0,k=.64]
+\definecolor [SpotYellow] [c=0,m=.28,y=1,k=.06]
+\definemultitonecolor [MultiColor] [SpotBlue=.5,SpotYellow=.25]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+draw image (
+ fill unitsquare shifted (7,0)
+ withcolor namedcolor("MultiColor") ;
+ fill unitsquare shifted (6,0)
+ withcolor .6 * spotcolor("temp1",red) ;
+ fill unitsquare shifted (5,0)
+ withcolor .4 * spotcolor("temp1",red) ;
+ fill unitsquare shifted (4,0)
+ withcolor .5 * spotcolor("temp2",.5green) ;
+ fill unitsquare shifted (3,0)
+ withcolor .5 * spotcolor("temp3",green) ;
+ fill unitsquare shifted (2,0)
+ withcolor multitonecolor("temp4",blue/2,yellow/2,green/2,magenta/3) ;
+) xsized TextWidth ;
+\stopbuffer
+
+Next we process this graphic:
+
+\typebuffer
+
+and get:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Transparency}]
+
+\index{transparency}
+
+{\em In the screen version we use a light gray background color. As a result,
+some of the transparency methods demonstrated here give unexpected results. The
+A4 version of this document demonstrates the real effects.}
+
+Although transparent colors have been around for some time already, it was only
+around 2000 that they made it as a high level feature into document format
+languages like \PDF. Supporting such a feature at a higher abstraction level is
+not only more portable, but also less sensitive for misinterpretation.
+
+\startbuffer[mpdef]
+vardef ColorCircle (expr method, factor, ca, cb, cc) =
+ save u, p ; path p ; p := fullcircle shifted (1/4,0) ;
+ image
+ ( fill p rotated 90 withcolor ca withtransparency (method,factor) ;
+ fill p rotated 210 withcolor cb withtransparency (method,factor) ;
+ fill p rotated 330 withcolor cc withtransparency (method,factor) ; )
+enddef ;
+\stopbuffer
+
+\typebuffer[mpdef]
+
+\startbuffer[mp]
+draw ColorCircle ("normal", .5, red, green, blue) xsized 3cm ;
+currentpicture := currentpicture shifted (-4cm,0) ;
+draw ColorCircle ("exclusion", .5, red, green, blue) xsized 3cm ;
+currentpicture := currentpicture shifted (-4cm,0) ;
+draw ColorCircle ("exclusion", 1, red, green, blue) xsized 3cm ;
+\stopbuffer
+
+\typebuffer[mp]
+
+\startlinecorrection[blank]
+\processMPbuffer[mpdef,mp]
+\stoplinecorrection
+
+\startbuffer[mp]
+cmykcolor xcyan ; xcyan := (1,0,0,0) ;
+cmykcolor xmagenta ; xmagenta := (0,1,0,0) ;
+cmykcolor xyellow ; xyellow := (0,0,1,0) ;
+
+draw ColorCircle ("exclusion", .5, xcyan, xmagenta, xyellow) xsized 3cm ;
+\stopbuffer
+
+\typebuffer[mp]
+
+\startlinecorrection[blank]
+\processMPbuffer[mpdef,mp]
+\stoplinecorrection
+
+You can be tempted to use transparency as a convenient way to achieve soft
+colors. In that case you should be aware of the fact that rendering transparent
+colors takes more time than normal colors \footnote {When your printer does not
+support this feature natively, the intermediate (\POSTSCRIPT) file send to the
+printing engine is also larger.}
+
+Fortunatey, \METAPOST\ provides a similar mechanism. The last circle in the
+following row demonstrates how we can trigger colors proportionally to other
+colors. Normally \type {background} is white, but you can set predefined color
+variables to another value.
+
+\startbuffer[mp]
+path p ; p := fullcircle scaled 2cm ;
+fill p shifted (0cm,0) withcolor blue ;
+fill p shifted (3cm,0) withcolor .5blue ;
+fill p shifted (6cm,0) withcolor transparent (1,0.5,blue) ;
+fill p shifted (9cm,0) withcolor .5[blue,white] ;
+\stopbuffer
+
+\typebuffer[mp]
+
+\startlinecorrection[blank]
+\processMPbuffer[mp]
+\stoplinecorrection
+
+The next series demonstrates that we use the complementary factor \type {.7} in
+the \METAPOST\ soft color to achieve the same softness as the \type {.3}
+transparency.
+
+\startbuffer[mp]
+path p ; p := fullcircle scaled 2cm ;
+fill p shifted (0cm,0) withcolor red ;
+fill p shifted (3cm,0) withcolor .7red ;
+fill p shifted (6cm,0) withcolor transparent (1,0.3,red) ;
+fill p shifted (9cm,0) withcolor .7[red,white] ;
+\stopbuffer
+
+\typebuffer[mp]
+
+\startlinecorrection[blank]
+\processMPbuffer[mp]
+\stoplinecorrection
+
+\startbuffer[mp]
+vardef SampleText (expr t, c) =
+ save p ; picture p ;
+ p := image (draw t infont "\truefontname{Regular}") ;
+ draw (p shifted (- xpart center p,0)) scaled 5 withcolor c;
+enddef ;
+
+SampleText ("Much Of This" , transparent(1, .5, red )) ;
+SampleText ("Functionality" , transparent(1, .5, green)) ;
+SampleText ("Was Written" , transparent(1, .5, blue )) ;
+SampleText ("While Listening", transparent(1, .5, cmyk(1,0,0,0))) ;
+SampleText ("To the CD's Of" , transparent(1, .5, cmyk(0,1,0,0))) ;
+SampleText ("Tori Amos" , transparent(1, .5, cmyk(0,0,1,0))) ;
+\stopbuffer
+
+So far we have applied transparent colors to shapes but text can also be the
+target.
+
+\typebuffer[mp]
+
+The source code of this example illustrates that the \CMYK\ color space is also
+supported. The \type {\truefontname} macro communicates the running font from
+\TEX\ to \METAPOST. Instead of such low level code one can of course also use the
+\type {textext} macro.
+
+\startbuffer[mp]
+vardef SampleText (expr t) =
+ draw textext(t) scaled 5 ;
+enddef ;
+
+SampleText ("\colored[a=1,t=.5,r=1]{Much Of This}") ;
+SampleText ("\colored[a=1,t=.5,g=1]{Functionality}") ;
+SampleText ("\colored[a=1,t=.5,b=1]{Was Written}") ;
+SampleText ("\colored[a=1,t=.5,c=1]{While Listening}") ;
+SampleText ("\colored[a=1,t=.5,m=1]{To the CD's Of}") ;
+SampleText ("\colored[a=1,t=.5,y=1]{Tori Amos}") ;
+\stopbuffer
+
+However, as we do the typesetting in \TEX\ in \MKIV\ this is the way to go:
+
+\typebuffer[mp]
+
+As expected we get:
+
+\startlinecorrection[blank]
+\processMPbuffer[mp]
+\stoplinecorrection
+
+Currently the 12 in \PDF\ available transparency methods are supported. \footnote
+{In the future we may also support more control over the individual methods.} You
+can use both numbers and names. As you may expect, both \CONTEXT\ and \METAFUN\
+support transparency in the same way. \in {Figure} [fig:transparencies] shows how
+the method affects the result.
+
+\startuseMPgraphic{test}
+numeric u ; u := if lua.mp.mode("screen") : 12mm else : 20mm fi ;
+
+path p ; p := fullcircle scaled u shifted (u/4,0);
+
+% cmykcolor xyellow ; xyellow := (0,0,1,0) ;
+% color xgreen ; xgreen := (0,1,0) ;
+% color xblue ; xblue := (0,0,1) ;
+
+% fill p rotated 90 withcolor transparent("\MPvar{a}",.5,xyellow) ;
+% fill p rotated 210 withcolor transparent("\MPvar{a}",.5,xgreen) ;
+% fill p rotated 330 withcolor transparent("\MPvar{a}",.5,xblue) ;
+
+fill p rotated 90 withcolor (0,0,1,0) withtransparency("\MPvar{a}",.5) ;
+fill p rotated 210 withcolor (0,1,0) withtransparency("\MPvar{a}",.5) ;
+fill p rotated 330 withcolor (0,0,1) withtransparency("\MPvar{a}",.5) ;
+\stopuseMPgraphic
+
+\startplacefigure[location=here,reference=fig:transparencies,title={The 12 transparency alternatives by name.}]
+ \doifelsemode {screen} {
+ \setupcombination[nx=8,ny=2]
+ } {
+ \setupcombination[nx=4,ny=4]
+ }
+ \startcombination
+ {\useMPgraphic{test}{a=normal}} {\tttf normal}
+ {\useMPgraphic{test}{a=multiply}} {\tttf multiply}
+ {\useMPgraphic{test}{a=screen}} {\tttf screen}
+ {\useMPgraphic{test}{a=overlay}} {\tttf overlay}
+ {\useMPgraphic{test}{a=softlight}} {\tttf softlight}
+ {\useMPgraphic{test}{a=hardlight}} {\tttf hardlight}
+ {\useMPgraphic{test}{a=colordodge}} {\tttf colordodge}
+ {\useMPgraphic{test}{a=colorburn}} {\tttf colorburn}
+ {\useMPgraphic{test}{a=darken}} {\tttf darken}
+ {\useMPgraphic{test}{a=lighten}} {\tttf lighten}
+ {\useMPgraphic{test}{a=difference}} {\tttf difference}
+ {\useMPgraphic{test}{a=exclusion}} {\tttf exclusion}
+ {\useMPgraphic{test}{a=hue}} {\tttf hue}
+ {\useMPgraphic{test}{a=saturation}} {\tttf saturation}
+ {\useMPgraphic{test}{a=color}} {\tttf color}
+ {\useMPgraphic{test}{a=luminosity}} {\tttf luminosity}
+ \stopcombination
+\stopplacefigure
+
+In \CONTEXT\ a transparent color is defined in a similar way as \quote {normal}
+colors. The transparency method is specified with the \type {a} key (either by
+number or by name) and the factor \type {t}.
+
+\startbuffer
+\definecolor [tred] [r=1,t=.5,a=exclusion]
+\definecolor [tgreen] [g=1,t=.5,a=exclusion]
+\definecolor [tblue] [b=1,t=.5,a=exclusion]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Both keys are needed. You can define your own symbolic names using:
+
+\starttyping
+\definetransparency [myowndefault] [1]
+\stoptyping
+
+The \type {\MPcolor} macro passes a color from \CONTEXT\ to \METAPOST, including
+the transparency specification.
+
+\startbuffer[mp]
+u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0);
+
+fill p rotated 90 withcolor \MPcolor{tred} ;
+fill p rotated 210 withcolor \MPcolor{tgreen} ;
+fill p rotated 330 withcolor \MPcolor{tblue} ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[mp]
+\stoplinecorrection
+
+Of course this also works well for \CMYK\ colors.
+
+\startbuffer
+\definecolor[tred] [c=1,k=.2,t=.5,a=1]
+\definecolor[tgreen][m=1,k=.2,t=.5,a=1]
+\definecolor[tblue] [y=1,k=.2,t=.5,a=1]
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[mp]
+\stoplinecorrection
+
+Gray scales work as well:
+
+\startbuffer
+\definecolor[ta][s=.9,t=.7,a=11]
+\definecolor[tb][s=.7,t=.7,a=11]
+\definecolor[tc][s=.5,t=.7,a=11]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We apply this to some text. By using an overlay we can conveniently explore the
+difference in fonts.
+
+% \startbuffer
+% def SampleText (expr s, f, c) =
+% draw s infont f scaled 5 withcolor c ;
+% enddef ;
+
+% SampleText("Hello", "\truefontname{Regular}" , \MPcolor{ta}) ;
+% SampleText("Hello", "\truefontname{RegularBold}" , \MPcolor{tb}) ;
+% SampleText("Hello", "\truefontname{RegularSlanted}", \MPcolor{tc}) ;
+% \stopbuffer
+
+\startbuffer
+draw textext("\color[ta]{\tf Hello}") scaled 5 ;
+draw textext("\color[tb]{\bf Hello}") scaled 5 ;
+draw textext("\color[tc]{\sl Hello}") scaled 5 ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Shading}]
+
+\startsubsection[title=Introduction]
+
+\index{shading}
+
+In this section we introduce different kinds of shading. Since \METAPOST\ does
+not support this feature directly, we have to fall back on a few tricks. For the
+moment shading is only supported in \PDF. In the following examples, we will use
+the next three colors:
+
+\startbuffer
+\definecolor[a][darkyellow]
+\definecolor[b][s=.8]
+\definecolor[c][darkred]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+Shading support evolved in steps and alongside development of the backend code. Also,
+as it became more used a second interface came available. We discuss both here.
+
+\stopsubsection
+
+\startsubsection[title=The old method]
+
+First we discuss the old method which is still valid and also available in
+\MKII. It illustrates some of the principles.
+
+\startbuffer[a]
+\startuniqueMPgraphic{CircularShade}
+ path p ;
+ p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
+ circular_shade(p,0,\MPcolor{a},\MPcolor{b}) ;
+\stopuniqueMPgraphic
+
+\startuniqueMPgraphic{LinearShade}
+ path p ;
+ p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
+ linear_shade(p,0,\MPcolor{a},\MPcolor{b});
+\stopuniqueMPgraphic
+\stopbuffer
+
+\startbuffer[b]
+\defineoverlay[circular shade][\uniqueMPgraphic{CircularShade}]
+\defineoverlay[linear shade] [\uniqueMPgraphic{LinearShade}]
+\stopbuffer
+
+\startbuffer[c]
+\framed
+ [background=circular shade,frame=off]
+ {\bf \white Hi there, I'm Circular!}
+\stopbuffer
+
+\startbuffer[d]
+\framed
+ [background=linear shade,frame=off]
+ {\bf \white Whow, this is Linear!}
+\stopbuffer
+
+A shade is a fill with a stepwise change in color. In \POSTSCRIPT\ (level 2), the
+way this color changes can be circular, linear, or according to a user defined
+function. Circular and linear shades look like this:
+
+\startlinecorrection[blank]
+\getbuffer[a,b,c]
+\stoplinecorrection
+
+\startlinecorrection[blank]
+\getbuffer[a,b,d]
+\stoplinecorrection
+
+As you can see, the shade lays behind the text, as a background overlay. These
+overlays are unique \METAPOST\ graphics, so they will adapt themselves to the
+dimensions of the foreground.
+
+\typebuffer[b]
+
+The two framed texts are defined as:
+
+\typebuffer[c]
+
+and:
+
+\typebuffer[d]
+
+We still have to define the graphics. Here we use a macro that takes four
+arguments: a path, a number identifying the center of shading, and the colors to
+start and end with.
+
+\typebuffer[a]
+
+The \METAPOST\ macros, \type {circular_shade} and \type {linear_shade}, add
+information to the \METAPOST\ output file, which is interpreted by the converter
+built in \CONTEXT. Shading comes down to interpolation between two or more points
+or user supplied ranges. A poor mans way of doing this, is to build the graphics
+piecewise with slightly changing colors. But, instead of \quote {manually}
+stepping through the color values, we can use the more efficient and generalized
+\POSTSCRIPT\ level~2 and \PDF\ level~1.3 shading feature.
+
+\def\SomeShade#1#2#3% waarom unique ?
+ {\startuniqueMPgraphic{shade-#1}
+ width := \overlaywidth ;
+ height := \overlayheight ;
+ path p ; p := unitsquare xscaled width yscaled height ;
+ #2_shade(p,#3,\MPcolor{a},\MPcolor{b}) ;
+ \stopuniqueMPgraphic
+ \defineoverlay[shade-#1][\uniqueMPgraphic{shade-#1}]%
+ \framed[background=shade-#1,width=2cm,height=2cm,frame=off]{}}
+
+\startlinecorrection[blank]
+\startcombination[5*1]
+ {\SomeShade{20}{circular}{0}} {circular 0}
+ {\SomeShade{21}{circular}{1}} {circular 1}
+ {\SomeShade{22}{circular}{2}} {circular 2}
+ {\SomeShade{23}{circular}{3}} {circular 3}
+ {\SomeShade{24}{circular}{4}} {circular 4}
+\stopcombination
+\stoplinecorrection
+
+\startlinecorrection[blank]
+\startcombination[4*2]
+ {\SomeShade{32}{linear}{1}} {linear 1}
+ {\SomeShade{32}{linear}{2}} {linear 2}
+ {\SomeShade{33}{linear}{3}} {linear 3}
+ {\SomeShade{34}{linear}{4}} {linear 4}
+ {\SomeShade{35}{linear}{5}} {linear 5}
+ {\SomeShade{36}{linear}{6}} {linear 6}
+ {\SomeShade{37}{linear}{7}} {linear 7}
+ {\SomeShade{38}{linear}{8}} {linear 8}
+\stopcombination
+\stoplinecorrection
+
+% % This limitation si no longer present in mpiv.
+%
+% Shading is not a \METAPOST\ feature, which means that it has to be implemented
+% using so called specials, directives that end up in the output file.
+% Unfortunately these are not coupled to the specific path, which means that we
+% have to do a significant amount of internal bookkeeping. Also, in \PDF\ we have
+% to make sure that the graphics and their resources (being the shading functions)
+% are packaged together.
+%
+% Because of this implementation, shading may behave somewhat unexpected at times.
+% A rather normal case is the next one, where we place 5~shaded circles in a row.
+%
+% \startbuffer
+% path p ; p := fullcircle scaled 1cm ;
+% for i=0 step 2cm until 8cm :
+% circular_shade(p shifted (i,0),0,\MPcolor{a},\MPcolor{b}) ;
+% endfor ;
+% \stopbuffer
+%
+% \typebuffer
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% At first sight, in the next situation, we would expect something similar, because
+% we simply copy the same circle 5~times. However, due to the way we have
+% implemented shading in \CONTEXT, we do indeed copy the circles, but the shade
+% definition is frozen and the same one is used for all 5~circles. This means that
+% the center of the shading stays at the first circle.
+%
+% \startbuffer
+% circular_shade(fullcircle scaled 1cm,0,\MPcolor{a},\MPcolor{b}) ;
+% picture s ; s := currentpicture ; currentpicture := nullpicture ;
+% for i=0 step 2cm until 8cm :
+% addto currentpicture also s shifted (i,0) ;
+% endfor ;
+% \stopbuffer
+%
+% \typebuffer
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% Unlike \TEX, \METAPOST\ does not keep its specials attached to the current path,
+% and flushes them before the graphic data. Since we use these specials to register
+% shading information, it is rather hard to tightly connect a specific shade with a
+% certain fill, especially if an already performed fill is not accessible, which is
+% the case when we copy a picture.
+%
+% This may seem a disadvantage, but fortunately it also has its positive side. In
+% the next example we don't copy, but reuse an already defined shade. By storing
+% the reference to this shade, and referring to it by using \type {withshade}, we
+% can use a shade that operates on multiple shapes.
+
+\startbuffer
+sh := define_circular_shade
+ (origin,origin,0,8cm,\MPcolor{a},\MPcolor{b}) ;
+for i=0 step 2cm until 8cm :
+ fill fullcircle scaled 1cm shifted (i,0) withshade sh ;
+endfor ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The low level macro \type {define_circular_shade} is fed with two pairs (points),
+two radius, and two colors. The shade is distributed between the colors according
+to the radius.
+
+Shading can hardly be called an easy issue. The macros that we provide here are
+in fact simplifications, which means that at a lower level, one can do more
+advanced things. Here we limit ourselves to the more common cases. In the
+previous examples, we used an arrow to indicate the direction and magnitude of
+the shade. The next macro demonstrates the principles in a different way.
+
+\startbuffer[a]
+def test_shade (expr a, b, ra, rb) =
+ pickup pencircle scaled 1mm ;
+
+ color ca ; ca := \MPcolor{a} ;
+ color cb ; cb := \MPcolor{b} ;
+ color cc ; cc := \MPcolor{c} ;
+
+ path pa ; pa := fullcircle scaled 2ra shifted a ;
+ path pb ; pb := fullcircle scaled 2rb shifted b ;
+
+ sh := define_circular_shade(a,b,ra,rb,ca,cb) ;
+
+ fill pb withshade sh ;
+ draw pb withcolor cc ;
+ draw pa withcolor cc ;
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+The shade is distributed between two circles, each with a radius and center
+point. All four can be set, but as the next calls demonstrate, we can normally do
+with less, which is why we provided the macro with less parameters.
+
+\startbuffer[b]
+test_shade(origin, origin, 0cm, 1cm) ;
+\stopbuffer
+\startbuffer[c]
+test_shade(origin, origin, .25cm, 1cm) ;
+\stopbuffer
+\startbuffer[d]
+test_shade(origin, origin, .50cm, 1cm) ;
+\stopbuffer
+
+\startbuffer[f]
+\startlinecorrection[blank]
+\hbox
+ {\processMPbuffer[a,b]\quad
+ \processMPbuffer[a,c]\quad
+ \processMPbuffer[a,d]}
+\stoplinecorrection
+\stopbuffer
+
+\typebuffer[b,c,d] \getbuffer[f]
+
+\startbuffer[b]
+test_shade(origin, origin shifted (.25cm,0), 0cm, 1cm) ;
+\stopbuffer
+\startbuffer[c]
+test_shade(origin, origin shifted (.25cm,0), .25cm, 1cm) ;
+\stopbuffer
+\startbuffer[d]
+test_shade(origin, origin shifted (.25cm,0), .50cm, 1cm) ;
+\stopbuffer
+
+\typebuffer[b,c,d] \getbuffer[f]
+
+\startbuffer[b]
+test_shade(origin shifted (.25cm,0), origin, 0cm, 1cm) ;
+\stopbuffer
+\startbuffer[c]
+test_shade(origin shifted (.25cm,0), origin, .25cm, 1cm) ;
+\stopbuffer
+\startbuffer[d]
+test_shade(origin shifted (.25cm,0), origin, .50cm, 1cm) ;
+\stopbuffer
+
+\typebuffer[b,c,d] \getbuffer[f]
+
+\startbuffer[a]
+def test_shade (expr a, b) =
+ pickup pencircle scaled 1mm ;
+
+ color ca ; ca := \MPcolor{a} ;
+ color cb ; cb := \MPcolor{b} ;
+ color cc ; cc := \MPcolor{c} ;
+
+ sh := define_linear_shade(a,b,ca,cb) ;
+
+ fill fullsquare scaled 2cm withshade sh ;
+ draw a withcolor cc ;
+ draw b withcolor cc ;
+enddef ;
+\stopbuffer
+
+In a similar fashion, we can define a linear shade. This time we only pass two
+points and two colors.
+
+\typebuffer[a]
+
+Although one can control shading to a large extend, in practice only a few cases
+really make sense.
+
+\startbuffer[b]
+test_shade(origin, origin shifted (1cm,0)) ;
+\stopbuffer
+\startbuffer[c]
+test_shade(origin shifted (-1cm,0), origin shifted (1cm,0)) ;
+\stopbuffer
+\startbuffer[d]
+test_shade(origin shifted (-1cm,-1cm), origin shifted (1cm,1cm)) ;
+\stopbuffer
+
+\startbuffer[f]
+\startlinecorrection[blank]
+\hbox
+ {\processMPbuffer[a,b]\quad
+ \processMPbuffer[a,c]\quad
+ \processMPbuffer[a,d]}
+\stoplinecorrection
+\stopbuffer
+
+\typebuffer[b,c,d] \getbuffer[f]
+
+\stopsubsection
+
+\startsubsection[title=The new method]
+
+By now the shader macros are rather advanced and specifications are easier than
+before. Here we discuss the new method. An example is:
+
+\startbuffer
+fill fullsquare xyscaled (TextWidth,1cm)
+ withshademethod "linear"
+ withshadevector (1,0)
+ withshadecolors (darkred,darkgreen)
+;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+There are several properties that can be set:
+
+\starttabulate[|l|p|]
+\NC domain \NC The range over which the colors run, with a minimum of 0 and maximum of 1. \NC \NR
+\NC color \NC A color to start from and one to end with, we default from black to white. \NC \NR
+\NC type \NC The shading can be linear or circular. \NC \NR
+\NC center \NC The origin of the shade vector. \NC \NR
+\NC radius \NC The radius vector of a circular shade. \NC \NR
+\NC vector \NC Where we start and end the shading. \NC \NR
+\stoptabulate
+
+For a linear shade the centers are the lower left and upper right corners, for a
+circular shade it's the center of the path. For a circular shade the radius runs
+from zero to the maximum distance from the center as determined by the
+boundingbox.
+
+The vector is used as follows: the first coordinate (xpart) determines the point
+on the path where we start, the second coordinate (ypart) the point on the
+path where we end.
+
+\startbuffer[a]
+fill fullsquare xyscaled (TextWidth,1cm)
+ withshademethod "linear"
+ withshadevector (1,0)
+ withshadecolors (darkred,darkgreen)
+;
+\stopbuffer
+
+\startbuffer[b]
+draw fullsquare xyscaled (TextWidth,1cm)
+ shownshadevector (1,0)
+ withpen pencircle scaled 2
+ withcolor .5white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer[a,b]
+\stoplinecorrection
+
+In the end only the x coordinate matters, but using a point on the path sort of
+fits in \METAPOST. In the case of a rectangle we have 4 points while circle has 8
+points.
+
+\startbuffer[a]
+fill fullcircle xyscaled (TextWidth,1cm)
+ withshademethod "linear"
+ withshadevector (2,4)
+ withshadecolors (darkred,darkgreen)
+;
+\stopbuffer
+
+\startbuffer[b]
+draw fullcircle xyscaled (TextWidth,1cm)
+ shownshadevector (2,4)
+ withpen pencircle scaled 2
+ withcolor .5white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer[a,b]
+\stoplinecorrection
+
+A triangle has three points. Using 1 and 2 as second vector value gives the same
+results as do values in the range 0 upto 1 and 2 upto 3 (0 again).
+
+\startbuffer[a]
+fill fulltriangle xyscaled (TextWidth,1cm)
+ withshademethod "linear"
+ withshadevector (0.25,0.75)
+ withshadecolors (darkred,darkgreen)
+;
+\stopbuffer
+
+\startbuffer[b]
+draw fulltriangle xyscaled (TextWidth,1cm)
+ shownshadevector (0.25,0.75)
+ withpen pencircle scaled 2
+ withcolor .5white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer[a,b]
+\stoplinecorrection
+
+The shadevector relates to (the x coordinates of) points on the path. A variant is
+to use the boundingbox:
+
+\startbuffer[a]
+for i=1 upto 3 :
+ fill fulltriangle xyscaled (TextWidth,1cm)
+ shifted (0,-i*15mm)
+ withshademethod "linear"
+ withshadedirection (1,1-i/4)
+ withshadecolors (darkgreen,darkblue)
+ ;
+endfor ;
+\stopbuffer
+
+\startbuffer[b]
+for i=1 upto 3 :
+ draw fulltriangle xyscaled (TextWidth,1cm)
+ shifted (0,-i*15mm)
+ shownshadevector (1,1-i/4)
+ withpen pencircle scaled 2
+ withcolor .5white ;
+endfor ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startlinecorrection[blank]
+ \processMPbuffer[a,b]
+\stoplinecorrection
+
+So, where a vector is defined as going from {\em point xpart a of pth} to
+{\em point ypart a of pth}, a direction goes from {\em point xpart a of
+boundingbox pth} to {\em point ypart a of boundingbox pth}.
+
+To make life convenient we provide a few constants that indicate directions:
+
+\starttyping
+pair shadedup ; shadedup := (0.5,2.5) ;
+pair shadeddown ; shadeddown := (2.5,0.5) ;
+pair shadedleft ; shadedleft := (1.5,3.5) ;
+pair shadedright ; shadedright := (3.5,1.5) ;
+\stoptyping
+
+\startbuffer[a]
+for d = shadedup, shadeddown, shadedleft, shadedright :
+ fill fullsquare xyscaled (TextWidth,1cm)
+ withshademethod "linear"
+ withshadedirection d
+ withshadecolors (darkgreen,darkblue)
+ ;
+ currentpicture := currentpicture shifted (0,15mm) ;
+endfor ;
+\stopbuffer
+
+\startbuffer[b]
+currentpicture := currentpicture shifted (0,-60mm) ;
+for d = shadedup, shadeddown, shadedleft, shadedright :
+ draw fullsquare xyscaled (TextWidth,1cm)
+ shownshadedirection d
+ withpen pencircle scaled 2
+ withcolor .5white ;
+ currentpicture := currentpicture shifted (0,15mm) ;
+endfor ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startlinecorrection[blank]
+ \processMPbuffer[a,b]
+\stoplinecorrection
+
+In case of a circular shade another method comes in handy:
+
+\startbuffer[a]
+fill fullcircle xyscaled (TextWidth,4cm)
+ withshademethod "circular"
+ withshadecenter (.7,.9)
+ withshadecolors (darkblue,darkyellow)
+;
+\stopbuffer
+
+\startbuffer[b]
+draw fullcircle xyscaled (TextWidth,4cm)
+ shownshadecenter (.7,.9)
+ withpen pencircle scaled 2
+ withcolor .5white ;
+\stopbuffer
+
+\typebuffer
+
+Here the values relate to the center of path i.e.\ they shift the center by the
+given fraction of the width and height of the boundingbox devided by 2.
+
+\startlinecorrection[blank]
+ \processMPbuffer[a,b]
+\stoplinecorrection
+
+You can set a center directly i.e.\ unrelated to the center of the path as
+follows:
+
+\startbuffer[a]
+fill fullcircle xyscaled (TextWidth,4cm)
+ withshademethod "circular"
+ withshadeorigin (-30mm,-15mm)
+ withshadecolors (darkblue,darkyellow)
+;
+\stopbuffer
+
+\startbuffer[b]
+draw fullcircle xyscaled (TextWidth,4cm)
+ shownshadeorigin (-30mm,-15mm)
+ withpen pencircle scaled 2
+ withcolor .5white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer[a,b]
+\stoplinecorrection
+
+In a similar way you can set an explicit radius:
+
+\startbuffer[a]
+fill fullcircle xyscaled (TextWidth,1cm)
+ withshademethod "circular"
+ withshaderadius (10mm,50mm)
+ withshadecolors (darkblue,darkyellow)
+;
+currentpicture := currentpicture shifted (0,15mm) ;
+fill fullcircle xyscaled (TextWidth,1cm)
+ withshademethod "circular"
+ withshaderadius (50mm,10mm)
+ withshadecolors (darkgreen,darkred)
+;
+currentpicture := currentpicture shifted (0,15mm) ;
+fill fullcircle xyscaled (TextWidth,1cm)
+ withshademethod "circular"
+ withshaderadius (TextWidth/3,0mm)
+ withshadecolors (darkmagenta,darkcyan)
+;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer[a]
+\stoplinecorrection
+
+A more fancy feature is combined shades. This works as follows:
+
+\startbuffer[a]
+fill fullsquare xyscaled (TextWidth,1cm)
+ withshademethod "linear"
+ withshadevector (0,1)
+ withshadestep (
+ withshadefraction .3
+ withshadecolors (red,green)
+ )
+ withshadestep (
+ withshadefraction .5
+ withshadecolors (green,blue)
+ )
+ withshadestep (
+ withshadefraction .7
+ withshadecolors (blue,red)
+ )
+ withshadestep (
+ withshadefraction 1
+ withshadecolors (red,yellow)
+ )
+;
+\stopbuffer
+
+\typebuffer[a]
+
+By stepwise defining the colored bands you get:
+
+\startlinecorrection[blank]
+ \processMPbuffer[a]
+\stoplinecorrection
+
+Shades work well with colors and transparencies. This involves quite some
+resource managament in the backend but it's hidden by the interface.
+
+\startbuffer[a]
+fill fullsquare scaled 5cm
+ withshademethod "linear"
+ withshadefactor 1
+ withshadedomain (0,1)
+ withshadevector (0.5,2.75)
+ withshadecolors (red,green) ;
+
+fill fullcircle scaled 5cm
+ withshademethod "circular"
+ withshadefactor 1
+ withshadedomain (0,1)
+ withshadecenter (.25,.25)
+ withshadecolors (green,blue) ;
+
+fill fulltriangle scaled 5cm
+ withshademethod "circular"
+ withshadefactor 1
+ withshadedomain (0,1)
+ withshadecenter (.25,.25)
+ withshadecolors (blue,yellow) ;
+\stopbuffer
+
+\startbuffer[b]
+fill fullsquare scaled 5cm
+ withcolor white ;
+fill fullsquare scaled 5cm
+ withshademethod "linear"
+ withshadevector (0.5,2.75)
+ withshadecolors (red,green)
+ withtransparency (1,.5) ;
+
+fill fullcircle scaled 5cm
+ withcolor white ;
+fill fullcircle scaled 5cm
+ withshademethod "circular"
+ withshadecenter (.25,.25)
+ withshadecolors (green,blue)
+ withtransparency (1,.5) ;
+
+fill fulltriangle scaled 5cm
+ withcolor white ;
+fill fulltriangle scaled 5cm
+ withshademethod "circular"
+ withshadecenter (.25,.25)
+ withcolor blue shadedinto yellow
+ withtransparency (1,.5) ;
+\stopbuffer
+
+\startbuffer[c]
+fill fullsquare scaled 5cm
+ withshademethod "linear"
+ withshadevector (0.5,2.75)
+ withshadecolors (red,green)
+ withtransparency (1,.5) ;
+
+fill fullcircle scaled 5cm
+ withshademethod "circular"
+ withshadecenter (.25,.25)
+ withcolor green shadedinto blue
+ withtransparency (1,.5) ;
+
+fill fulltriangle scaled 5cm
+ withshademethod "circular"
+ withshadecenter (.25,.25)
+ withcolor blue shadedinto yellow
+ withtransparency (1,.5) ;
+\stopbuffer
+
+Here are some shades without transparency:
+
+\typebuffer[a]
+
+When the background is white, transparency is just a way to achieve soft colors.
+We leave out the defaults.
+
+\typebuffer[b]
+
+Real transparency will show op darker due to the accumulated colors. This time we
+demonstrate an alternative color specification.
+
+\typebuffer[c]
+
+\startplacefigure[reference=shades:transparency,title={Transparency applied to shades.}]
+ \startcombination[3*1]
+ {\processMPbuffer[a]} {no transparency}
+ {\processMPbuffer[b]} {transparency on white}
+ {\processMPbuffer[c]} {real transparency}
+ \stopcombination
+\stopplacefigure
+
+Within reasonable bounds you can move around and adapt shaded paths but you need
+to keep in mind that due to the fact that we are dealing with relatively complex
+data structures there are some limits. For instance it is possible to define a
+shade as (kind of) variable and reuse it. it's also possible then to overload
+some properties.
+
+% % still supported but not advertized:
+%
+% numeric n ; n = define_linear_shade (center fullcircle,center fullsquare,red,green) ;
+%
+% fill fullcircle randomized 1cm xyscaled(10cm,8cm) withshade n ;
+
+\startbuffer
+defineshade myshade
+ withshademethod "circular"
+ withshadefactor 1
+ withshadedomain (0,1)
+ withshadecolors (black,white)
+ withtransparency (1,.5)
+;
+
+for i=1 upto 5 :
+ fill fullcircle randomized 1 xyscaled(5cm,3cm)
+ shaded myshade ;
+endfor ;
+
+draw image (
+ for i=1 upto 5 :
+ fill fullcircle randomized 1
+ shaded myshade
+ withshadecolors (yellow,blue) ;
+ endfor ;
+) xyscaled(5cm,3cm) shifted (5cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+We get two groups of five overlayed shades here, one with a different color. The
+shade properties can only be applied to paths (see \in {figure}
+[fig:shades:defined]).
+
+\startplacefigure[reference=fig:shades:defined,title={Reusing defined shaded.}]
+ \processMPbuffer
+\stopplacefigure
+
+In older versions one could not reposition or scale a shaded path without losing
+or crippling the shade properties. Nowadays this is no longer a limitation, as we
+demonstrate in the following examples. You can disable this feature if wanted.
+The results are shown in \in {figure} [fig:shades:transform]. Without the
+transform the vectors and such are kept which might be useful in special cases.
+
+\startbuffer[a]
+fill fullsquare xyscaled (15mm, 15mm)
+ withshademethod "linear"
+ withshadedirection shadedright
+ withshadecolors (red,(1,1,1)) ;
+
+fill fullsquare xyscaled (10mm, 10mm)
+ withshademethod "circular"
+ withshadecolors (green,blue) ;
+
+currentpicture := currentpicture xysized (.4TextWidth,30mm) ;
+currentpicture := currentpicture shifted (5mm,5mm) ;
+\stopbuffer
+
+\typebuffer[a]
+
+The transform can be ignored with:
+
+\startbuffer[b]
+fill fullsquare xyscaled (15mm, 15mm)
+ withshademethod "linear"
+ withshadetransform "no"
+ withshadedirection shadedright
+ withshadecolors (red,(1,1,1)) ;
+
+fill fullsquare xyscaled (10mm, 10mm)
+ withshademethod "circular"
+ withshadetransform "no"
+ withshadecolors (green,blue) ;
+
+currentpicture := currentpicture xysized (.4TextWidth,30mm) ;
+currentpicture := currentpicture shifted (5mm,5mm) ;
+\stopbuffer
+
+\typebuffer[b]
+
+\startplacefigure[reference=fig:shades:transform,title={Shifting and scaling shades.}]
+ \startcombination
+ {\processMPbuffer[a]} {with transform}
+ {\processMPbuffer[b]} {without transform}
+ \stopcombination
+\stopplacefigure
+
+\stopsubsection
+
+\stopsection
+
+\startsection[title={Clipping}]
+
+\index{clipping}
+
+In this section we will use the graphic representation (although simplified) of a
+Dutch cow to demonstrate clipping.
+
+\startbuffer
+\placefigure
+ {A cow.}
+ {\externalfigure[cow-fun.mps][width=4cm]}
+\stopbuffer
+
+\getbuffer
+
+Since this cow is defined as a \METAPOST\ graphic, we use the suffix \type {mps}
+instead of \type {eps} or a number, although \CONTEXT\ will recognize each as
+being \METAPOST\ output. The placement of the cow is defined as:
+
+\typebuffer
+
+Clipping is combined with a matrix, as in \in {figure} [fig:clipped cow 1]. The
+content to be clipped is divided in \type {nx} by \type {ny} rectangles. For
+instance, \type {nx=5} and \type {ny=8} will produce a 40~cell grid with
+5~columns of 8~rows.
+
+\startbuffer
+\startbuffer
+\setupclipping[nx=3,ny=2]
+\startcombination
+ {\clip[x=1,y=1]{\externalfigure[cow-fun.mps][width=4cm]}} {1,1}
+ {\clip[x=3,y=1]{\externalfigure[cow-fun.mps][width=4cm]}} {3,1}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:clipped cow 1]
+ {A clipped cow.}{\getbuffer}
+\stopbuffer
+
+\getbuffer
+
+Here we have divided the cow in six cells, so that we can clip its head and tail.
+This kind of clipping enables you to zoom in or focus on a specific part of a
+graphic.
+
+\typebuffer
+
+Alternatively, we can specify a \type {width}, \type {height}, \type {hoffset}
+and \type {voffset}, as demonstrated in \in {figure} [fig:clipped cow 2].
+
+\startbuffer
+\placefigure
+ [here][fig:clipped cow 2]
+ {Another clipped cow.}
+ {\clip
+ [width=2cm,height=2cm,hoffset=0cm,voffset=0cm]
+ {\externalfigure[cow-fun.mps][width=4cm]}}
+\stopbuffer
+
+\getbuffer
+
+\typebuffer
+
+Because \METAPOST\ supports clipping, it will be no surprise that both techniques
+can be combined. In the next example we will zoom in on the head of the cow. We
+also use this opportunity to demonstrate how you can package a clip in a figure
+definition.
+
+\startbuffer
+\startMPclip{head clip}
+ w := \width ; h := \height ;
+ clip currentpicture to
+ ((0,h)--(w,h){down}..{left}(0,0)--cycle) ;
+\stopMPclip
+
+\placefigure
+ [here][fig:circular clipped cowhead]
+ {A quarter circle applied to a cows head.}
+ {\ruledhbox
+ {\clip
+ [nx=2,ny=2,x=1,y=1,mp=head clip]
+ {\externalfigure[cow-fun.mps][width=4cm]}}}
+\stopbuffer
+
+\typebuffer
+
+A more advanced clip is demonstrated in \in {figure} [fig:circular clipped
+cowhead]. We added \type {\ruledhbox} to demonstrate the dimensions of the
+resulting graphic. Putting something in such a ruled box is often a quick way to
+test spacing.
+
+\getbuffer
+
+Although a clip path definition can contain any \METAPOST\ command, even
+graphics, it must contain at least one clipping path. The first one encountered
+in the resulting graphic is used. In the example we used a path that is built out
+of three subpaths.
+
+\starttyping
+(0,h)--(w,h){down}..{left}(0,0)--cycle
+\stoptyping
+
+We start in the top left corner and draw a straight line. Next we draw a curve to
+the origin. Directives like \type {down} and \type {right} force the curve in a
+certain direction. With \type {cycle} we close the path. Because we use this path
+as a clipping path, we use \type {clip} instead of \type {draw} or \type {fill}.
+
+\startbuffer
+w := 4cm ; h := 2cm ;
+draw (0,h)--(w,h){down}..{left}(0,0)--cycle
+ withpen pencircle scaled 1mm withcolor .625red ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Clipping as such is not limited to graphics. Take for instance the text buffer:
+
+\startbuffer
+\startbuffer[sample]
+\framed
+ [align=middle,width=4cm,background=screen,frame=off]
+ {A \METAPOST\ clip is not the same as a video clip,
+ although we can use \METAPOST\ to produce a video clip.}
+\stopbuffer
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+We can call up such a buffer as if it were an external figure. \in {Figure}
+[fig:clipped text 1] shows the result. This time we use a different clip path:
+
+\startbuffer[a]
+\startMPclip{text clip}
+ clip currentpicture to fullcircle shifted (.5,.5)
+ xscaled \width yscaled \height ;
+\stopMPclip
+\stopbuffer
+
+\typebuffer[a]
+
+To load a buffer, we have to specify its name and type, as in:
+
+\startbuffer[b]
+\placefigure
+ [here][fig:clipped text 1]
+ {A clipped buffer (text).}
+ {\clip
+ [nx=1,ny=1,mp=text clip]
+ {\externalfigure[sample][type=buffer,width=4cm]}}
+\stopbuffer
+
+\typebuffer[b]
+
+\getbuffer[a,b]
+
+The next few lines demonstrate that we can combine techniques like backgrounds
+and clipping.
+
+\startbuffer
+\startuseMPgraphic{clip outline}
+ draw fullcircle
+ xscaled \overlaywidth yscaled \overlayheight
+ withpen pencircle scaled 4mm
+ withcolor .625red ;
+\stopuseMPgraphic
+
+\defineoverlay[clip outline][\useMPgraphic{clip outline}]
+
+\placefigure
+ [here][fig:clipped text 2]
+ {A clipped buffer (text).}
+ {\framed
+ [background=clip outline,offset=overlay,frame=off]
+ {\clip
+ [nx=1,ny=1,mp=text clip]
+ {\externalfigure[sample][type=buffer,width=4cm]}}}
+\stopbuffer
+
+\typebuffer
+
+We could have avoided the \type {\framed} here, by using the \typ{clip outline}
+overlay as a background of the sample. In that case, the resulting linewidth
+would have been 2.5~mm instead of 5~mm, since the clipping path goes through the
+center of the line.
+
+\getbuffer
+
+In most cases, the clip path will be a rather simple path and defining such a
+path every time you need it, can be annoying. \in {Figure} [fig:clipping paths]
+shows a collection of predefined clipping paths. These are available after
+loading the \METAPOST\ clipping library.
+
+\starttyping
+\useMPlibrary[clp]
+\stoptyping
+
+We already saw how the circular clipping path was defined. The diamond is defined
+in a similar way, using the predefined path \type {diamond}:
+
+\starttyping
+\startMPclip{diamond}
+ clip currentpicture to unitdiamond
+ xscaled \width yscaled \height ;
+\stopMPclip
+\stoptyping
+
+The definition of the negated ellipse (\type {negellipse}) uses the primary \type
+{peepholed}. This primary is defined in one of the \METAPOST\ modules that come
+with \CONTEXT.
+
+\starttyping
+\startMPclip{negellipse}
+ clip currentpicture to (unitcircle peepholed unitsquare)
+ xscaled \width yscaled \height ;
+\stopMPclip
+\stoptyping
+
+The definition of \type {peepholed} is rather dirty and using \type {peepholed}
+is restricted to well defined situations (like here). It's called a primary
+because it acts as an operator at the same level as \type {*} and \type {scaled}.
+
+\startbuffer
+\setupclipping [nx=1,ny=1,x=1,y=1]
+\setupblackrules[width=2cm,height=1cm]
+\startcombination[6*3]
+ {\clip[mp=urellipse] {\darkred\blackrule}} {urellipse}
+ {\clip[mp=ulellipse] {\darkred\blackrule}} {ulellipse}
+ {\clip[mp=llellipse] {\darkred\blackrule}} {llellipse}
+ {\clip[mp=lrellipse] {\darkred\blackrule}} {lrellipse}
+ {\clip[mp=ellipse] {\darkred\blackrule}} {ellipse}
+ {\clip[mp=negellipse]{\darkred\blackrule}} {negellipse}
+ {\clip[mp=tellipse] {\darkred\blackrule}} {tellipse}
+ {\clip[mp=bellipse] {\darkred\blackrule}} {bellipse}
+ {\clip[mp=lellipse] {\darkred\blackrule}} {lellipse}
+ {\clip[mp=rellipse] {\darkred\blackrule}} {rellipse}
+ {} {}
+ {} {}
+ {\clip[mp=urtriangle]{\darkred\blackrule}} {urtriangle}
+ {\clip[mp=ultriangle]{\darkred\blackrule}} {ultriangle}
+ {\clip[mp=lltriangle]{\darkred\blackrule}} {lltriangle}
+ {\clip[mp=lrtriangle]{\darkred\blackrule}} {lrtriangle}
+ {\clip[mp=diamond] {\darkred\blackrule}} {diamond}
+ {\clip[mp=negdiamond]{\darkred\blackrule}} {negdiamond}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:clipping paths]
+ {A collection of predefined clipping paths.}
+ {\getbuffer}
+
+\stopsection
+
+\startsection[title={Including graphics}]
+
+\index{graphics+including}
+
+This document demonstrates that it is no big problem to include \METAPOST\
+graphics in a \TEX\ document. But how about including graphics in a \METAPOST\
+picture? In this section we will explore a couple of macros that provide you this
+feature.
+
+Before we go into details, we introduce a very impressive program called
+\PSTOEDIT\ by Wolfgang Glunz. This program runs on top of \GHOSTSCRIPT\ and is
+able to convert \POSTSCRIPT\ code into other formats, among them \METAPOST\ (that
+part of the \PSTOEDIT\ code is due to Scott Pakin). Some of the graphics that we
+use in this section are produced that way. For us, the next call works well, but
+the exact call may differ per version or platform.
+
+\starttyping
+pstoedit -ssp -dt -f mpost yourfile.ps newfile.mp
+\stoptyping
+
+We have converted the Dutch cow that shows up in many \CONTEXT\ documents into
+\METAPOST\ using this program. The resulting \METAPOST\ file encapsulates the cow
+in \METAPOST\ figure~1: \type {beginfig(1)}. Of course you can process this file
+like any other, but more interesting is to use this code in an indirect way.
+
+\startbuffer
+loadfigure "mycow.mp" number 1 scaled .5 ;
+\stopbuffer
+
+\typebuffer
+
+This call will load figure~1 from the specified \METAPOST\ file, in such a way
+that there is no interference with the current (encapsulating) figure.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Because this graphic is the result from a conversion, there are only paths. If
+you want to import a more complex graphic, you need to make sure that the
+variables used in there do not conflict with the one currently in use.
+
+\METAPOST\ is good in drawing vector graphics, but lacks natural support for
+bitmaps, but the next macro offers a way out. This macro permits you to include
+graphics in \PNG, \PDF, and \JPG\ format, or more precise: those formats
+supported by \PDFTEX.\pagereference[hacker]
+
+\startbuffer
+draw externalfigure "hacker.png" scaled 5cm shifted (-6cm,0) ;
+draw externalfigure "hacker.png" scaled 5cm slanted .5 ;
+\stopbuffer
+
+\typebuffer
+
+You can apply the usual transformations, but only those applied directly will be
+taken into account. This means that you (currently) cannot store external figures
+in picture variables in order to transform them afterwards.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Although you are limited in what you can do with such graphics, you can include
+them multiple times with a minimum of overhead. Graphics are stored in objects
+and embedded only once.
+
+\startbuffer
+numeric s ; pair d, c ;
+for i := 1 upto 5 :
+ s := 3cm randomized 1cm ; % size of picture
+ c := .5(s,s) ; % center of picture
+ d := (2cm*i,.5cm) randomized .5cm ; % displacement
+ draw externalfigure "hacker.png"
+ scaled s rotatedaround (c,0 randomized 30) shifted d ;
+endfor ;
+\stopbuffer
+
+\typebuffer
+
+Because we cannot store the graphic in a picture and scale afterwards, we
+calculate the scale in advance, so that we can rotate around the center.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+As long as you don't mess around with a stored external figure, you're safe. The
+following example demonstrates how we can combine two special driven features:
+figure inclusion and shading.
+
+\startbuffer
+picture p ;
+p := externalfigure "hacker.png" scaled 150pt ;
+clip p to unitcircle scaled 150pt ;
+circular_shade(boundingbox p enlarged 10pt, 0, .2red, .9red) ;
+addto currentpicture also p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+We end this section with a few more words to \METAPOST\ inclusion. It may seem
+that in order to use the features discussed here, you need to use \CONTEXT\ as
+typesetting engine. This is not true. First of all, you can use the small \TEX\
+package \MPTOPDF\ (described in another manual) or you can make small \CONTEXT\
+files with one page graphics. The advantage of the last method is that you can
+manipulate graphics a bit.
+
+\starttyping
+\setupcolors[cmyk=yes,rgb=no,state=start]
+
+\starttext
+
+\startMPpage[offset=6pt]
+ loadfigure "niceone.mp" number 10 ;
+\stopMPpage
+
+\stoptext
+\stoptyping
+
+The resulting \PDF\ file can be included as any other graphic
+and has the advantage that it is self contained.
+
+\stopsection
+
+\startsection[reference=sec:conversion,title={Changing colors}]
+
+\index{color+manipulating}
+
+One of the advantages of \METAPOST\ graphics is that it is rather easy to force
+consistency in colors and line widths. You seldom can influence third party
+graphics that way, but we can use some \METAFUN\ trickery to get around this
+limitation.
+
+\startbuffer
+loadfigure "mycow.mp" number 1 scaled .35 ;
+refill currentpicture withcolor .625red ;
+\stopbuffer
+
+Say that we want a red cow instead of a black one. The following code does the
+trick:
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+In a similar way we can influence the width and colors of the lines.
+
+\startbuffer
+loadfigure "mycow.mp" number 1 scaled .35 ;
+refill currentpicture withcolor .625red ;
+redraw currentpicture withpen pencircle scaled 2pt withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Of course we can also use the more fancy features of \METAFUN, like transparency
+and shading.
+
+\startbuffer
+loadfigure "mycow.mp" number 1 scaled .35 ;
+numeric sh ; sh := define_linear_shade
+ (llcorner currentpicture,urcorner currentpicture,.625red, .625yellow) ;
+refill currentpicture withshade sh ;
+redraw currentpicture withpen pencircle scaled 2pt withcolor .5white;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Before we show a next trick, we draw a few circles.
+
+\startbuffer[a]
+fill fullcircle scaled 2cm withcolor yellow ;
+fill fullcircle scaled 2cm shifted (3cm,0) withcolor red ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+The yellow and red color do not match the main document colors, but this is no
+problem: we can remap them, without spoiling the original definition.
+
+\startbuffer[b]
+remapcolor(yellow,.625yellow) ;
+remapcolor(red ,.625red) ;
+recolor currentpicture ;
+resetcolormap ;
+\stopbuffer
+
+\typebuffer[a,b]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+We can combine the inclusion technique with remapping colors. This time using an
+artist impression of one of Hasselts Canals (gracht in Dutch)\pagereference
+[canal].
+
+\startbuffer[a]
+loadfigure "gracht.mp" number 1 scaled .5 ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+If you think that the sky is too bright in this picture, and given that you also
+know which color is used, you can fool the reader by remapping a few colors.
+
+\startbuffer[b]
+color skycolor ; skycolor := (0.8,0.90,1.0) ;
+color watercolor ; watercolor := (0.9,0.95,1.0) ;
+remapcolor(skycolor ,.8skycolor ) ;
+remapcolor(watercolor,.8watercolor) ;
+recolor currentpicture ;
+resetcolormap ;
+\stopbuffer
+
+\typebuffer[a,b]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+Including another \METAPOST\ graphic, refilling, redrawing, and recoloring are
+all relatively simple features that use no real tricks. Opposite to the next
+feature, which is implemented using the \METAPOST\ special driver that comes with
+\CONTEXT.
+
+\METAPOST\ is not really meant for manipulating graphics, but the previous
+examples demonstrated that we have some control over individual colors. In the
+next series of examples we will treat the picture as a whole. First we invert the
+colors using \type {inverted}.
+
+\startbuffer
+loadfigure "gracht.mp" number 1 scaled .5 ;
+addto currentpicture also
+ inverted currentpicture
+ shifted (bbwidth(currentpicture)+.5cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+This is a special case of \type {uncolored}. In the next example we explicitly
+specify the color.
+
+\startbuffer
+loadfigure "gracht.mp" number 1 scaled .5 ;
+addto currentpicture also
+ (currentpicture uncolored green)
+ shifted (bbwidth(currentpicture)+.5cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+You can also multiply each color using \type {softened}. In the next sample, the
+colors have 80\% of their value.
+
+\startbuffer
+loadfigure "gracht.mp" number 1 scaled .5 ;
+addto currentpicture also
+ (currentpicture softened .8)
+ shifted (bbwidth(currentpicture)+.5cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+You can also use this operator to harden colors, simply by
+providing a value larger than~1. Keep in mind that colors
+are clipped at~1 anyway.
+
+\startbuffer
+loadfigure "gracht.mp" number 1 scaled .5 ;
+addto currentpicture also
+ (currentpicture softened 1.2)
+ shifted (bbwidth(currentpicture)+.5cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+By providing a triplet, you can treat each color component
+independently.
+
+\startbuffer
+loadfigure "gracht.mp" number 1 scaled .5 ;
+addto currentpicture also
+ (currentpicture softened (.7,.8,.9))
+ shifted (bbwidth(currentpicture)+.5cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+After these examples your are probably sick of seeing this picture in color, so
+let's turn the colors into a weigthed grayscales (in a way similar to the way
+black and white television treated color).
+
+\startbuffer
+loadfigure "gracht.mp" number 1 scaled .5 ;
+addto currentpicture also
+ grayed currentpicture
+ shifted (bbwidth(currentpicture)+.5cm,0) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+\stopsection
+
+% \startsection[title={Outline fonts}]
+%
+% \index{text+outlines}
+% \index{outlines}
+%
+% Outline fonts don't belong to \METAPOST's repertoire of features. Nevertheless we
+% can simulate this in a reasonable way. We will not discuss all details here,
+% because most details are covered in the \MAKEMPY\ manual.
+%
+% The macro responsible for outline fonts is \type {graphictext}. The first
+% argument should be a string. This string is processed by \TEX. Additionally you
+% can provide transformation directives and color specifications. The next example
+% demonstrates this.
+%
+% \startbuffer
+% graphictext "\bf Fun" scaled 4 zscaled (1,1.5)
+% withdrawcolor blue
+% withfillcolor .5white
+% withpen pencircle scaled 5pt
+% \stopbuffer
+%
+% \typebuffer
+%
+% Once the text is typeset by \TEX, it is converted to \POSTSCRIPT\ and converted
+% into \METAPOST\ by the \PSTOEDIT\ program. The resulting graphic is imported,
+% analyzed, and processed conforming the specifications of \type {graphictext}.
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% By default the shapes are filled after they are drawn. This has the advantage
+% that in characters built out of pieces, disturbing lines fragments are covered.
+% The drawback is that you get only half the linewidth. You can reverse the drawing
+% order by adding the \type {reversefill} directive. The previous graphic then
+% comes out as:
+%
+% \startbuffer
+% graphictext "\bf Fun" scaled 4 zscaled (1,1.5)
+% reversefill
+% withdrawcolor blue
+% withfillcolor .5white
+% withpen pencircle scaled 5pt
+% \stopbuffer
+%
+% \typebuffer
+%
+% The \type {reversefill} directive can be countered by \type {outlinefill}.
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% The next example is taken from the \MAKEMPY\ manual. It demonstrates that you can
+% combine \TEX's powerful line breaking with \METAPOST's graphic capabilities.
+%
+% \startbuffer
+% \startuseMPgraphic{quotation}
+% picture one ; one := image ( graphictext
+% \MPstring{text}
+% scaled 1.5
+% withdrawcolor .625blue
+% withfillcolor .625white
+% withpen pencircle scaled 1pt ; ) ;
+% picture two ; two := image ( graphictext
+% \MPstring{author}
+% scaled 2
+% withdrawcolor .625red
+% withfillcolor .625white
+% withpen pencircle scaled 2pt ; ) ;
+% currentpicture := one ;
+% addto currentpicture also two
+% shifted lrcorner one
+% shifted - 1.125 lrcorner two
+% shifted (0, - 1.250 * ypart urcorner two) ;
+% setbounds currentpicture to boundingbox currentpicture enlarged 3pt ;
+% \stopuseMPgraphic
+% \stopbuffer
+%
+% \typebuffer \getbuffer
+%
+% In this graphic, we have two text fragments, the first one is a text, the second
+% one the name of the author. We combine the quotation and author into this graphic
+% using the following definitions:
+%
+% \startbuffer
+% \setMPtext{text} {\vbox{\hsize 8.5cm \input zapf }}
+% \setMPtext{author}{\hbox{\sl Hermann Zapf}}
+% \stopbuffer
+%
+% \typebuffer \getbuffer
+%
+% These definitions assume that the file \type {zapf.tex} is present on the system
+% (which is the case when you have installed \CONTEXT). The graphic can now be
+% typeset using the following call:
+%
+% \startbuffer
+% \placefigure
+% {A text does not need to be an outline in order to be
+% typeset in an outline font.}
+% {\useMPgraphic{quotation}}
+% \stopbuffer
+%
+% \typebuffer \getbuffer
+%
+% The quality of the output depends on how the glyphs are constructed. For
+% instance, in \TEX, math symbols are sometimes composed of glyph fragments and
+% rules.
+%
+% \startbuffer
+% graphictext
+% "$$\sqrt{1+x}$$"
+% scaled 8
+% withdrawcolor .625red
+% withpen pencircle scaled 1.5pt
+% \stopbuffer
+%
+% \typebuffer
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% This is not really a problem because we can also fill the shapes. It is the
+% reason why the fill is applied after the draw and in such case the effective line
+% width is half the size specified.
+%
+% \startbuffer
+% graphictext
+% "$$\left({{\sqrt{1+x}}\over{\sqrt{2+x^2}}}\right)$$"
+% scaled 4
+% dashed evenly
+% withdrawcolor .625red
+% withfillcolor .850white
+% withpen pencircle scaled 1.5pt
+% \stopbuffer
+%
+% \typebuffer
+%
+% In this example we also use a dashed line. Instead of normal colors, we could
+% have used shades or transparent colors.
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% Instead of supplying the text directly, you can use the indirect method. This
+% permits you to process rather complex data without messing up your \METAPOST\
+% code.
+%
+% \startbuffer
+% \setMPtext {some math}%
+% {\usemodule[mathml]
+% \xmlprocessdata
+% {main}
+% {<math xmlns='http://www.w3c.org/mathml' version='2.0'>
+% <apply> <log/>
+% <logbase> <cn> 2 </cn> </logbase>
+% <apply> <plus/>
+% <ci> x </ci>
+% <cn> 1 </cn>
+% </apply>
+% </apply>
+% </math>}
+% {}}
+% \stopbuffer
+%
+% \typebuffer \getbuffer
+%
+% Here we feed some \MATHML\ into \TEX, which in turn shows up as a \METAPOST\
+% graphic.
+%
+% \startbuffer
+% graphictext
+% \MPstring{some math}
+% scaled 4
+% withdrawcolor .625red
+% withfillcolor .625white
+% withpen pencircle scaled 1.5pt
+% \stopbuffer
+%
+% \typebuffer
+%
+% \startlinecorrection[blank]
+% \processMPbuffer
+% \stoplinecorrection
+%
+% \stopsection
+
+\startsection[title={Outline fonts}]
+
+\index{text+outlines}
+\index{outlines}
+
+Outline fonts don't belong to \METAPOST's repertoire of features. Nevertheless we
+can simulate this in a reasonable way. The current version of \METAFUN\ uses the
+outline subsystem of \CONTEXT\ \MKIV, but in earlier days we used an external
+process: a \PDF\ file is generated that has the snippet, that gets converted to
+\POSTSCRIPT, which in turn is converted to \METAPOST\ with \type {pstoedit} and
+from that result we filter the outlines. This method uses \type {graphictext} and
+is covered in the \MAKEMPY\ manual. Here we discuss the new method using \type
+{outlinetext}.
+
+\startbuffer
+draw outlinetext.b("\bf Funky")
+ (withcolor .5white)
+ (withcolor blue withpen pencircle scaled 1/5)
+ scaled 4 zscaled (1,0.5) ;
+\stopbuffer
+
+\typebuffer
+
+Once the text is typeset by \TEX, the result (a node list) is parsed and a
+\METAPOST\ representation is created. The glyphs are converted to outlines that
+are taken from the original font. For the moment this only works for \OPENTYPE\
+fonts.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\startbuffer[1]
+draw outlinetext ("\bf Funky")
+ scaled 3 ;
+\stopbuffer
+
+\startbuffer[2]
+draw outlinetext.d ("\bf Funky")
+ (withcolor red withpen pencircle scaled 1/5)
+ scaled 3 ;
+\stopbuffer
+
+\startbuffer[3]
+draw outlinetext.f ("\bf Funky")
+ (withcolor blue)
+ scaled 3 ;
+\stopbuffer
+
+\startbuffer[4]
+draw outlinetext.b ("\bf Funky")
+ (withcolor blue)
+ (withcolor red withpen pencircle scaled 1/5)
+ scaled 3 ;
+\stopbuffer
+
+\startbuffer[5]
+draw outlinetext.r ("\bf Funky")
+ (withcolor blue)
+ (withcolor red withpen pencircle scaled 1/5)
+ scaled 3 ;
+\stopbuffer
+
+\startplacetable[reference=tab:outlinetext,title={The four variants of \type {graphictext}.}]
+ \bTABLE[offset=1ex]
+ \dorecurse{5}{\bTR \bTD \processMPbuffer[#1] \eTD \bTD \typebuffer[#1] \eTD \eTR}
+ \eTABLE
+\stopplacetable
+
+The five variants of this command are shown in \in {table} [tab:outlinetext]: the
+suffix determines the number of arguments and rendering. The \type {r} suffix
+reverses the order: the fill comes over the draw. There is a \type {p} suffix
+that returns just the picture.
+
+The next example demonstrates that you can combine \TEX's powerful line breaking
+algorithm with \METAPOST's graphic capabilities.
+
+\startbuffer
+\startuseMPgraphic{quotation}
+ picture one ; one := image ( draw outlinetext.b
+ (\MPstring{text})
+ (withcolor .625white)
+ (withcolor .625blue withpen pencircle scaled 1/5)
+ scaled 1.5
+ ) ;
+ picture two ; two := image ( draw outlinetext.b
+ (\MPstring{author})
+ (withcolor .625white)
+ (withcolor .625red withpen pencircle scaled 1/5)
+ scaled 2
+ ) ;
+ currentpicture := one ;
+ addto currentpicture also two
+ shifted lrcorner one
+ shifted - 1.125 lrcorner two
+ shifted (0, - 2 * ypart urcorner two) ;
+ setbounds currentpicture to boundingbox currentpicture enlarged 3pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+In this graphic, we have two text fragments, the first one is a text, the second
+one the name of the author. We combine the quotation and author into this graphic
+using the following definitions:
+
+\startbuffer
+\setMPtext
+ {text}
+ {\vbox
+ {\setupalign[verytolerant,stretch]
+ \hsize 8.5cm
+ \input zapf }}
+\setMPtext
+ {author}
+ {\hbox
+ {\sl Hermann Zapf}}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+These definitions assume that the file \type {zapf.tex} is present on the system
+(which is the case when you have installed \CONTEXT). The graphic can now be
+typeset using the following call:
+
+\startbuffer
+\placefigure
+ [here]
+ [fig:zapf]
+ {A text does not need to be an outline in order to be
+ typeset in an outline font.}
+ {\useMPgraphic{quotation}}
+\stopbuffer
+
+\typebuffer
+
+The result is \in {figure} [fig:zapf]. The quality of the output depends on how
+the glyphs are constructed. For instance, in \TEX, math symbols are sometimes
+composed of glyph fragments and rules.
+
+\start
+ \def||{-}
+ \getbuffer
+\stop
+
+\startbuffer
+draw outlinetext.d
+ ("\mathematics{\sqrt{1+x}}")
+ (withcolor .625red withpen pencircle scaled 1/5)
+ scaled 8
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+This is not really a problem because we can also fill the shapes. It is the
+reason why the fill is applied after the draw and in such case the effective line
+width is half the size specified.
+
+\startbuffer
+draw outlinetext.b
+ ("\mathematics{\left({{\sqrt{1+x}}\over{\sqrt{2+x^2}}}\right)}")
+ (withcolor .850white)
+ (withcolor .625red
+ dashed evenly scaled .1
+ withpen pencircle scaled 1/5)
+ scaled 8
+\stopbuffer
+
+\typebuffer
+
+In this example (shown in \in {figure} [fig:dashedoutline]) we also use a dashed
+line.
+
+\placefigure
+ [here]
+ [fig:dashedoutline]
+ {A dashed outline text.}
+ {\processMPbuffer}
+
+Instead of supplying the text directly, you can use the indirect method. This
+permits you to process rather complex data without messing up your \METAPOST\
+code.
+
+\startbuffer
+\usemodule[mathml]
+
+\setMPtext {some math}%
+ {\xmlprocessdata
+ {main}
+ {<math xmlns='http://www.w3c.org/mathml' version='2.0'>
+ <apply> <log/>
+ <logbase> <cn> 2 </cn> </logbase>
+ <apply> <plus/>
+ <ci> x </ci>
+ <cn> 1 </cn>
+ </apply>
+ </apply>
+ </math>}
+ {}}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Here we feed some \MATHML\ into \TEX, which in turn shows up as a \METAPOST\
+graphic (\in {figure} [fig:mathml]).
+
+\startbuffer
+draw outlinetext.b
+ (\MPstring{some math})
+ (withcolor .625white)
+ (withcolor .625red withpen pencircle scaled 1/5)
+ scaled 8
+\stopbuffer
+
+\typebuffer
+
+\placefigure
+ [here]
+ [fig:mathml]
+ {A \MATHML\ snippet turned into outlines.}
+ {\processMPbuffer}
+
+Outlines are fun to look at. Here are a few ways to visualize a glyph:
+
+\startbuffer[1]
+\startcombination[3*1]
+ {\ruledhbox\bgroup
+ \showshape[character=(,alternative=text]%
+ \egroup} {}
+ {\ruledhbox\bgroup
+ \showshape[character=a,alternative=text]%
+ \egroup} {}
+ {\ruledhbox\bgroup
+ \showshape[character=x,alternative=text]%
+ \egroup} {}
+\stopcombination
+\stopbuffer
+
+\typebuffer[1]
+
+You can control the rendering a bit by setting \type {option}. Possible options
+are: \type {box}, \type {width}, \type {min}, \type {max} and \type {comment}.
+The \type {simple} option disables all. The simple results are shown in
+\in{figure} [fig:showshape].
+
+\startbuffer[2]
+\startcombination[3*1]
+ {\ruledhbox\bgroup
+ \showshape[character=(,alternative=text,option=simple]%
+ \egroup} {}
+ {\ruledhbox\bgroup
+ \showshape[character=a,alternative=text,option=simple]%
+ \egroup} {}
+ {\ruledhbox\bgroup
+ \showshape[character=x,alternative=text,option=simple]%
+ \egroup} {}
+\stopcombination
+\stopbuffer
+
+\typebuffer[2]
+
+\startplacefigure[reference=fig:showshape,title={Showing shapes.}]
+ \getbuffer[2]
+\stopplacefigure
+
+When you use this feature you need to be aware of the fact that fonts can have
+features, for instance ligatures and kerns between characters. In \in {figure}
+[fig:outlines:features] we see a few examples with and without features, one with
+Pagella (the Zapf quote) and one with Optima Nova (the Tufte quote).
+
+\startplacefigure[reference=fig:outlines:features,title={Pagela (\OPENTYPE) and Optima Nova (\TYPEONE)}]
+ \startcombination[1*4]
+ \bgroup
+ \def|#1|{-}%
+ \definedfont[texgyrepagella-regular.otf*none]%
+ \startMPcode
+ draw outlinetext.b
+ ("\framed[align=normal,width=max]{\input{zapf}}")
+ (withcolor .375white)
+ (withcolor .625red withpen pencircle scaled 1/10) ;
+ \stopMPcode
+ \egroup {pagella / no features}
+ \bgroup
+ \def|#1|{-}%
+ \definedfont[texgyrepagella-regular.otf*default]%
+ \startMPcode
+ draw outlinetext.b
+ ("\framed[align=normal,width=max]{\input{zapf}}")
+ (withcolor .375white)
+ (withcolor .625blue withpen pencircle scaled 1/10) ;
+ \stopMPcode
+ \egroup {pagella / default features}
+ \bgroup
+ \def|#1|{-}%
+ \definedfont[lt55476.afm*none]% optima nova
+ \startMPcode
+ draw outlinetext.b
+ ("\framed[align=normal,width=max]{\input{tufte}}")
+ (withcolor .375white)
+ (withcolor .625green withpen pencircle scaled 1/10) ;
+ \stopMPcode
+ \egroup {optima nova / no features}
+ \bgroup
+ \def|#1|{-}%
+ \definedfont[lt55476.afm*default]% optima nova
+ \startMPcode
+ draw outlinetext.b
+ ("\framed[align=normal,width=max]{\input{tufte}}")
+ (withcolor .375white)
+ (withcolor .625yellow withpen pencircle scaled 1/10) ;
+ \stopMPcode
+ \egroup {optima nova / default features}
+ \stopcombination
+\stopplacefigure
+
+Given that a shape has a path that is suitable for it, you can use special effects,
+like:
+
+\startbuffer
+ draw image (
+ draw outlinetext.d
+ ("Abracadabra")
+ (withpen pencircle scaled 1/10 dashed withdots scaled 1/20) ;
+ ) xsized TextWidth ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection
+ \processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=Transparency groups]
+
+The following feature is not that usefull but implemented anyway. The \PDF\ reference says:
+
+\startitemize
+ \startitem
+ A group may be isolated or non-isolated, which shall determine the
+ initial backdrop against which its stack is composited.
+ \stopitem
+ \startitem
+ A group may be knockout or non-knockout, which shall determine whether
+ the objects within its stack are composited with one another or only with
+ the group’s backdrop.
+ \stopitem
+\stopitemize
+
+and then carries on with a detailed explanation of groups. Here we stick to just
+mentioning how one can create a group in a picture. First we define a helper:
+
+\startbuffer
+\startMPdefinitions
+ def ShowGroup (expr clr) (text grouped) =
+ draw image (
+ drawarrow (10,0) -- (0,0)
+ withtransparency(1,.5)
+ withcolor clr ;
+ ) grouped ;
+ currentpicture := currentpicture xsized (TextWidth/8) ;
+ setbounds currentpicture to boundingbox currentpicture enlarged 2mm ;
+ addbackground withcolor .5white ;
+ enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+ \startcombination[5*1]
+ {\startMPcode ShowGroup(.5red) () \stopMPcode} {\tttf no group}
+ {\startMPcode ShowGroup(.5green) (asgroup "") \stopMPcode} {\tttf group}
+ {\startMPcode ShowGroup(.5blue) (asgroup "isolated") \stopMPcode} {\tttf isolated}
+ {\startMPcode ShowGroup(.5cyan) (asgroup "knockout") \stopMPcode} {\tttf knockout}
+ {\startMPcode ShowGroup(.5magenta)(asgroup "isolated,knockout") \stopMPcode} {\tttf isolated\crlf knockout}
+ \stopcombination
+\stoplinecorrection
+
+The syntax is:
+
+\starttyping
+draw somepicture|somepath grouped "[isolated|knockout] ;
+\stoptyping
+
+The group becomes an object and is no longer part of the stream of graphic
+operators but a reference. For what it's worth: I never needed this feature.
+
+\stopsection
+
+\startsection[title=Decorating]
+
+Although the \METAPOST\ language is quite powerful the number of data types is
+not that large and when it comes to drawing stuff there are only paths and
+pictures. A path is a list of points (with controlpoints) and a few properties,
+like the pen, linewidth, linecap, color and such. For a long time in \METAFUN\ we
+used so called specials to implement extensions (like shading). This was done by
+using special colors and associating these with entries in the special section at
+the top of the output.
+
+Nowadays we use the pre- and postscript properties of paths. The advantage is
+that we can add whatever we want, as long as the backend supports it and because
+the backend is written in \LUA\ there are no real limitations. So, instead of
+extending \METAPOST\ we extend the \METAFUN\ macros and backend.
+
+Most extensions use the prescripts. Think of this:
+
+\starttyping
+draw fullcircle
+ withprescript "do this"
+ withprescript "and that"
+ withprescript "and even more" ;
+\stoptyping
+
+Eventually this becomes a string:
+
+\starttyping
+and even more<newline>and that<newline>do this
+\stoptyping
+
+\typebuffer
+
+The prescripts get prepended, while the postscripts (that we use for text only)
+get appended. When we draw a picture with properties (like color) they get
+overwritten but not so (with good reason) for the pre- and postscripts: these
+just accumulate. We will now demonstrate how we can manipulate the picture
+(a bit).
+
+\startbuffer
+picture MyShape ; MyShape := image (
+ fill fullsquare xyscaled (4,1) withcolor .625red ;
+ fill fullsquare xyscaled (3,1) withcolor .625green ;
+ fill fullsquare xyscaled (2,1) withcolor .625blue ;
+ fill fullsquare xyscaled (1,1) withcolor .625yellow ;
+) xysized (TextWidth,1cm) ;
+
+draw MyShape;
+\stopbuffer
+
+\typebuffer
+
+We just draw the (natural) picture:
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+When we draw the picture with a new color, all its components get recolored:
+
+\startbuffer
+draw MyShape
+ withcolor .625magenta ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+However, when we add a transparency only the first component gets adapted because
+we use prescripts for this extension. (An extension using the postscripts would
+affect the last component.)
+
+\startbuffer
+draw MyShape
+ withcolor .625magenta
+ withtransparency (1,.5) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+The same logic applied to the \type {image}: prescripts get prepended to the
+first copmponent, postscripts to the last.
+
+\startbuffer
+draw image (draw MyShape)
+ withcolor .625cyan ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+\startbuffer
+draw image (draw MyShape)
+ withcolor .625cyan
+ withtransparency (1,.5) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+The \type {undecorated} macro ignores the properties. We can't reset the scripts as
+this could ruin the effects like shading.
+
+\startbuffer
+draw undecorated (draw MyShape)
+ withcolor .625white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+The \type {decorated} macro applies the properties to each component.
+
+\startbuffer
+draw decorated (draw MyShape)
+ withtransparency (1,.5) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+Here we kept the colors as they are but next we redo them:
+
+\startbuffer
+draw decorated (draw MyShape)
+ withcolor .625magenta
+ withtransparency (1,.5) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+The \type {redecorated} macro is the most intrusive as it resets the properties.
+This also means that you will loose texts, shades etc.
+
+\startbuffer
+draw redecorated (draw MyShape)
+ withtransparency (1,.5) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+Indeed we get no color (but black) but we can bring back some color:
+
+\startbuffer
+draw redecorated (draw MyShape)
+ withcolor .625yellow
+ withtransparency (1,.5) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=Properties]
+
+The (plain) \METAPOST\ macro \type {drawoptions} stored its arguments
+in a macro that gets expanded when something is drawn (or filled). So, when you say
+
+\starttyping
+drawoptions(withcolor red) ;
+draw somepath ;
+\stoptyping
+
+This effectively is:
+
+\starttyping
+draw somepath withcolor red ;
+\stoptyping
+
+A disadvantage is that there is not much control over where it gets applied,
+especially when you hide drawing operations in macros. It's the reason why
+personally I always prefer explicit options. If you want some abstraction
+you can use the properties feature:
+
+\startbuffer
+\startMPcode
+ property p[] ;
+ p1 = properties(withcolor "darkred") ;
+ p2 = properties(withcolor "darkblue") ;
+ p3 = properties(withcolor "darkgreen") ;
+ fill fullsquare xysized (TextWidth,12mm) withproperties p1 ;
+ fill fullsquare xysized (TextWidth, 8mm) withproperties p2 ;
+ fill fullsquare xysized (TextWidth, 4mm) withproperties p3 ;
+ fill fullsquare xysized (TextWidth, 2mm) withproperties p1 ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+We get:
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+Here we use an \quote {array} of properties but a single property is also possible:
+
+\startbuffer
+\startMPcode
+ property p ;
+ p = properties(withcolor "darkyellow") ;
+ fill fullsquare xysized (TextWidth,4mm) withproperties p ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+We get:
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-embedding.tex b/doc/context/sources/general/manuals/metafun/metafun-embedding.tex
new file mode 100644
index 000000000..10383fa3a
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-embedding.tex
@@ -0,0 +1,1208 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-embedding
+
+\environment metafun-environment
+
+\startchapter[reference=sec:embedding,title={Embedded graphics}]
+
+\startintro
+
+In addition to the \type {beginfig}||\type {endfig} method, there are other ways
+to define and include a \METAPOST\ graphic. Each method has its advantages and
+disadvantages.
+
+In the previous chapter we were still assuming that the graphic was defined in
+its own file. In this chapter we will introduce the interface between \CONTEXT\
+and \METAPOST\ and demonstrate how the definitions of the graphics can be
+embedded in the document source.
+
+\stopintro
+
+\startsection[title={Getting started}]
+
+\index{running}
+\index{processing}
+
+From now on, we will assume that you have \CONTEXT\ running on your platform.
+Since \PDF\ has full graphics support, we also assume that you use \LUATEX\ in
+combination with \CONTEXT\ \MKIV, although most will also work with other engines
+and \MKII. Since this document is not meant as a \CONTEXT\ tutorial, we will
+limit this introduction to the basics needed to run the examples.
+
+A simple document looks like:
+
+\starttyping
+\starttext
+ Some text.
+\stoptext
+\stoptyping
+
+You can process this document with the \LUA\ based command line interface to
+\CONTEXT. If the source code is embedded in the file \type {mytext.tex}, you can
+say:
+
+\starttyping
+context mytext
+\stoptyping
+
+We will use color, and in \MKIV\ color is enabled by default. If you don't want
+color you can tell \CONTEXT, so
+
+\starttyping
+\setupcolors[state=stop]
+\starttext
+ Some \color[blue]{text} and/or \color[green]{graphics}.
+\stoptext
+\stoptyping
+
+comes out in black and white.
+
+In later chapters we will occasionally see some more \CONTEXT\ commands show up.
+If you want to know more about what \CONTEXT\ can do for you, we recommend the
+beginners manual and the reference manual, as well as the wiki pages.
+
+\stopsection
+
+\startsection[title={External graphics}]
+
+\index {graphics+external}
+
+Since \TEX\ has no graphic capabilities built in, a graphic is referred to as an
+external figure. A \METAPOST\ graphic often has a number as suffix, so embedding
+such a graphic is done by:
+
+\starttyping
+\externalfigure[graphic.123][width=4cm]
+\stoptyping
+
+An alternative method is to separate the definition from the inclusion. An
+example of a definition is:
+
+\starttyping
+\useexternalfigure[pentastar][star.803][height=4cm]
+\useexternalfigure[octostar] [star.804][pentastar]
+\stoptyping
+
+Here, the second definition inherits the characteristics from the first one.
+These graphics can be summoned like:
+
+\starttyping
+\placefigure
+ {A five||point star drawn by \METAPOST.}
+ {\externalfigure[pentastar]}
+\stoptyping
+
+Here the stars are defined as stand||alone graphics, in a file called \type
+{star.mp}. Such a file can look like:
+
+\starttyping
+def star (expr size, n, pos) =
+ for a=0 step 360/n until round(360*(1-1/n)) :
+ draw (origin -- (size/2,0))
+ rotatedaround (origin,a) shifted pos ;
+ endfor ;
+enddef ;
+
+beginfig(803) ;
+ pickup pencircle scaled 2mm ; star(2cm,5,origin) ;
+endfig ;
+
+beginfig(804) ;
+ pickup pencircle scaled 1mm ; star(1cm,8,origin) ;
+ pickup pencircle scaled 2mm ; star(2cm,7,(3cm,0)) ;
+endfig ;
+
+end.
+\stoptyping
+
+This \type {star} macro will produce graphics like:
+
+\startbuffer
+def star (expr size, n, pos) =
+ for a=0 step 360/n until round(360*(1-1/n)) :
+ draw (origin -- (size/2,0))
+ rotatedaround (origin,a) shifted pos ;
+ endfor ;
+enddef ;
+
+for i=5 upto 10 :
+ drawoptions (withpen pencircle scaled 2mm withcolor .625red) ;
+ star(1cm,i,origin shifted (i*2cm,0)) ;
+endfor ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+But, now that we have instant \METAPOST\ available in \LUATEX, there is no need
+for external images and we can collect them in libraries, as we will see later
+on.
+
+\stopsection
+
+\startsection[title={Integrated graphics}]
+
+\index{graphics+embedded}
+
+An integrated graphic is defined in the document source or in a style definition
+file. The most primitive way of doing this is just inserting the code:
+
+\starttyping
+\startMPcode
+ fill fullcircle scaled 200pt withcolor .625white ;
+\stopMPcode
+\stoptyping
+
+Such a graphic is used once at the spot where it is defined. In this document we
+also generate graphics while we finish a page, so there is a good chance that
+when we have constructed a graphic which will be called on the next page, the
+wrong graphic is placed.
+
+For this reason there are are more convenient ways of defining and using
+graphics, which have the added advantage that you can predefine multiple
+graphics, thereby separating the definitions from the usage.
+
+The first alternative is a {\em usable} graphic. Such a graphic is calculated
+anew each time it is used. An example of a usable graphic is:
+
+\starttyping
+\startuseMPgraphic{name}
+ fill fullcircle scaled 200pt withcolor .625yellow ;
+\stopuseMPgraphic
+\stoptyping
+
+When you put this definition in the preamble of your document, you can place this
+graphic anywhere in the file, saying:
+
+\starttyping
+\useMPgraphic{name}
+\stoptyping
+
+As said, this graphic is calculated each time it is placed, which can be time
+consuming. Apart from the time aspect, this also means that the graphic itself is
+incorporated many times. Therefore, for graphics that don't change, \CONTEXT\
+provides {\em reusable} graphics:
+
+\starttyping
+\startreusableMPgraphic{name}
+ fill fullcircle scaled 200pt withcolor .625yellow;
+\stopreusableMPgraphic
+\stoptyping
+
+This definition is accompanied by:
+
+\starttyping
+\reuseMPgraphic{name}
+\stoptyping
+
+Imagine that we use a graphic as a background for a button. We can create a
+unique and reusable graphic by saying:
+
+\starttyping
+\def\MyGraphic
+ {\startreusableMPgraphic{name:\overlaywidth:\overlayheight}
+ path p ; p := unitsquare
+ xscaled OverlayWidth yscaled OverlayHeight ;
+ fill p withcolor .625yellow ;
+ draw p withcolor .625red ;
+ \stopreusableMPgraphic
+ \reuseMPgraphic{name:\overlaywidth:\overlayheight}}
+\stoptyping
+
+Notice the use of \type {OverlayWidth} and \type {OverlayHeight}. These variables
+are set for each call to \METAPOST. After this we can say:
+
+\starttyping
+\defineoverlay[my graphic][\MyGraphic]
+\button[background=my graphic,frame=off]{Go Home}[firstpage]
+\stoptyping
+
+Say that we have a 30pt by 20pt button, then the identifier will be \type
+{name:30pt:20pt}. Different dimensions will lead to other identifiers, so this
+sort of makes the graphics unique.
+
+We can bypass the ugly looking \type {\def} by using a third class of embedded
+graphics, the {\em unique} graphics.
+
+\starttyping
+\startuniqueMPgraphic{name}
+ path p ; p := unitsquare
+ xscaled OverlayWidth yscaled OverlayHeight ;
+ fill p withcolor .625yellow ;
+ draw p withcolor .625red ;
+\stopuniqueMPgraphic
+\stoptyping
+
+Now we can say:
+
+\starttyping
+\defineoverlay[my graphic][\uniqueMPgraphic{name}]
+\button[background=my graphic,frame=off]{Go Home}[firstpage]
+\stoptyping
+
+A shorter variant is:
+
+\starttyping
+\startuniqueMPgraphic{name}
+ fill OverlayBox withcolor .625yellow ;
+ draw OverlayBox withcolor .625red ;
+\stopuniqueMPgraphic
+\stoptyping
+
+You may wonder why unique graphics are needed when a single graphic might be used
+multiple times by scaling it to fit the situation. Since a unique graphic is
+calculated for each distinctive case, we can be sure that the current
+circumstances are taken into account. Also, scaling would result in incomparable
+graphics. Consider the following definition:
+
+\startbuffer[a]
+\startuseMPgraphic{demo}
+ draw unitsquare
+ xscaled 5cm yscaled 1cm
+ withpen pencircle scaled 2mm
+ withcolor .625red ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[a]
+
+Since we reuse the graphic, the dimensions are sort of fixed, and because the
+graphic is calculated once, scaling it will result in incompatible line widths.
+
+\startbuffer[b]
+\hbox \bgroup
+ \scale[width=5cm,height=1cm]{\useMPgraphic{demo}}\quad
+ \scale[width=8cm,height=1cm]{\useMPgraphic{demo}}%
+\egroup
+\stopbuffer
+
+\startlinecorrection[blank]
+\getbuffer[a,b]
+\stoplinecorrection
+
+These graphics were placed with:
+
+\typebuffer[b]
+
+Imagine what happens when we add some buttons to an interactive document without
+taking care of this side effect. All the frames would look different. Consider
+the following example.
+
+\startbuffer[a]
+\startuniqueMPgraphic{right or wrong}
+ pickup pencircle scaled .075 ;
+ fill unitsquare withcolor .8white ;
+ draw unitsquare withcolor .625red ;
+ currentpicture := currentpicture
+ xscaled OverlayWidth yscaled OverlayHeight ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\typebuffer[a]
+
+Let's define this graphic as a background to some buttons.
+
+\startbuffer[b]
+\defineoverlay[button][\uniqueMPgraphic{right or wrong}]
+\setupbuttons[background=button,frame=off]
+\stopbuffer
+
+\startbuffer[c]
+\hbox
+ {\button {previous} [previouspage]\quad
+ \button {next} [nextpage]\quad
+ \button {index} [index]\quad
+ \button {table of contents} [content]}
+\stopbuffer
+
+\typebuffer[b,c]
+
+The buttons will look like:
+
+\startlinecorrection[blank]
+\setupinteraction[state=start,color=,contrastcolor=]
+\getbuffer[a,b,c]
+\stoplinecorrection
+
+Compare these with:
+
+\startbuffer[a]
+\startuniqueMPgraphic{wrong or right}
+ pickup pencircle scaled 3pt ;
+ path p ; p := unitsquare
+ xscaled OverlayWidth yscaled OverlayHeight ;
+ fill p withcolor .8white ;
+ draw p withcolor .625red ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\startlinecorrection[blank]
+\getbuffer[a,b]
+\defineoverlay[button][\uniqueMPgraphic{wrong or right}]
+\setupinteraction[state=start,color=,contrastcolor=]
+\getbuffer[c]
+\stoplinecorrection
+
+Here the graphic was defined as:
+
+\typebuffer[a]
+
+The last class of embedded graphics are the {\em runtime} graphics. When a
+company logo is defined in a separate file \type {mylogos.mp}, you can run this
+file by saying:
+
+\starttyping
+\startMPrun
+ input mylogos ;
+\stopMPrun
+\stoptyping
+
+The source for the logo is stored in a file named \type {mylogos.mp}.
+
+\startbuffer
+beginfig(21) ;
+ draw fullsquare withcolor .625red ;
+ draw fullsquare rotated 45 withcolor .625red ;
+ picture cp ; cp := currentpicture ;
+ def copy = addto currentpicture also cp enddef ;
+ copy scaled .9 withcolor .625white ;
+ copy scaled .7 withcolor .625yellow ;
+ copy scaled .6 withcolor .625white ;
+ copy scaled .4 withcolor .625red ;
+ copy scaled .3 withcolor .625white ;
+ fill fullcircle scaled .2 withcolor .625yellow ;
+ currentpicture := currentpicture scaled 50 ;
+endfig ;
+end .
+\stopbuffer
+
+\typebuffer
+
+In this example the result is available in the virtual file \type {mprun.21}.
+This file can be included in the normal way, using:
+
+\starttyping
+\externalfigure[mprun.21][width=5cm]
+\stoptyping
+
+\startuseMPgraphic{dummy logo}
+ draw fullsquare withcolor .625red ;
+ draw fullsquare rotated 45 withcolor .625red ;
+ picture cp ; cp := currentpicture ;
+ def copy = addto currentpicture also cp enddef ;
+ copy scaled .9 withcolor .625white ;
+ copy scaled .7 withcolor .625yellow ;
+ copy scaled .6 withcolor .625white ;
+ copy scaled .4 withcolor .625red ;
+ copy scaled .3 withcolor .625white ;
+ fill fullcircle scaled .2 withcolor .625yellow ;
+ currentpicture := currentpicture scaled 3cm ;
+\stopuseMPgraphic
+
+\placefigure
+ {The logo is defined in the file \type {mylogos.mp} as
+ figure~21 and processed by means of the \type {mprun}
+ method.}
+ {\useMPgraphic{dummy logo}}
+
+Optionally you can specify a name and an instance. This has the advantage that
+the graphics don't interfere with the regular inline graphics. Here the instance
+used is \type {extrafun} and the name where the run is stored is \type {mydemo}.
+
+\startbuffer
+\startMPrun{extrafun::mydemo}
+ input mfun-mrun-demo.mp ;
+\stopMPrun
+
+\placefigure
+ {An external file can have multiple graphics. Here we show a few
+ images that we used to use on the \PRAGMA\ \CONTEXT\ website.}
+ {\startcombination[2*2]
+ {\externalfigure[mprun:extrafun::mydemo.1][height=6cm]} {downloads}
+ {\externalfigure[mprun:extrafun::mydemo.2][height=6cm]} {links}
+ {\externalfigure[mprun:extrafun::mydemo.3][height=6cm]} {mirrors}
+ {\externalfigure[mprun:extrafun::mydemo.4][height=6cm]} {team}
+ \stopcombination}
+\stopbuffer
+
+\typebuffer
+
+Keep in mind that the whole file will be processed (using the built in library)
+in order to get one graphic. Normally this is no big deal.
+
+\getbuffer
+
+\stopsection
+
+\startsection[title={Using \METAFUN\ but not \CONTEXT}]
+
+\index{graphics+standalone}
+
+If you don't want to use \CONTEXT\ but still want to use \METAFUN, a rather
+convenient method is the following. Create a file that
+
+\starttyping
+\startMPpage
+ % Your mp code goes here. You can use the textext
+ % macro as discussed later to deal with typeset text.
+\stopMPpage
+\stoptyping
+
+When you process that file with the \type {context} command you will get a \PDF\
+file that you can include in any application that can embed a \PDF\ image. In
+this case your exposure to \CONTEXT\ is minimal.
+
+\stopsection
+
+\startsection[title={Graphic buffers}]
+
+\index{graphics+buffers}
+\index{buffers}
+
+In addition to the macros defined in the previous section, you can use \CONTEXT's
+buffers to handle graphics. This can be handy when making documentation, so it
+makes sense to spend a few words on them.
+
+A buffer is a container for content that is to be (re|)|used later on. The main
+reason for their existence is that they were needed for typesetting manuals and
+articles on \TEX. By putting the code snippets in buffers, we don't have to key
+in the code twice, since we can either show the code of buffers verbatim, or
+process the code as part of the text flow. This means that the risk of mismatch
+between the code shown and the typeset text is minimized.
+
+\startbuffer[a]
+\startbuffer
+You are reading the \METAFUN\ manual.
+\stopbuffer
+\stopbuffer
+
+\typebuffer[a]
+
+This buffer can be typeset verbatim using \type {\typebuffer} and processed using
+\type {\getbuffer}, as we will do now:
+
+\blank \getbuffer[a] \blank
+
+An other advantage of using buffers, is that they help you keeping the document
+source clean. In many places in this manual we put table or figure definitions in
+a buffer and pass the buffer to another command, like:
+
+\starttyping
+\placefigure{A very big table}{\getbuffer}
+\stoptyping
+
+Sometimes it makes sense to collect buffers in separate files. In that case we
+give them names.
+
+\startbuffer
+\startbuffer[mfun]
+You are reading the \METAFUN\ manual.
+\stopbuffer
+\stopbuffer
+
+This time we should say \type {\typebuffer[mfun]} to typeset the code verbatim.
+Instead of \TEX\ code, we can put \METAPOST\ definitions in buffers.
+
+\startbuffer
+\startbuffer[graphic]
+draw fullcircle scaled 2cm ;
+\stopbuffer
+\stopbuffer
+
+Buffers can be used to stepwise build graphics. By putting code in multiple
+buffers, you can selectively process this code.
+
+\startbuffer
+\startbuffer[red]
+drawoptions(withcolor .625red) ;
+\stopbuffer
+
+\startbuffer[yellow]
+drawoptions(withcolor .625yellow) ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer
+
+We can now include the same graphic in two colors by simply using different
+buffers. This time we use the special command \type {\processMPbuffer}, since
+\type {\getbuffer} will typeset the code fragment, which is not what we want.
+
+\startbuffer
+\startlinecorrection[blank]
+\processMPbuffer[red,graphic]
+\stoplinecorrection
+\stopbuffer
+
+\typebuffer
+
+The line correction macros take care of proper spacing around the graphic. The
+\type {[blank]} directive tells \CONTEXT\ to add more space before and after the
+graphic.
+
+\startbuffer
+\startlinecorrection[blank]
+\processMPbuffer[yellow,graphic]
+\stoplinecorrection
+\stopbuffer
+
+\typebuffer
+
+Which mechanism you use, (multiple) buffers or (re|)|usable graphics, depends on
+your preferences. Buffers are slower but don't take memory, while (re|)|usable
+graphics are stored in memory which means that they are accessed faster.
+
+\stopsection
+
+\startsection[title={Communicating color}]
+
+\index{color}
+
+Now that color has moved to the desktop, even simple documents have become more
+colorful, so we need a way to consistently apply color to text as well as
+graphics. In \CONTEXT, colors are called by name.
+
+The next definitions demonstrate that we can define a color using different color
+models, \RGB\ or \CMYK. Depending on the configuration, \CONTEXT\ will convert
+one color system to the other, \RGB\ to \CMYK, or vice versa. The full repertoire
+of color components that can be set is as follows.
+
+\starttyping
+\definecolor[color one] [r=.1, g=.2, b=.3]
+\definecolor[color two] [c=.4, m=.5, y=.6, k=.7]
+\definecolor[color three][s=.8]
+\stoptyping
+
+The numbers are limited to the range $0\dots1$ and represent percentages. Black
+is represented by:
+
+\starttyping
+\definecolor[black 1] [r=0, g=0, b=0]
+\definecolor[black 2] [c=0, m=0, y=0, k=1]
+\definecolor[black 3] [s=0]
+\stoptyping
+
+Predefined colors are passed to \METAPOST\ graphics via the \type {\MPcolor}.
+First we define some colors.
+
+\starttyping
+\definecolor[darkyellow][y=.625] % a CMYK color
+\definecolor[darkred] [r=.625] % a RGB color
+\definecolor[darkgray] [s=.625] % a gray scale
+\stoptyping
+
+These are the colors we used in this document. The next example uses two of them.
+
+\startbuffer
+\startuseMPgraphic{color demo}
+ pickup pencircle scaled 1mm ;
+ path p ; p := fullcircle xscaled 10cm yscaled 1cm ;
+ fill p withcolor \MPcolor{darkgray} ;
+ draw p withcolor \MPcolor{darkred} ;
+\stopuseMPgraphic
+
+\useMPgraphic{color demo}
+\stopbuffer
+
+\typebuffer
+
+The previous example uses a pure \RGB\ red shade, combined with a gray fill.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+Originally \METAPOST\ only supported only the \RGB\ and gray color spaces. In \METAFUN\
+we also supported \CMYK\ and spot colors, using an extension mechanism that hooked into
+the backend. At some point \METAPOST\ got native support for \CMYK. When you use mixed
+color models you need to be aware of the fact that their related variables have different
+types:
+
+\starttabulate[||T|T|]
+\NC gray \NC numeric \NC s \NC \NR
+\NC rgb \NC color \NC (r,g,b) \NC \NR
+\NC cmyk \NC cmykcolor \NC (c,m,y,k) \NC \NR
+\stoptabulate
+
+Because in \METAFUN\ (\type {mpiv}) we hook deeply into the \CONTEXT\ color
+mechanisms we can use symbolic names instead. and these are just strings.
+
+There is a fundamental difference between a yellow as defined in \CONTEXT\ using
+\CMYK\ and a \RGB\ yellow.
+
+\startbuffer
+\definecolor[cmyyellow] [y=1]
+\definecolor[rgbyellow] [r=1,g=1]
+
+\definecolor[cmydarkyellow][y=.625]
+\definecolor[rgbdarkyellow][r=.625,g=.625]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\in {Figure} [fig:many yellows:pass] demonstrates what happens when we multiply
+colors by a factor. Since we are not dealing with real \CMYK\ colors,
+multiplication gives different results for \CMYK\ colors passed as \type
+{\MPcolor}. \in {Figure} [fig:many yellows:fetch] we show the same colors but
+this time we use a different method, one that avoids the \TEX\ macro. This method
+can be used in \MKIV. We will use both methods in examples.
+
+\def\TestColor#1%
+ {\startuseMPgraphic{yellow}
+ fill unitsquare xscaled (.30*\the\hsize) yscaled 1cm withcolor #1 ;
+ \stopuseMPgraphic
+ \useMPgraphic{yellow}}
+
+\startbuffer
+\setuptype[style=\ttx]%
+\startcombination[3*3]
+ {\TestColor{(0,0,1,0)}} {\type{(0,0,1,0)}}
+ {\TestColor{(1,1,0)}} {\type{(1,1,0)}}
+ {\TestColor{(.5,.5,0)}} {\type{(.5,.5,0)}}
+ {\TestColor{\MPcolor{rgbyellow}}} {\type{\MPcolor{rgbyellow}}}
+ {\TestColor{\MPcolor{rgbdarkyellow}}} {\type{\MPcolor{rgbdarkyellow}}}
+ {\TestColor{.5\MPcolor{rgbyellow}}} {\type{.5\MPcolor{rgbyellow}}}
+ {\TestColor{\MPcolor{cmyyellow}}} {\type{\MPcolor{cmyyellow}}}
+ {\TestColor{\MPcolor{cmydarkyellow}}} {\type{\MPcolor{cmydarkyellow}}}
+ {\TestColor{.5\MPcolor{cmyyellow}}} {\type{.5\MPcolor{cmyyellow}}}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:many yellows:pass]
+ {All kinds of yellow (passing valued from \TEX).}
+ {\getbuffer}
+
+\startbuffer
+\setuptype[style=\ttx]%
+\startcombination[3*3]
+ {\TestColor{(0,0,1,0)}} {\type{(0,0,1,0)}}
+ {\TestColor{(1,1,0)}} {\type{(1,1,0)}}
+ {\TestColor{(.5,.5,0)}} {\type{(.5,.5,0)}}
+ {\TestColor{"rgbyellow"}} {\type{"rgbyellow"}}
+ {\TestColor{"rgbdarkyellow"}} {\type{"rgbdarkyellow"}}
+ {\TestColor{.5namedcolor("rgbyellow")}} {\type{.5namedcolor("rgbyellow")}}
+ {\TestColor{"cmyyellow"}} {\type{"cmyyellow"}}
+ {\TestColor{"cmydarkyellow"}} {\type{"cmydarkyellow"}}
+ {\TestColor{.5namedcolor("cmyyellow")}} {\type{.5namedcolor("cmyyellow")}}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:many yellows:fetch]
+ {All kinds of yellow (fetching values from \TEX).}
+ {\getbuffer}
+
+So, \type {.625red} is the same as \type {[r=.5]}, but \type {.625yellow} is not
+the same as \type {[y=.5]}, but matches \type {[r=.5,g=.5]}. \in {Figure}
+[fig:some reds] shows the pure and half reds.
+
+\def\TestColor#1%
+ {\startMPcode
+ fill unitsquare xscaled (.30*\the\hsize) yscaled 1cm withcolor #1 ;
+ \stopMPcode}
+
+\startbuffer
+\setuptype[style=\ttx]\setupcolors[mpcmyk=no]
+\startcombination[3*2]
+ {\TestColor{red}} {\type{red}}
+ {\TestColor{(1,0,0)}} {\type{(1,0,0)}}
+ {\TestColor{(.625,0,0)}} {\type{(.625,0,0)}}
+ {\TestColor{"red"}} {\type{"red")}}
+ {\TestColor{"darkred"}} {\type{"darkred")}}
+ {\TestColor{.625namedcolor("red")}} {\type{.625namedcolor("red")}}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:some reds]
+ {Some kinds of red.}
+ {\getbuffer}
+
+In order to prevent problems, we advise you to stick to \RGB\ color
+when you create documents for screen and \CMYK\ when producing for print.
+
+In the \METAFUN\ macro collection there is a macro \type {cmyk} that takes four
+arguments, representing the cyan, magenta, yellow, and black component. Nowadays
+you don't need it as we have native \CMYK.
+
+\startbuffer
+fill unitsquare xyscaled (10cm, 5mm) withcolor cmyk(1,0,.3,.3) ;
+fill unitsquare xyscaled (10cm,-5mm) withcolor (1,.3,0,.3) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+If you take a close look at the numbers, you will notice that the cyan component
+results in a 100\% ink contribution. You will also notice that 30\% black ink is
+added. This means that we cannot safely convert this color to \RGB\ ($r=1-c-k<0$)
+without losing information. Nevertheless the previous blue bar is presented all
+right. This is due to the fact that in \METAFUN\ the \CMYK\ colors are handled as
+they should, even when \METAPOST\ does not support this color model.
+
+If you use this feature independent of \CONTEXT, you need to enable it by setting
+\type {cmykcolors} to \type {true}. You have to convert the resulting graphic to
+\PDF\ by using for instance the \type {mptopdf} suite.
+
+In \CONTEXT\ you can influence this conversion by changing parameters related to
+color handling:
+
+\starttyping
+\setupcolors[cmyk=yes,rgb=no]
+\stoptyping
+
+Unless you know what you are doing, you don't have to change the default settings
+(both \type {yes}). In the \CONTEXT\ reference manual you can also read how color
+reduction can be handled.
+
+Special care should be paid to gray scales. Combining equal quantities of the
+three color inks will not lead to a gray scale, but to a muddy brown shade.
+
+\startbuffer
+fill fullsquare xyscaled (10cm, 2cm) withcolor .5white ;
+fill fullsquare xyscaled ( 6cm,1.5cm) withcolor cmyk(.5,.5,.5,0) ;
+fill fullsquare xyscaled ( 2cm, 1cm) withcolor cmyk(0,0,0,.5) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+In \in {figure} [fig:cmyk 1] \in {and} [fig:cmyk 2] you can see some more colors
+defined in the \CMYK\ color space. When you display the screen version of this
+document, you will notice that the way colors are displayed can differ per
+viewer. This is typical for \CMYK\ colors and has to do with the fact that some
+assumptions are made with respect to the (print) medium.
+
+\startbuffer[mp]
+ fill fullcircle xyscaled (3cm,1cm) withcolor \MPcolor{test} ;
+\stopbuffer
+
+\startbuffer[cmyk]
+\startcombination[4*1]
+ {\definecolor[test][c=1,y=.3,k=.3] \processMPbuffer[mp]} {c=1 y=.3 k=.3}
+ {\definecolor[test][c=.9,y=.15] \processMPbuffer[mp]} {c=.9 y=.15}
+ {\definecolor[test][c=.25,y=.8] \processMPbuffer[mp]} {c=.25 y=.8}
+ {\definecolor[test][c=.45,y=.1] \processMPbuffer[mp]} {c=.45 y=.1}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:cmyk 1]
+ {\CMYK\ support enabled.}
+ {\getbuffer[cmyk]}
+
+\placefigure
+ [here][fig:cmyk 2]
+ {\CMYK\ support disabled, no support in \METAPOST.}
+ {\setupcolors[cmyk=no]\getbuffer[cmyk]\setupcolors[cmyk=yes]}
+
+\stopsection
+
+% \startsection[title={Common definitions}]
+%
+% \index{inclusions}
+% \index{common definitions}
+%
+% When using many graphics, there is a chance that they share common definitions.
+% Such shared components can be defined by:
+%
+% \starttyping
+% \startMPinclusions
+% color mycolor ; mycolor := .625red ;
+% \stopMPinclusions
+% \stoptyping
+%
+% {\em The following is only true for \CONTEXT\ \MKII ! Users of \MKIV\ can skip
+% this section.}
+%
+% All \METAPOST\ graphics defined in the document end up in the files \type
+% {mpgraph.mp} and \type {mprun.mp}. When processed, they produce (sometimes many)
+% graphic files. When you use \CONTEXT\ \MKII\ and \TEXEXEC\ to process documents,
+% these two files are processed automatically after a run so that in a next run,
+% the right graphics are available.
+%
+% When you are using the \type {web2c} distribution, \CONTEXT\ can call \METAPOST\
+% at runtime and thereby use the right graphics instantaneously. In order to use
+% this feature, you have to enable \type {\write18} in the file \type {texmf.cnf}.
+% Also, in the file \type {cont-sys.tex}, that holds local preferences, or in the
+% document source, you should say:
+%
+% \starttyping
+% \runMPgraphicstrue
+% \stoptyping
+%
+% This enables runtime generation of graphics using the low level \TEX\ command
+% \type {\write18}. First make sure that your local brand of \TEX\ supports this
+% feature. A simple test is making a \TEX\ file with the following line:
+%
+% \starttyping
+% \immediate\write18{echo It works}
+% \stoptyping
+%
+% If this fails, you should consult the manual that comes with your system, locate
+% an expert or ask around on the \CONTEXT\ mailing list. Of course you can also
+% decide to let \TEXEXEC\ take care of processing the graphics afterwards. This has
+% the advantage of being faster but has the disadvantage that you need additional
+% \TEX\ runs.
+%
+% If you generate the graphics at run time, you should consider to turn on graphic
+% slot recycling, which means that you often end up with fewer intermediate files:
+%
+% \starttyping
+% \recycleMPslotstrue
+% \stoptyping
+%
+% There are a few more low level switches and features, but these go beyond the
+% purpose of this manual. Some of these features, like the option to add tokens to
+% \type {\everyMPgraphic} are for experts only, and fooling around with them can
+% interfere with existing features.
+%
+% \stopsection
+
+\startsection[title={One page graphics}]
+
+An advantage of using \CONTEXT\ to make your \METAPOST\ graphics is you don't
+have to bother about specials, font inclusion and all those nasty things that can
+spoil a good day. An example of such a graphic is the file \type {mfun-800} that
+resides on the computer of the author.
+
+\typefile{mfun-800}
+
+Given that \CONTEXT\ is present on your system, you can process this file with:
+
+\starttyping
+context mfun-800
+\stoptyping
+
+You can define many graphics in one file. Later you can include individual pages
+from the resulting \PDF\ file in your document:
+
+\startbuffer
+\placefigure
+ {A silly figure, demonstrating that stand||alone||graphics
+ can be made.}
+ {\typesetfile[mfun-800.tex][page=1]}
+\stopbuffer
+
+\typebuffer
+
+In this case the \type {page=1} specification is not really needed. You can scale
+and manipulate the figure in any way supported by the macro package that you use.
+
+\getbuffer
+
+\stopsection
+
+\startsection[title={Managing resources}]
+
+A graphic consists of curves, either or not filled with a given color. A graphic
+can also include text, which means that fonts are used. Finally a graphic can
+have special effects, like a shaded fill. Colors, fonts and special effects go
+under the name resources, since they may demand special care or support from the
+viewing or printing device.
+
+% When fonts are used, a \METAPOST\ file is not self contained. This means that the
+% postprocessing program has to deal with the fonts. In \CONTEXT, the special
+% driver |<|and \PDFTEX\ support is considered as such|>| takes care of this.
+
+Special effects, like shading, are supported by dedicated \METAPOST\ modules.
+These are included in the \CONTEXT\ distribution and will be discussed later in
+\in {chapter} [sec:effects].
+
+Since \METAPOST\ supports color, an embedded graphic can be rather colorful.
+However, when color support is disabled or set up to convert colors to gray
+scales, \CONTEXT\ will convert the colors in the graphics to gray scales.
+
+\startbuffer[circle]
+ colorcircle(4cm,red,green,blue) ;
+\stopbuffer
+
+\startbuffer
+\startcombination[3*1]
+ {\setupcolors[state=start]\processMPbuffer[circle]} {full color}
+ {\setupcolors[state=stop]\processMPbuffer[circle]} {weighted gray}
+ {\setupcolors[state=stop,factor=no]\processMPbuffer[circle]} {linear gray}
+\stopcombination
+\stopbuffer
+
+You may wonder what the advantage is of weighted gray conversion. \in {Figure}
+[fig:color circles] shows the difference between natural colors, weighted gray
+scales and straightforward, non||weighted, gray scales.
+
+\placefigure
+ [here][fig:color circles]
+ {The advantage of weighted gray over linear gray.}
+ {\getbuffer\setupcolors[state=start,factor=yes]} % just to be sure
+
+When we convert color to gray, we use the following formula. This kind of
+conversion also takes place in black and white televisions.
+
+\placeformula [-]
+ \startformula
+ G = .30r + .59g + .11b
+ \stopformula
+
+\in {Section} [sec:conversion] introduces the \type {grayed} operation that you
+can use to convert a colored picture into a gray one. This macro uses the same
+conversion method as mentioned here.
+
+\stopsection
+
+\startsection[title={Instances}]
+
+There are a few instances predefined and if you want to isolate your own
+graphics from whatever \CONTEXT\ itself cooks up, you can define more as the
+extra overhead can be neglected.
+
+\starttabulate[|T|T|T|T|T|]
+\BC name \BC format \BC extensions \BC initializations \BC method \NC \NR
+\NC metafun \NC metafun \NC yes \NC yes \NC \NC \NR
+\NC extrafun \NC metafun \NC yes \NC yes \NC \NC \NR
+\NC lessfun \NC metafun \NC \NC \NC \NC \NR
+\NC doublefun \NC metafun \NC yes \NC yes \NC double \NC \NR
+\NC binaryfun \NC metafun \NC yes \NC yes \NC binary \NC \NR
+\NC decimalfun \NC metafun \NC yes \NC yes \NC decimal \NC \NR
+\stoptabulate
+
+According to this the \type {doublefun} instance is defined as:
+
+\starttyping
+\defineMPinstance
+ [doublefun]
+ [format=metafun,
+ extensions=yes,
+ initializations=yes,
+ method=double]
+\stoptyping
+
+The \type {extensions} key relates to:
+
+\starttyping
+\startMPextensions
+ % some code
+\stopMPextensions
+\stoptyping
+
+that are used to pass (common) extensions to the instance. The \type
+{initializations} key relates to:
+
+\starttyping
+\startMPinitializations
+ % some code
+\stopMPinitializations
+\stoptyping
+
+that are used to communicate \TEX\ properties to the instance (they are
+expanded each graphic). Instance bound definitions can be set with:
+
+\starttyping
+\startMPdefinitions{doublefun}
+ % some code
+\stopMPdefinitions
+\stoptyping
+
+We do have more instances, for instance for the chemical subsystem. If you load
+the \type {graph} module you get a double precision \type {graph} instance. We might
+use more private ones in the future.
+
+When you make graphic pages, you can do this:
+
+\starttyping
+\startMPpage[instance=doublefun]
+ % some code
+\stopMPpage
+\stoptyping
+
+When you use the other commands you can optionally specify an instance:
+
+\startbuffer[metafun]
+\startMPcode{metafun}
+ draw textext(decimal pi) scaled 2 withcolor .625red ;
+ draw boundingbox currentpicture enlarged 2pt ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[extrafun]
+\startMPcode{extrafun}
+ draw textext(decimal pi) scaled 2 withcolor .625green ;
+ draw boundingbox currentpicture enlarged 2pt ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[doublefun]
+\startMPcode{doublefun}
+ draw textext(decimal pi) scaled 2 withcolor .625blue ;
+ draw boundingbox currentpicture enlarged 2pt ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[binaryfun]
+\startMPcode{binaryfun}
+ draw textext(decimal pi) scaled 2 withcolor .625yellow ;
+ draw boundingbox currentpicture enlarged 2pt ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[decimalfun]
+\startMPcode{decimalfun}
+ draw textext(decimal pi) scaled 2 withcolor .375white ;
+ draw boundingbox currentpicture enlarged 2pt ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[metafun,extrafun,doublefun,binaryfun,decimalfun]
+
+The result is shown in \in {figure} [fig:instances] and as expected there
+is a different value for $\pi$ reported.
+
+\startplacefigure[reference=fig:instances,title={Instances can use different number systems.}]
+ \startcombination[1*5]
+ {\getbuffer[metafun]} {metafun}
+ {\getbuffer[extrafun]} {extrafun}
+ {\getbuffer[doublefun]} {doublefun}
+ {\getbuffer[binaryfun]} {binaryfun}
+ {\getbuffer[decimalfun]} {decimalfun}
+ \stopcombination
+\stopplacefigure
+
+You need to be aware of the fact that the results of a (for instance) double
+instance can differ from a scaled (the default) one. As long as graphics can be
+processed in both models (which is the case as long as the dimensions stay below
+4096 base points) the outcome is probably not that different. However, we've seen
+that the accuracy of for instance $\pi$ (just a variable) differs. I like to use
+random values and the random generators are definitely different: each of the
+number libraries has its own implementation. Let's look at that. We define two
+random graphic generators:
+
+\startbuffer
+\startuseMPgraphic{normaldeviate}
+ randomseed := 100 ;
+ draw fullsquare
+ withpen pencircle scaled 1/200
+ withcolor .5white ;
+ for i=1 upto 500 :
+ draw (normaldeviate,normaldeviate)
+ scaled 1/3
+ withpen pencircle scaled 1/30
+ withtransparency (1,.5) ;
+ endfor ;
+ setbounds currentpicture to
+ boundingbox fullcircle
+ enlarged 1/2 ;
+ currentpicture :=
+ currentpicture
+ xsized (2TextWidth/5) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+And:
+
+\startbuffer
+\startuseMPgraphic{uniformdeviate}
+ randomseed := 100 ;
+ draw fullsquare
+ withpen pencircle scaled 1/200
+ withcolor .5white ;
+ for i=1 upto 500 :
+ draw (-1/2 + uniformdeviate 1,-1/2 + uniformdeviate 1)
+ withpen pencircle scaled 1/30
+ withtransparency (1,.5) ;
+ endfor ;
+ setbounds currentpicture to
+ boundingbox fullcircle
+ enlarged 1/2 ;
+ currentpicture :=
+ currentpicture
+ xsized (2TextWidth/5) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We show the results for a normaldeviate in \in {figure} [fig:random:1] \in {upto}
+[fig:random:4] you see the randomizers per number system. In \in {figure}
+[fig:random:compared] we demonstrate that the scaled version has its own variant.
+
+\unexpanded\def\TestRandomFun#1#2#3%
+ {\startMPcode{#1}
+ draw image(\includeMPgraphic{#2})
+ withcolor #3 ;
+ \stopMPcode}
+
+\startplacefigure[reference=fig:random:1,title={The scaled randomizers.}]
+ \pushrandomseed
+ \startcombination
+ {\TestRandomFun{metafun} {normaldeviate} {darkred}} {normaldeviate}
+ {\TestRandomFun{metafun} {uniformdeviate}{darkred}} {uniformdeviate}
+ \stopcombination
+ \poprandomseed
+\stopplacefigure
+
+\startplacefigure[reference=fig:random:2,title={The double randomizers.}]
+ \pushrandomseed
+ \startcombination
+ {\TestRandomFun{doublefun} {normaldeviate} {darkgreen}} {normaldeviate}
+ {\TestRandomFun{doublefun} {uniformdeviate}{darkgreen}} {uniformdeviate}
+ \stopcombination
+ \poprandomseed
+\stopplacefigure
+
+\startplacefigure[reference=fig:random:3,title={The decimal randomizers.}]
+ \pushrandomseed
+ \startcombination
+ {\TestRandomFun{decimalfun}{normaldeviate} {darkblue}} {normaldeviate}
+ {\TestRandomFun{decimalfun}{uniformdeviate}{darkblue}} {uniformdeviate}
+ \stopcombination
+ \poprandomseed
+\stopplacefigure
+
+\startplacefigure[reference=fig:random:4,title={The binary randomizers.}]
+ \pushrandomseed
+ \startcombination
+ {\TestRandomFun{binaryfun} {normaldeviate} {darkyellow}} {normaldeviate}
+ {\TestRandomFun{binaryfun} {uniformdeviate}{darkyellow}} {uniformdeviate}
+ \stopcombination
+ \poprandomseed
+\stopplacefigure
+
+\startplacefigure[reference=fig:random:compared,title={Normaldeviate and uniformdeviate overlayed.}]
+ \pushrandomseed
+ \startcombination[2*1]
+ \bgroup
+ \startoverlay
+ {\TestRandomFun{metafun} {normaldeviate} {darkred}}
+ {\TestRandomFun{doublefun} {normaldeviate} {darkgreen}}
+ {\TestRandomFun{decimalfun}{normaldeviate} {darkblue}}
+ {\TestRandomFun{binaryfun} {normaldeviate} {darkyellow}}
+ \stopoverlay
+ \egroup {normaldeviate}
+ \bgroup
+ \startoverlay
+ {\TestRandomFun{metafun} {uniformdeviate}{darkred}}
+ {\TestRandomFun{doublefun} {uniformdeviate}{darkgreen}}
+ {\TestRandomFun{decimalfun}{uniformdeviate}{darkblue}}
+ {\TestRandomFun{binaryfun} {uniformdeviate}{darkyellow}}
+ \stopoverlay
+ \egroup {uniformdeviate}
+ \stopcombination
+ \poprandomseed
+\stopplacefigure
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-environment-layout.tex b/doc/context/sources/general/manuals/metafun/metafun-environment-layout.tex
new file mode 100644
index 000000000..409839cba
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-environment-layout.tex
@@ -0,0 +1,151 @@
+\startenvironment metafun-environment-layout
+
+\setupsystem
+ [random=big]
+
+\setupfootertexts
+ [section][] % [Preliminary Version \currentdate][]
+ [][section] % [][Preliminary Version \currentdate]
+
+\useMPlibrary
+ [clp,txt]
+
+\definepapersize
+ [mine]
+ [width=21cm,
+ height=28cm]
+
+\setuppapersize
+ [mine]
+ [A4]
+
+\setuplayout
+ [topspace=1cm,
+ backspace=3cm,
+ cutspace=3cm,
+ leftmargin=.75cm,
+ leftmargindistance=.5cm,
+ rightmargin=1.25cm,
+ rightmargindistance=1cm,
+ header=1cm,
+ headerdistance=1cm,
+ footer=1cm,
+ footerdistance=1cm,
+ width=middle,
+ height=middle,
+ % marking=on,
+ location=middle]
+
+\startmode[book]
+
+ % \definepapersize
+ % [mine]
+ % [width=21cm,
+ % height=24cm]
+ %
+ % \setuppapersize
+ % [mine]
+ % [oversized]
+ %
+ % \setuplayout
+ % [backspace=2.5cm,
+ % cutspace=3.5cm]
+
+ \setuplayout
+ [marking=on,
+ scale=\luaexpr{24/28}]
+
+\stopmode
+
+\startmode[print]
+
+ \setuppapersize
+ [mine]
+ [mine]
+
+\stopmode
+
+\setupcolumns
+ [distance=1cm]
+
+\setuppagenumbering
+ [alternative=doublesided]
+
+\definetypeface [metafunbodyfont] [rm] [serif] [pagella] [default]
+\definetypeface [metafunbodyfont] [ss] [sans] [modern] [default]
+\definetypeface [metafunbodyfont] [tt] [mono] [modern] [default]
+\definetypeface [metafunbodyfont] [mm] [math] [palatino] [default]
+
+\setupbodyfont [metafunbodyfont,10pt] % 11 pt and 12pt -> errors due to intersection mess
+
+\definefont[RotFont][RegularBold*default]
+
+% \setupindenting
+% [medium,yes]
+
+\setupwhitespace
+ [medium]
+
+\setuptyping
+ [margin=standard,
+ blank=halfline]
+
+\definecolor [darkred] [r=.625]
+\definecolor [darkyellow] [r=.625,g=.625] % not: [y=.625]
+\definecolor [darkgray] [s=.625]
+\definecolor [lightgray] [s=.875]
+
+\definecolor [metafun] [darkred]
+
+\startMPinclusions
+ color darkred ; darkred := \MPcolor{darkred} ;
+ color darkyellow ; darkyellow := \MPcolor{darkyellow} ;
+ color darkgray ; darkgray := \MPcolor{darkgray} ;
+ color lightgray ; lightgray := \MPcolor{lightgray} ;
+\stopMPinclusions
+
+\setupinteraction % otherwise funny page dimensions due to
+ [state=start, % grouping half way the file in demo text
+ style=,
+ color=,
+ contrastcolor=]
+
+% \enabledirectives[refences.linkmethod=page]
+
+% \setupstructure % needs \startchapter
+% [state=start]
+
+\placebookmarks
+ [chapter,title,section]
+ [all]
+ [force=yes]
+
+\setuptolerance
+ [verytolerant]
+
+\definestartstop
+ [intro]
+ [style=slanted,
+ after=\blank]
+
+\setupquote
+ [before=\blank\startnarrower,
+ after=\stopnarrower\blank]
+
+\setuplist
+ [chapter]
+ [after={\blank[line]}]
+
+\setupcombinedlist
+ [content]
+ [aligntitle=yes,
+ alternative=c,
+ interaction=all]
+
+\setuptabulate
+ [rulecolor=darkyellow,
+ rulethickness=1pt]
+
+\setuplist[chapter][style=bold]
+
+\stopenvironment
diff --git a/doc/context/sources/general/manuals/metafun/metafun-environment-samples.tex b/doc/context/sources/general/manuals/metafun/metafun-environment-samples.tex
new file mode 100644
index 000000000..5991a61d5
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-environment-samples.tex
@@ -0,0 +1,321 @@
+\startenvironment metafun-environment-sample
+
+\startuseMPgraphic{sample setup}
+ numeric Scale ; Scale := 2cm ;
+ numeric Size ; Size := 2.5mm/Scale ;
+ numeric Pen ; Pen := .25mm/Scale ;
+ path Path ;
+ pickup pencircle scaled (4Pen) ;
+ def InRed = withcolor .625red enddef ;
+ def InYellow = withcolor .625yellow enddef ;
+ def InGray = withpen pencircle scaled Pen withcolor .625white enddef ;
+ def InBetween= withpen pencircle scaled (4Pen) withcolor .800white enddef ;
+ def InBlack = withpen pencircle scaled Pen enddef ;
+ def InWhite = withpen pencircle scaled Pen withcolor white enddef ;
+ def DrawArrow text t =
+ draw t ; Path := boundingbox currentpicture ;
+ drawarrow t ; setbounds currentpicture to Path ;
+ enddef ;
+ def ColorCircle =
+ fill llcircle withcolor .625red ;
+ fill lrcircle withcolor .625green ;
+ fill urcircle withcolor .625blue ;
+ fill ulcircle withcolor .625yellow ;
+ enddef ;
+ evenly := dashpattern(on (3mm/Scale) off (3mm/Scale)) ;
+ withdots := dashpattern(off (2.5mm/Scale) on 0 off (2.5mm/Scale)) ;
+ ahlength := 4mm/Scale ; ahangle := 30 ;
+ draw (origin shifted (0,Size)--origin shifted (0,-Size)) ;
+ draw (origin shifted (Size,0)--origin shifted (-Size,0)) ;
+ picture Origin ; Origin := currentpicture ;
+ setbounds Origin to origin--cycle ;
+ currentpicture := nullpicture ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{sample finish}
+ draw boundingbox currentpicture InBlack ;
+ draw Origin InGray ;
+ currentpicture := currentpicture scaled Scale ;
+\stopuseMPgraphic
+
+% fm = metafun macro
+% fv = metafun variable
+% mc = metapost concept
+% mm = metapost macro
+% mp = metapost primitive
+% mv = metapost variable
+
+\starttexdefinition unexpanded DoDoSampleHead#1#2#3
+ \setbox\scratchbox\vbox {
+ \tabskip\zeropoint
+ \tt\tfx
+ \halign {
+ \strut\hss##\unskip\unskip
+ \cr#3\cr#1\cr
+ }
+ }
+ \ht\scratchbox\ht\strutbox
+ \dp\scratchbox\dp\strutbox
+ \noligature{#2}\black
+ \hfill
+ \box\scratchbox
+ \ignorespaces
+\stoptexdefinition
+
+\starttexdefinition unexpanded DoSampleHead #1#2#3
+ \processaction
+ [#1]
+ [fm=>\DoDoSampleHead{metafun macro}{#2}{#3},
+ fv=>\DoDoSampleHead{metafun variable}{#2}{#3},
+ mc=>\DoDoSampleHead{metapost concept}{#2}{#3},
+ mm=>\DoDoSampleHead{metapost macro}{#2}{#3},
+ mp=>\DoDoSampleHead{metapost primitive}{#2}{#3},
+ mv=>\DoDoSampleHead{metapost variable}{#2}{#3}]
+\stoptexdefinition
+
+\starttexdefinition unexpanded SampleHead #1#2#3
+ \expanded{\extrosubject{\DoSampleHead{#1}{#2}{\detokenize{#3}}}}
+\stoptexdefinition
+
+\starttexdefinition unexpanded StartSample
+ \doquintuplegroupempty\doStartSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded StopSample
+ % dummy
+\stoptexdefinition
+
+\starttexdefinition unexpanded doStartSample #1#2#3#4#5#6 StopSample
+ \bgroup
+ \SampleHead{#1}{#2}{#3}
+ \startuseMPgraphic{dummy}
+ \includeMPgraphic{sample setup}
+ #6
+ \includeMPgraphic{sample finish}
+ \stopuseMPgraphic
+ \blank[samepage]
+ \startlinecorrection[blank]
+ \useMPgraphic{dummy}
+ \stoplinecorrection
+ \egroup
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleZ #1#2#3
+ \bgroup
+ \SampleHead{#1}{#2}{}
+ \blank[samepage]
+ #3
+ \par
+ \egroup
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleA #1#2#3
+ \StartSample{#1}{#2}{#3}
+ path p ; p := #3 ; % freeze randomized
+ if length(p)>0 :
+ DrawArrow p InRed ;
+ fi ;
+ drawpoints p InBetween ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleB #1#2#3#4
+ \StartSample{#1}{#2}{#4}
+ DrawArrow (#3) InRed ;
+ DrawArrow (#4) InYellow ;
+ drawpoints (#3) InBetween ;
+ drawpoints (#4) InBetween ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleC #1#2#3#4
+ \StartSample{#1}{#2}{#4}
+ path bb ; bb := boundingbox #3 ;
+ DrawArrow #3 InRed ;
+ draw #4 withpen pencircle scaled .15 InYellow ;
+ setbounds currentpicture to bb ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleD #1#2#3#4
+ \StartSample{#1}{#2}{#4}
+ DrawArrow #3 InRed ;
+ setbounds currentpicture to #4 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleDD #1#2#3#4
+ \StartSample{#1}{#2}{#4}
+ DrawArrow #3 InRed ;
+ DrawArrow #4 InYellow ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleE #1#2#3#4
+ \StartSample{#1}{#2}{#4}
+ fill fullcircle scaled 1cm InRed ;
+ currentpicture := currentpicture #3 ;
+ Scale := 1 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleF #1#2#3#4
+ \StartSample{#1}{#2}{#4}
+ DrawArrow #3 InRed ;
+ drawdot #4 InYellow ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleG #1#2#3#4
+ \StartSample{#1}{#2}{#4}
+ draw #3 InRed ;
+ drawdot #4 InYellow ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleH #1#2#3#4#5
+ \StartSample{#1}{#2}{#5}
+ DrawArrow #3 InRed ;
+ DrawArrow #4 InYellow ;
+ drawdot #5 InWhite ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleHH #1#2#3
+ \StartSample{#1}{#2}{#3}
+ draw #3 InRed ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleI #1#2#3
+ \StartSample{#1}{#2}{#3}
+ draw fullcircle InRed #3 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleII #1#2#3
+ \StartSample{#1}{#2}{#3}
+ draw fullcircle #3 InRed ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleJ #1#2#3
+ \StartSample{#1}{withpen #2}{withpen #3 scaled 2mm}
+ draw fullcircle xscaled 2 withpen #3 scaled Pen InRed ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleK #1#2#3
+ \StartSample{#1}{withpen #2}{withpen #3}
+ draw fullcircle xscaled 2 withpen #3 InRed ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleL #1#2#3
+ \StartSample{#1}{#2}{#2 #3}
+ #2 #3 InRed;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleM #1#2#3
+ \StartSample{#1}{#2}{#2 #3}
+ fill boundingbox (#3--cycle) InRed ;
+ #2 #3 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleN #1#2#3#4
+ \StartSample{#1}{#2}{#3}
+ #3 ;
+ draw #4 withpen pencircle scaled 25Pen InRed ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleO #1#2#3
+ \StartSample{#1}{#2}{#3}
+ drawdot origin InRed ;
+ #3 scaled (2.5/Scale) InYellow ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleP #1#2#3
+ \StartSample{#1}{#2}{#3}
+ drawdot origin InRed ;
+ #3 scaled (2.5/Scale) InYellow ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleQ #1#2#3
+ \StartSample{#1}{#2}{#3}
+ #2 #3 withpen pencircle scaled 25Pen InRed ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleQQ #1#2#3
+ \StartSample{#1}{#2}{#3}
+ #3 scaled (2.5/Scale) withpen pencircle scaled Pen InYellow ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleQQQ #1#2#3
+ \StartSample{#1}{#2}{#3}
+ #3 scaled (2.5/Scale) withpen pencircle scaled Pen ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleR #1#2#3
+ \StartSample{#1}{#2}{#3}
+ ColorCircle ;
+ addto currentpicture also (#3) shifted (bbwidth(currentpicture)+.1,0) ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleS #1#2#3
+ \StartSample{#1}{#2}{#3}
+ Pen := Pen * Scale ; Scale := 1 ; #3 ;%
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleT #1#2#3#4
+ \StartSample{#1}{#2}{#3}
+ #4 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleU #1#2#3
+ \StartSample{#1}{#2}{#3}
+ Scale := Scale / 5 ;
+ #3 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleUU #1#2#3
+ \StartSample{#1}{#2}{#3}
+ Scale := Scale / 10 ;
+ #3 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleV #1#2#3#4
+ \StartSample{#1}{#2}{#3}
+ Scale := Scale / 5 ;
+ Pen := Pen * 20 ;
+ #4 ;
+ Pen := Pen / 20 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleW #1#2#3#4
+ \StartSample{#1}{#2}{#3}
+ Scale := 1 ;
+ #4 ;
+ \StopSample
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowSampleX #1#2#3
+ \StartSample{#1}{#2}{#3}
+ #3 InRed ;
+ \StopSample
+\stoptexdefinition
+
+\stopenvironment
diff --git a/doc/context/sources/general/manuals/metafun/metafun-environment-screen.tex b/doc/context/sources/general/manuals/metafun/metafun-environment-screen.tex
new file mode 100644
index 000000000..afeea7008
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-environment-screen.tex
@@ -0,0 +1,139 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startenvironment mfun-environment-screen
+
+\enablemode[screen]
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [backspace=60pt,
+ topspace=60pt,
+ cutspace=0pt,
+ header=0pt,
+ footer=0pt,
+ bottom=20pt,
+ bottomdistance=40pt,
+ top=20pt,
+ topdistance=40pt,
+ leftmargin=30pt,
+ leftmargindistance=25pt,
+ rightmargin=0pt,
+ edge=0pt,
+ width=middle,
+ height=middle]
+
+\setupbodyfont
+ [9pt]
+
+\setuppagenumbering
+ [alternative=singlesided]
+
+\setupinteraction
+ [state=start,
+ style=bold,
+ color=darkred,
+ contrastcolor=darkred,
+ symbolset=navigation 3,
+ menu=on]
+
+\setupsymbolset
+ [navigation 3]
+
+\setupinteractionscreen
+ [option=max]
+
+\setupinteractionmenu
+ [bottom]
+ [unknownreference=yes,
+ state=start]
+
+\setuptoptexts
+ []
+ [{\lightgray \bf Page \pagenumber
+ \doifcontent\quad{}{}\hbox{\getmarking[section]}}]
+
+\startinteractionmenu[bottom]
+ \txt \bf \lightgray \getmarking[chapter] \\
+ \hfill
+ \bgroup
+ \setupinteraction[color=white,contrastcolor=white]
+ \got [CloseDocument] exit \\
+ \egroup
+ \got [content] content \\
+ \got [index] index \\
+% \got [commands] commands \\
+ \got [reference] reference \\
+ \setupinteraction[color=white,contrastcolor=white]
+ \got [PreviousJump] \symbol[PreviousJump] \\
+ \got [previouspage] \symbol[previouspage] \\
+ \got [nextpage] \symbol[nextpage] \\
+ \got [NextJump] \symbol[NextJump] \\
+\stopinteractionmenu
+
+\starttexdefinition unexpanded ChapterCommand #1#2
+ \framed [
+ background=titled,
+ frame=off
+ ] {
+ #1
+ \quad
+ #2
+ }
+\stoptexdefinition
+
+\startuseMPgraphic{PageFrame}
+ StartPage ;
+ save p, q, ranx, rany, minx, miny, maxx, maxy ;
+ pickup pencircle scaled 4pt ;
+ pair p[] ; path q[] ; numeric ranx, rany, minx, miny, maxx, maxy ;
+ minx := BackSpace/2 ; maxx := PaperWidth -minx ; ranx := minx/2 ;
+ miny := TopSpace /2 ; maxy := PaperHeight-miny ; rany := miny/2 ;
+ p[0] := llcorner Page ;
+ p[1] := (minx,0) randomshifted (ranx,0) ;
+ p[2] := (maxx,0) randomshifted (ranx,0) ;
+ p[3] := lrcorner Page ;
+ p[4] := (PaperWidth,miny) randomshifted (0,rany) ;
+ p[5] := (PaperWidth,maxy) randomshifted (0,rany) ;
+ p[6] := urcorner Page ;
+ p[7] := (maxx,PaperHeight) randomshifted (ranx,0) ;
+ p[8] := (minx,PaperHeight) randomshifted (ranx,0) ;
+ p[9] := ulcorner Page ;
+ p[10] := (0,maxy) randomshifted (0,rany) ;
+ p[11] := (0,miny) randomshifted (0,rany) ;
+ def page_color = (.4+uniformdeviate.3)*white enddef ;
+ fill Page withcolor \MPcolor{lightgray} ;
+ q[1] := p[9]--p[6]--p[ 5]--p[10]--cycle ;
+ q[2] := p[6]--p[3]--p[ 2]--p[ 7]--cycle ;
+ q[3] := p[3]--p[0]--p[11]--p[ 4]--cycle ;
+ q[4] := p[0]--p[9]--p[ 8]--p[ 1]--cycle ;
+ for i=1 upto 4: fill q[i] withcolor page_color ; endfor ;
+ q[1] := p[9]--p[8]--((p[8]--p[ 1]) intersectionpoint (p[10]--p[ 5]))--p[10]--cycle ;
+ q[2] := p[6]--p[5]--((p[5]--p[10]) intersectionpoint (p[ 2]--p[ 7]))--p[ 7]--cycle ;
+ q[3] := p[3]--p[4]--((p[4]--p[11]) intersectionpoint (p[ 7]--p[ 2]))--p[ 2]--cycle ;
+ q[4] := p[0]--p[1]--((p[1]--p[ 8]) intersectionpoint (p[ 4]--p[11]))--p[11]--cycle ;
+ for i=1 upto 4: fill q[i] withcolor page_color ; endfor ;
+ q[1] := p[ 8]--p[1] ;
+ q[2] := p[ 7]--p[2] ;
+ q[3] := p[10]--p[5] ;
+ q[4] := p[11]--p[4] ;
+ for i=1 upto 4: draw q[i] withcolor \MPcolor{darkred} ; endfor ;
+ StopPage ;
+\stopuseMPgraphic
+
+% \setupbackgrounds[page][background=PageFrame]
+
+\setupbackgrounds
+ [page]
+ [background={PageFrame,backgraphics,foreground,foregraphics}]
+
+\defineoverlay[PageFrame][\useMPgraphic{PageFrame}]
+
+\startMPinclusions
+ background := \MPcolor{lightgray} ;
+\stopMPinclusions
+
+\stopenvironment
diff --git a/doc/context/sources/general/manuals/metafun/metafun-environment.tex b/doc/context/sources/general/manuals/metafun/metafun-environment.tex
new file mode 100644
index 000000000..ca9fc24b3
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-environment.tex
@@ -0,0 +1,595 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startenvironment metafun-environment
+
+\environment metafun-environment-layout
+
+\usemodule[abr-01,syntax]
+
+\startuseMPgraphic{cover page}
+
+ numeric w ; w := PaperWidth -eps ; % or clip
+ numeric h ; h := PaperHeight-eps ; % or clip
+
+ for i=0cm step 1cm until w :
+ for j=0cm step 1cm until h :
+ fill unitsquare scaled 1cm shifted (i,j) withcolor (.6+uniformdeviate.35)*white ;
+ endfor ;
+ endfor ;
+
+ % clip currentpicture to unitsquare xyscaled (w,h) ;
+
+ for i=0cm step 1cm until w+.5cm :
+ draw (i,0) -- (i,h) withpen pensquare scaled .5mm withcolor .625yellow ;
+ endfor ;
+
+ for i=0cm step 1cm until h+.5cm :
+ draw (0,i) -- (w,i) withpen pensquare scaled .5mm withcolor .625yellow ;
+ endfor ;
+
+\stopuseMPgraphic
+
+\startuseMPgraphic{title page}
+
+ StartPage ;
+
+ \includeMPgraphic{cover page}
+
+ picture p ; p := image (draw rawtextext("\darkred\definedfont[Sans]metafun" )) ;
+ picture q ; q := image (draw rawtextext("\darkred\definedfont[Sans]Hans Hagen")) ;
+ % picture r ; r := image (draw rawtextext("\darkred\definedfont[Sans]\doifnotmode{book}{context mkiv}")) ;
+ picture r ; r := image (draw rawtextext("\darkred\definedfont[Sans]context mkiv")) ;
+
+ p := p xsized(PaperHeight - 2cm) ;
+ q := q xsized(PaperWidth - 8cm) ;
+ r := r xsized(6cm) ;
+
+ p := p rotated 90 ;
+ r := r rotated 90 ;
+
+ draw p shifted (urcorner Page - urcorner p - (1cm,1cm) - (-1mm,0) ) ;
+ draw q shifted (1cm, 1cm) ;
+ draw r shifted (urcorner Page - urcorner r - (5cm,2cm) ) ;
+
+ StopPage ;
+
+ setbounds currentpicture to Page ;
+
+\stopuseMPgraphic
+
+\startuseMPgraphic{back page}
+
+ \includeMPgraphic{cover page}
+
+\stopuseMPgraphic
+
+\startuseMPgraphic{small grid}
+
+ numeric w ; w := \overlaywidth ;
+ numeric h ; h := \overlayheight ;
+ numeric d ; d := .25cm ;
+
+ drawoptions(withcolor (.6+uniformdeviate.35)*white) ;
+
+ for i=0cm step d until w :
+ for j=0cm step d until h :
+ fill unitsquare scaled d shifted (i,j) ;
+ endfor ;
+ endfor ;
+
+ drawoptions(withpen pencircle scaled .125mm withcolor .625yellow) ;
+
+ for i=0 step d until w+d : draw (i,0) -- (i,h) ; endfor ;
+ for i=0 step d until h+d : draw (0,i) -- (w,i) ; endfor ;
+
+\stopuseMPgraphic
+
+\defineoverlay[title page][\useMPgraphic{title page}]
+
+\startnotmode[proof]
+ \defineoverlay[back page][\useMPgraphic{back page}]
+ \defineoverlay[small grid][\useMPgraphic{small grid}]
+\stopnotmode
+
+% could be all in mp
+
+\starttexdefinition unexpanded OnGrid#1
+ \hbox to \hsize \bgroup
+ \ifodd\realpageno
+ \hss
+ \fi
+ \setbox\scratchbox=\hbox {
+ \color[darkred]{#1}
+ }
+ \scratchoffset.25cm
+ \scratchwidth\wd\scratchbox
+ \ifdim\scratchwidth>\zeropoint
+ \advance \scratchwidth by .5\scratchoffset
+ \divide \scratchwidth by \scratchoffset
+ \multiply\scratchwidth by \scratchoffset
+ \advance \scratchwidth by 2\scratchoffset
+ \else
+ \scratchwidth8\scratchoffset
+ \fi
+ \dp\scratchbox \scratchoffset
+ \ht\scratchbox 2\scratchoffset
+ \framed [
+ background=small grid,
+ frame=off,
+ offset=overlay
+ ] {
+ \hbox to \scratchwidth {
+ \hss
+ \box\scratchbox
+ \hss
+ }
+ }
+ \unless \ifodd\realpageno
+ \hss
+ \fi
+ \egroup
+\stoptexdefinition
+
+\setupfootertexts
+ [margin]
+ []
+ [\OnGrid{\doifelsetext{\getmarking[chapter]}{\getmarking[chapter]}{\getmarking[title]}}]
+
+\startuseMPgraphic{circled}
+ pickup pencircle scaled 1mm ;
+ drawoptions(withcolor (.6+uniformdeviate.35)*white) ;
+ fill fullcircle xscaled 1.5cm yscaled 1cm ;
+ drawoptions(withcolor .625yellow) ;
+ draw fullcircle xscaled 1.5cm yscaled 1cm ;
+\stopuseMPgraphic
+
+\startnotmode[proof]
+ \defineoverlay[circled][\useMPgraphic{circled}]
+\stopnotmode
+
+\starttexdefinition unexpanded Circled #1
+ \framed [
+ background=circled,
+ frame=off,
+ offset=overlay
+ ] {
+ \color[darkred]{#1}
+ }
+\stoptexdefinition
+
+\setuppagenumbering
+ [location=]
+
+\setupheadertexts
+ [margin]
+ [][\hbox to \hsize{\hss\Circled\pagenumber\hss}]
+
+\setupheader
+ [style=bold]
+
+\setupfooter
+ [style=bold]
+
+\startuniqueMPgraphic{titled}
+ path p ; p := unitsquare xscaled OverlayWidth yscaled OverlayHeight ;
+ pickup pencircle scaled 1mm ;
+ drawoptions(withcolor .625yellow) ;
+ draw llcorner p -- lrcorner p ;
+ setbounds currentpicture to p ;
+\stopuniqueMPgraphic
+
+\defineoverlay[titled][\uniqueMPgraphic{titled}]
+
+\starttexdefinition unexpanded ChapterCommand #1#2
+ \ifconditional\headshownumber
+ \ifdim\leftmarginwidth<\rightmarginwidth
+ \donetrue
+ \else
+ \donefalse
+ \fi
+ \hskip-\ifdone\leftmargintotal\else\rightmargintotal\fi
+ \framed [
+ background=titled,
+ frame=off,
+ offset=0pt
+ ] {
+ \hbox to \ifdone\leftmarginwidth\else\rightmarginwidth\fi {
+ #1
+ \hss
+ }
+ \hskip\ifdone\leftmargindistance\else\rightmargindistance\fi
+ #2
+ }
+ \else
+ \framed [
+ background=titled,
+ frame=off,
+ offset=0pt
+ ] {
+ #2
+ }
+ \fi
+\stoptexdefinition
+
+\starttexdefinition unexpanded TitleCommand #1#2
+ \framed [
+ background=titled,
+ frame=off,
+ offset=0pt
+ ] {
+ #2
+ }
+\stoptexdefinition
+
+\starttexdefinition unexpanded IntroTitleCommand #1#2
+ \framed [
+ background=titled,
+ frame=off,
+ offset=0pt,
+ width=\textwidth
+ ] {
+ \hfill
+ #2
+ }
+\stoptexdefinition
+
+\starttexdefinition unexpanded ExtroTitleCommand #1#2
+ \framed [
+ background=titled,
+ frame=off,
+ offset=0pt,
+ width=\textwidth
+ ] {
+ \hss
+ #2
+ \hss
+ }
+\stoptexdefinition
+
+\setuphead
+ [chapter,section,subsection,subsubsection]
+ [color=darkred]
+
+\setuphead
+ [chapter]
+ [style=\bfc]
+
+\setuphead
+ [section]
+ [style=\bfa]
+
+\setuphead
+ [subsection]
+ [style=\bf]
+
+\setuphead
+ [subsubsection]
+ [style=\bf]
+
+\setuphead
+ [chapter,section,subsection,subsubsection]
+ [command=\ChapterCommand]
+
+\setuphead
+ [title,subject,subsubject,subsubsubject]
+ [command=\TitleCommand]
+
+
+\definehead [introsubject] [subsubject]
+\definehead [extrosubject] [subsubject]
+
+\setuphead [introsubject] [command=\IntroTitleCommand]
+\setuphead [extrosubject] [command=\ExtroTitleCommand]
+
+\setuphead
+ [subsection,subsubject]
+ [before=\blank,
+ after=\blank]
+
+% charts
+
+\usemodule[chart]
+
+\setupFLOWcharts
+ [offset=0pt,
+ width=6\bodyfontsize,
+ height=3\bodyfontsize,
+ dx=\bodyfontsize,
+ dy=\bodyfontsize]
+
+\setupFLOWshapes
+ [framecolor=darkred]
+
+\setupFLOWlines
+ [color=darkyellow]
+
+% hm, slows down the whole doc
+
+\setupbackgrounds
+ [page]
+ [background={backgraphics,foreground,foregraphics}]
+
+\defineoverlay [backgraphics] [\positionoverlay{backgraphics}]
+\defineoverlay [foregraphics] [\positionoverlay{foregraphics}]
+
+\startbuffer[shape-a]
+\startuniqueMPgraphic{meta:hash}{linewidth,linecolor,angle,gap}
+ if unknown context_back : input mp-back ; fi ;
+ some_hash ( OverlayWidth, OverlayHeight ,
+ \MPvar{linewidth}, \MPvar{linecolor} ,
+ \MPvar{angle}, \MPvar{gap} ) ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\startbuffer[shape-b]
+\setupMPvariables
+ [meta:hash]
+ [gap=.25\bodyfontsize,
+ angle=45,
+ linewidth=\overlaylinewidth,
+ linecolor=\overlaylinecolor]
+\stopbuffer
+
+\startbuffer[shape-c]
+\def\metahashoverlay#1{\uniqueMPgraphic{meta:hash}{angle=#1}}
+
+\defineoverlay[meta:hash:right] [\metahashoverlay{ +45}]
+\defineoverlay[meta:hash:left] [\metahashoverlay{ -45}]
+\defineoverlay[meta:hash:horizontal][\metahashoverlay{+180}]
+\defineoverlay[meta:hash:vertical] [\metahashoverlay{ -90}]
+\stopbuffer
+
+\startbuffer[symb-a]
+\startuniqueMPgraphic{meta:button}{type,size,linecolor,fillcolor}
+ if unknown context_butt : input mp-butt ; fi ;
+ some_button ( \MPvar{type},
+ \MPvar{size},
+ \MPvar{linecolor},
+ \MPvar{fillcolor} ) ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\startbuffer[symb-b]
+\setupMPvariables
+ [meta:button]
+ [type=1,
+ size=2\bodyfontsize,
+ fillcolor=gray,
+ linecolor=darkred]
+\stopbuffer
+
+\startbuffer[symb-c]
+\def\metabuttonsymbol#1{\uniqueMPgraphic{meta:button}{type=#1}}
+
+\definesymbol[menu:left] [\metabuttonsymbol{101}]
+\definesymbol[menu:right] [\metabuttonsymbol{102}]
+\definesymbol[menu:list] [\metabuttonsymbol{103}]
+\definesymbol[menu:index] [\metabuttonsymbol{104}]
+\definesymbol[menu:person][\metabuttonsymbol{105}]
+\definesymbol[menu:stop] [\metabuttonsymbol{106}]
+\definesymbol[menu:info] [\metabuttonsymbol{107}]
+\definesymbol[menu:down] [\metabuttonsymbol{108}]
+\definesymbol[menu:up] [\metabuttonsymbol{109}]
+\definesymbol[menu:print] [\metabuttonsymbol{110}]
+\stopbuffer
+
+\hyphenation{tool-kit}
+
+\startbuffer[pagetext]
+\subject{Edward R. Tufte} \input tufte \par
+\subject{Donald E. Knuth} \input knuth \par
+\subject{Douglas R. Hostadter} \input douglas \page
+\stopbuffer
+
+\startbuffer[back-0]
+\defineoverlay[page][\useMPgraphic{page}]
+\setupbackgrounds[page][background=page]
+\stopbuffer
+
+\startbuffer[back-1]
+\startuseMPgraphic{page}
+ StartPage ;
+ path Main ;
+ if OnRightPage :
+ Main := lrcorner Field[OuterMargin][Text] --
+ llcorner Field[Text] [Text] --
+ ulcorner Field[Text] [Text] --
+ urcorner Field[OuterMargin][Text] -- cycle ;
+ else :
+ Main := llcorner Field[OuterMargin][Text] --
+ lrcorner Field[Text] [Text] --
+ urcorner Field[Text] [Text] --
+ ulcorner Field[OuterMargin][Text] -- cycle ;
+ fi ;
+ Main := Main enlarged 6pt ;
+ pickup pencircle scaled 2pt ;
+ fill Page withcolor .625white ;
+ fill Main withcolor .850white ;
+ draw Main withcolor .625red ;
+ StopPage ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[back-2]
+\startuseMPgraphic{page}
+ StartPage ;
+ pickup pencircle scaled 2pt ;
+ fill Page withcolor .625white ;
+ fill Field[OuterMargin][Text] withcolor .850white ;
+ fill Field[Text] [Text] withcolor .850white ;
+ draw Field[OuterMargin][Text] withcolor .625red ;
+ draw Field[Text] [Text] withcolor .625red ;
+ StopPage ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[back-3]
+\startuseMPgraphic{page}
+ StartPage ;
+ pickup pencircle scaled 2pt ;
+ fill Page withcolor .625white ;
+ fill Field[Text][Text] enlarged .5cm withcolor .850white ;
+ draw Field[Text][Text] enlarged .5cm withcolor .625red ;
+ StopPage ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[back-4]
+\startuseMPgraphic{page}
+ StartPage ;
+ def somewhere =
+ (uniformdeviate 1cm,uniformdeviate 1cm)
+ enddef ;
+ path Main ;
+ Main := Field[Text][Text] lrmoved somewhere --
+ Field[Text][Text] llmoved somewhere --
+ Field[Text][Text] ulmoved somewhere --
+ Field[Text][Text] urmoved somewhere -- cycle ;
+ pickup pencircle scaled 2pt ;
+ fill Page withcolor .625white ;
+ fill Main withcolor .850white ;
+ draw Main withcolor .625red ;
+ StopPage ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[back-4x]
+\startuseMPgraphic{page}
+ StartPage ;
+ path Main ; Main := Field[Text][Text] randomized 1cm ;
+ pickup pencircle scaled 2pt ;
+ fill Page withcolor .625white ;
+ fill Main withcolor .850white ;
+ draw Main withcolor .625red ;
+ StopPage ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[back-5]
+\startuseMPgraphic{page}
+ StartPage
+ for i=Top,Header,Text,Footer,Bottom :
+ for j=LeftEdge,LeftMargin,Text,RightMargin,RightEdge :
+ draw Field[i][j] withpen pencircle scaled 2pt withcolor .625red ;
+ endfor ;
+ endfor ;
+ StopPage
+\stopuseMPgraphic
+\stopbuffer
+
+\starttexdefinition unexpanded Literature #1#2#3
+ \blank
+ \noindentation
+ #1
+ \space
+ \begingroup
+ \bf
+ #2
+ \endgroup
+ \space
+ #3
+ \blank
+\stoptexdefinition
+
+\environment metafun-environment-samples
+
+\startbuffer[handwrit]
+
+\usetypescript[serif][chorus]
+
+\definefont[SomeHandwriting][TeXGyreChorus-MediumItalic*default at 12pt]
+
+\start \SomeHandwriting\setstrut
+
+\startMPpage
+ StartPage ;
+ numeric l, n ; path p ;
+ l := 1.5LineHeight ;
+ n := 0 ;
+ p := origin shifted (l,0) -- origin shifted (PaperWidth-l,0) ;
+ for i=PaperHeight-l step -l until l :
+ n := n + 1 ;
+ fill p shifted (0,i+StrutHeight) --
+ reverse p shifted (0,i-StrutDepth ) -- cycle
+ withcolor .85white ;
+ draw p shifted (0,i)
+ withpen pencircle scaled .25pt
+ withcolor .5white ;
+ draw p shifted (0,i+ExHeight)
+ withpen pencircle scaled .25pt
+ withcolor .5white ;
+ draw textext.origin("\strut How are those penalty lines called
+ in english? I may not steal candies ..." & decimal n)
+ shifted (l,i)
+ shifted (0,-StrutDepth) ;
+ endfor ;
+ StopPage ;
+\stopMPpage
+\stop
+\stopbuffer
+
+\startbuffer[gridpage]
+\startMPpage
+ StartPage ;
+ width := PaperWidth ; height := PaperHeight ; unit := cm ;
+ drawoptions(withpen pencircle scaled .2pt withcolor .8white) ;
+ draw vlingrid(0, width /unit, 1/10, width, height) ;
+ draw hlingrid(0, height/unit, 1/10, height, width ) ;
+ drawoptions(withpen pencircle scaled .5pt withcolor .4white) ;
+ draw vlingrid(0, width /unit, 1, width, height) ;
+ draw hlingrid(0, height/unit, 1, height, width ) ;
+ StopPage ;
+\stopMPpage
+\stopbuffer
+
+% needed to get white backgrounds
+
+\startmode[screen]
+
+\startbuffer[wipe]
+picture savedpicture ;
+savedpicture := currentpicture ;
+currentpicture := nullpicture ;
+draw savedpicture withcolor black ;
+draw savedpicture ;
+\stopbuffer
+
+\stopmode
+
+\startnotmode[screen]
+
+\startbuffer[wipe]
+ % nothing to whipe
+\stopbuffer
+
+\stopnotmode
+
+\startbuffer[backtext]
+
+ This document introduces you in the world of the graphic programming language
+ \MetaPost. Not only the language itself is covered in detail, but also the way to
+ interface with the typographic language \TeX. We also present the collection of
+ \MetaPost\ extensions that come with the \ConTeXt\ typesetting system. This
+ collection goes under the name \MetaFun.
+
+ \blank
+
+ All aspects of the \MetaPost\ language are covered. The first chapters focus on
+ the language itself, later chapters cover aspects like color, graphic
+ inclusions, adding labels, and stepwise constructing graphics. We finish with a
+ graphical overview of commands.
+
+\stopbuffer
+
+\startbuffer[backbanner]
+
+ \WidthSpanningText
+ {PRAGMA Advanced Document Engineering, Hasselt NL, \currentdate[year]}
+ {\hsize}
+ {RegularBold}
+
+\stopbuffer
+
+\stopenvironment
diff --git a/doc/context/sources/general/manuals/metafun/metafun-examples.tex b/doc/context/sources/general/manuals/metafun/metafun-examples.tex
new file mode 100644
index 000000000..4e5e0eed3
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-examples.tex
@@ -0,0 +1,3269 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-examples
+
+\environment metafun-environment
+
+\startchapter[title={A few applications}]
+
+\startintro
+
+For those who need to be inspired, we will demonstrate how \METAPOST\ can be used
+to enhance your document with simple graphics. In these examples we will try to
+be not too clever, simply because we lack the experience to be that clever. The
+real tricks can be found in the files that come with \METAPOST.
+
+\stopintro
+
+\startsection[reference={sec:coils,sec:springs},title={Simple drawings}]
+
+In the words of John Hobby, the creator of \METAPOST, \quotation {\METAPOST\ is
+particularly well||suited for generating figures for technical documents where
+some aspects of a picture may be controlled by mathematical or geometrical
+constraints that are best expressed symbolically. In other words, \METAPOST\ is
+not meant to take the place of a freehand drawing tool or even an interactive
+graphics editor}.
+
+An example of such a picture is the following one, which is dedicated to David
+Arnold, who asked me once how to draw a spring. So, imagine that we want to draw
+a schematic view of a system of four springs.
+
+\startbuffer[a]
+def spring (expr a, b, w, h, n) =
+ ( ( (0,0) -- (0,h) --
+ for i=1 upto n-1: (if odd(i) : - fi w/2,i+h) -- endfor
+ (0,n+h) -- (0,n+2h) )
+ yscaled ((xpart (b-a) ++ ypart (b-a))/(n+2h))
+ rotatedaround(origin,-90+angle(b-a))
+ shifted a )
+enddef ;
+\stopbuffer
+
+\startbuffer[b]
+vardef spring (expr a, b, w, h, n) =
+ pair vec ; path pat ; numeric len ; numeric ang ;
+ vec := (b-a) ;
+ pat := for i=1 upto n-1: (if odd(i):-fi w/2,i)--endfor (0,n) ;
+ pat := (0,0)--(0,h)-- pat shifted (0,h)--(0,n+h)--(0,n+2h) ;
+ len := (xpart vec ++ ypart vec)/(n+2h) ;
+ ang := -90+angle(vec) ;
+ ( pat yscaled len rotatedaround(origin,ang) shifted a )
+enddef ;
+\stopbuffer
+
+\startbuffer[c]
+path p ; p :=
+ (0,0)--spring((.5cm,0),(2.5cm,0),.5cm,0,10)--(3cm,0) ;
+
+draw p withpen pencircle scaled 2pt ;
+draw p withpen pencircle scaled 1pt withcolor .8white;
+\stopbuffer
+
+\startbuffer[d]
+z1 = (+2cm,0) ; z2 = (0,+2cm) ;
+z3 = (-2cm,0) ; z4 = (0,-2cm) ;
+
+pickup pencircle scaled 1.5pt ;
+
+drawoptions (withcolor .625red) ;
+
+draw spring (z1, z2, .75cm, 2, 10) ; draw z1 -- 1.5 z1 ;
+draw spring (z2, z3, .75cm, 2, 9) ; draw z2 -- 1.1 z2 ;
+draw spring (z3, z4, .75cm, 2, 8) ; draw z3 -- 1.5 z3 ;
+draw spring (z4, z1, .75cm, 2, 7) ; draw z4 -- 1.1 z4 ;
+\stopbuffer
+
+\startbuffer[e]
+drawarrow
+ (0,0)--spring((.5cm,0),(2.5cm,0),.5cm,0,10)--(3cm,0)
+ withpen pencircle scaled 2pt withcolor .625red ;
+\stopbuffer
+
+\startbuffer[f]
+numeric u ; u := 1mm ; pickup pencircle scaled (u/2) ;
+drawoptions (withcolor .625red) ;
+draw (0,0)--spring((5u,0),(25u,0),5u,0,10)--(30u,0) ;
+drawoptions (dashed evenly withcolor .5white) ;
+draw (0,0)--spring((5u,0),(35u,0),(25/35)*5u,0,10)--(40u,0) ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,d]
+\stoplinecorrection
+
+A rather natural way to define such a system is:
+
+\typebuffer[d]
+
+Here, the macro \type {spring} takes 5~arguments: two points, the width of the
+winding, the length of the connecting pieces, and the number of elements (half
+windings). The definition of \type {spring} is less complicated than readable.
+
+\typebuffer[a]
+
+First we build a path starting in the origin, going left or right depending on
+the counter being an odd number.
+
+\starttyping
+pat := (0,0) ;
+for i=1 upto n-1:
+ if odd(i) :
+ pat := pat -- (-w/2,i) ;
+ else :
+ pat := pat -- (+w/2,i) ;
+ fi ;
+endfor ;
+pat := pat -- (0,n) ;
+\stoptyping
+
+Once you are accustomed to the way \METAPOST\ interprets (specialists may say
+expand) the source code, you will start using \type {if} and \type {for}
+statements in assignments. The previous code can be converted in a one liner,
+using the pattern:
+
+\starttyping
+pat := for i=1 upto n-1: (x,y)-- endfor (0,n) ;
+\stoptyping
+
+The loop splits out a series of \type {(x,y)--} but the last point is added
+outside the loop. Otherwise \type {pat} would have ended with a dangling \type
+{--}. Of course we need to replace \type {(x,y)} by something meaningful, so we
+get:
+
+\starttyping
+pat := for i=1 upto n-1: (if odd(i):-fi w/2,i)--endfor (0,n) ;
+\stoptyping
+
+We scale this path to the length needed. The expression $b-a$ calculates a
+vector, starting at $a$ and ending at $b$. In \METAPOST, the expression \type
+{a++b} is identical to $\sqrt{a^2+b^2}$. Thus, the expression \typ {xpart (b-a)
+++ ypart (b-a)} calculates the length of the vector $b-a$. Because the unscaled
+spring has length $n+2h$, scaling by the expression \typ {((xpart (b-a) ++ ypart
+(b-a)) / (n+2h))} gives the spring the same length as the vector $b-a$.
+
+Because we have drawn our spring in the vertical position, we first rotate it 90
+degrees clockwise to a horizontal position, and then rotate it through an angle
+equal to the angle in which the vector $b-a$ is pointing. After that, we shift it
+to the first point. The main complications are that we also want to draw
+connecting lines at the beginning and end, as well as support springs that
+connect arbitrary points. Since no check is done on the parameters, you should be
+careful in using this macro.
+
+When we want to improve the readability, we have to use intermediate variables.
+Since the macro is expected to return a path, we must make sure that the content
+matches this expectation.
+
+\typebuffer[b]
+
+If you use \type {vardef}, then the last statement is the return value. Here,
+when \typ {p := spring (z1, z2, .75cm, 2, 10)} is being parsed, the macro is
+expanded, the variables are kept invisible for the assignment, and the path at
+the end is considered to be the return value. In a \type {def} the whole body of
+the macro is \quote {pasted} in the text, while in a \type {vardef} only the last
+line is visible. We will demonstrate this with a simple example.
+
+\starttyping
+def one = (n,n) ; n := n+1 ; enddef ;
+def two = n := n + 1 ; (n,n) enddef ;
+\stoptyping
+
+Now, when we say:
+
+\starttyping
+pair a, b ; numeric n ; n= 10 ; a := one ; b := two ;
+\stoptyping
+
+we definitely get an error message. This is because, when macro \type {two} is
+expanded, \METAPOST\ sees something:
+
+\starttyping
+b := n := n + 1 ;
+\stoptyping
+
+By changing the second definition in
+
+\starttyping
+vardef two = n := n + 1 ; (n,n) enddef ;
+\stoptyping
+
+the increment is expanded out of sight for \type {b :=} and the pair \type
+{(n,n)} is returned.
+
+We can draw a slightly better looking spring by drawing twice with a different
+pen. The following commands use the spring macro implemented by the \type
+{vardef}.
+
+\typebuffer[c]
+
+This time we get:
+
+\startlinecorrection[blank]
+\processMPbuffer[a,c]
+\stoplinecorrection
+
+Since the \type {spring} macro returns a path, you can do whatever is possible
+with a path, like drawing an arrow:
+
+\startlinecorrection[blank]
+\processMPbuffer[a,e]
+\stoplinecorrection
+
+Or even (watch how we use the neutral unit \type {u} to specify the dimensions):
+
+\startlinecorrection[blank]
+\processMPbuffer[a,f]
+\stoplinecorrection
+
+This was keyed in as:
+
+\typebuffer[e]
+
+and:
+
+\typebuffer[f]
+
+\stopsection
+
+\startsection[reference=sec:free labels,title={Free labels}]
+
+\index {labels}
+
+The \METAPOST\ label macro enables you to position text at certain points. This
+macro is kind of special, because it also enables you to influence the
+positioning. For that purpose it uses a special kind of syntax which we will not
+discuss here in detail.
+
+\startbuffer[a]
+pickup pencircle scaled 1mm ;
+path p ; p := fullcircle scaled 3cm ;
+draw p withcolor .625yellow ;
+dotlabel.rt ("right" , point 0 of p) ;
+dotlabel.urt ("upper right" , point 1 of p) ;
+dotlabel.top ("top" , point 2 of p) ;
+dotlabel.ulft ("upper left" , point 3 of p) ;
+dotlabel.lft ("left" , point 4 of p) ;
+dotlabel.llft ("lower left" , point 5 of p) ;
+dotlabel.bot ("bottom" , point 6 of p) ;
+dotlabel.lrt ("lower right" , point 7 of p) ;
+\stopbuffer
+
+\typebuffer[a]
+
+The \type {label} command just typesets a text, while \type {dotlabel} also draws
+a dot at the position of the label. The \type {thelabel} (not shown here) command
+returns a picture.
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+There is a numeric constant \type {labeloffset} that can be set to influence the
+distance between the point given and the content of the label. When we set the
+offset to zero, we get the following output.
+
+\startbuffer[x]
+interim labeloffset := 0pt ; % local assignment
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a]
+\stoplinecorrection
+
+This kind of positioning works well as long as we know where we want the label to
+be placed. However, when we place labels automatically, for instance in a macro,
+we have to apply a few clever tricks. There are for sure many ways to accomplish
+this goal, but here we will follow the mathless method.
+
+\startbuffer[a]
+pickup pencircle scaled 1mm ;
+path p ; p := fullcircle scaled 3cm ;
+draw p withcolor .625yellow ;
+vardef do (expr str) =
+ save currentpicture ; picture currentpicture ;
+ currentpicture := thelabel(str,origin) ;
+ draw boundingbox currentpicture withpen pencircle scaled .5pt ;
+ currentpicture
+enddef ;
+\stopbuffer
+
+\startbuffer[b]
+dotlabel.rt (do("right") , point 0 of p) ;
+dotlabel.urt (do("upper right") , point 1 of p) ;
+dotlabel.top (do("top") , point 2 of p) ;
+dotlabel.ulft (do("upper left") , point 3 of p) ;
+dotlabel.lft (do("left") , point 4 of p) ;
+dotlabel.llft (do("lower left") , point 5 of p) ;
+dotlabel.bot (do("bottom") , point 6 of p) ;
+dotlabel.lrt (do("lower right") , point 7 of p) ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+The previous graphic visualizes the bounding box of the labels. This bounding box
+is rather tight and therefore the placement of labels will always be suboptimal.
+Compare the alignment of the left- and rightmost labels. The \type {btex}||\type
+{etex} method is better, since then we can add struts, like:
+
+\starttyping
+btex \strut right etex
+\stoptyping
+
+to force labels with uniform depths and heights. The next graphic demonstrates
+that this looks better indeed. Also, as \TEX\ does the typesetting we get the
+current text font instead of the label font and the content will be properly
+typeset; for instance kerning will be applied when applicable. Spending some time
+on such details pays back in better graphics.
+
+\startbuffer[b]
+dotlabel.rt (do(btex \strut right etex) , point 0 of p) ;
+dotlabel.urt (do(btex \strut upper right etex) , point 1 of p) ;
+dotlabel.top (do(btex \strut top etex) , point 2 of p) ;
+dotlabel.ulft (do(btex \strut upper left etex) , point 3 of p) ;
+dotlabel.lft (do(btex \strut left etex) , point 4 of p) ;
+dotlabel.llft (do(btex \strut lower left etex) , point 5 of p) ;
+dotlabel.bot (do(btex \strut bottom etex) , point 6 of p) ;
+dotlabel.lrt (do(btex \strut lower right etex) , point 7 of p) ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+Now, what happens when we want to place labels in other positions? In the worst
+case, given that we place the labels manually, we end up in vague arguments in
+favour for one or the other placement.
+
+\startbuffer[y]
+p := p rotatedaround(center p, 22.5) ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,y,b]
+\stoplinecorrection
+
+Although any automatic mechanism will be sub||optimal, we can give it a try to
+write a macro that deals with arbitrary locations. This macro will accept three
+arguments and return a picture.
+
+\starttyping
+thefreelabel("some string or picture",a position,the origin)
+\stoptyping
+
+Our testcase is just a simple \type {for} loop that places a series of labels.
+The \type {freedotlabel} macro is derived from \type {thefreelabel}.
+
+\startbuffer[c]
+pickup pencircle scaled 1mm ;
+path p ; p := fullcircle scaled 3cm ;
+draw p withcolor .625yellow ;
+for i=0 step .5 until 7.5 :
+ freedotlabel ("text" , point i of p, center p) ;
+endfor ;
+\stopbuffer
+
+\typebuffer[c]
+
+As a first step we will simply place the labels without any correction. We also
+visualize the bounding box.
+
+\startbuffer[b]
+vardef freedotlabel (expr str, loc, ori) =
+ drawdot loc ; draw thefreelabel(str,loc,ori) ;
+enddef ;
+
+vardef freelabel (expr str, loc, ori) =
+ draw thefreelabel(str,loc,ori) ;
+enddef ;
+\stopbuffer
+
+\startbuffer[a]
+vardef thefreelabel (expr str, loc, ori) =
+ save s ; picture s ; s := thelabel(str,loc) ;
+ draw boundingbox s withpen pencircle scaled .5pt ;
+ s
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+To make our lives more easy, we also define a macro that draws the dot as well as
+a macro that draws the label.
+
+\typebuffer[b]
+
+Now we get:
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b,c]
+\stoplinecorrection
+
+The original label macros permits us to align the label at positions, 4~corners
+and 4~points halfway the sides. It happens that circles are also composed of
+8~points. Because in most cases the label is to be positioned in the direction of
+the center of a curve and the point at hand, it makes sense to take circles as
+the starting points for positioning the labels.
+
+To help us in positioning, we define a special square path, \type {freesquare}.
+This path is constructed out of 8~points that match the positions that are used
+to align labels.
+
+\startbuffer[d]
+path freesquare ;
+
+freesquare := ((-1,0)--(-1,-1)--(0,-1)--(+1,-1)--
+ (+1,0)--(+1,+1)--(0,+1)--(-1,+1)--cycle) scaled .5 ;
+\stopbuffer
+
+\typebuffer[d]
+
+We now show this free path together with a circle, using the following
+definitions:
+
+\startbuffer[e]
+drawpath fullcircle scaled 3cm ;
+drawpoints fullcircle scaled 3cm ;
+drawpointlabels fullcircle scaled 3cm ;
+currentpicture := currentpicture shifted (5cm,0) ;
+drawpath freesquare scaled 3cm ;
+drawpoints freesquare scaled 3cm ;
+drawpointlabels freesquare scaled 3cm ;
+\stopbuffer
+
+\typebuffer[e]
+
+We use two drawing macros that are part of the suite of visual debugging macros.
+
+\startlinecorrection[blank]
+\processMPbuffer[x,d,e]
+\stoplinecorrection
+
+As you can see, point~1 is the corner point that suits best for alignment when a
+label is put at point~1 of the circle. We will now rewrite \type {thefreelabel}
+in such a way that the appropriate point of the associated \type {freesquare} is
+found.
+
+\startbuffer[a]
+vardef thefreelabel (expr str, loc, ori) =
+ save s, p, q, l ; picture s ; path p, q ; pair l ;
+ s := thelabel(str,loc) ;
+ p := fullcircle scaled (2*length(loc-ori)) shifted ori ;
+ q := freesquare xyscaled (urcorner s - llcorner s) ;
+ l := point (xpart (p intersectiontimes (ori--loc))) of q ;
+ draw q shifted loc withpen pencircle scaled .5pt ;
+ draw l shifted loc withcolor .625yellow ;
+ draw loc withcolor .625red ;
+ s
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+The macro xyscaled is part of \METAFUN\ and scales in two directions at once. The
+\METAPOST\ primitive \type {intersectiontimes} returns a pair of time values of
+the point where two paths intersect. The first part of the pair concerns the
+first path.
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b,c]
+\stoplinecorrection
+
+We are now a small step from the exact placement. If we change the last line of
+the macro into:
+
+\starttyping
+(s shifted -l)
+\stoptyping
+
+we get the displacement we want. Although the final look and feel is also
+determined by the text itself, the average result is quite acceptable.
+
+\startbuffer[a]
+vardef thefreelabel (expr str, loc, ori) =
+ save s, p, q, l ; picture s ; path p, q ; pair l ;
+ s := thelabel(str,loc) ;
+ p := fullcircle scaled (2*length(loc-ori)) shifted ori ;
+ q := freesquare xyscaled (urcorner s - llcorner s) ;
+ l := point (xpart (p intersectiontimes (ori--loc))) of q ;
+ draw q shifted loc withpen pencircle scaled .5pt ;
+ draw l shifted loc withcolor .625yellow ;
+ draw loc withcolor .625red ;
+ (s shifted -l)
+enddef ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b,c]
+\stoplinecorrection
+
+Because we also want to pass pictures, and add a bit of offset too, the final
+implementation is slightly more complicated. The picture is handled with an
+additional condition, and the offset with the \METAFUN\ macro \type {enlarged}.
+
+\startbuffer[a]
+newinternal freelabeloffset ; freelabeloffset := 3pt ;
+
+vardef thefreelabel (expr str, loc, ori) =
+ save s, p, q, l ; picture s ; path p, q ; pair l ;
+ interim labeloffset := freelabeloffset ;
+ s := if string str : thelabel(str,loc)
+ else : str shifted -center str shifted loc fi ;
+ setbounds s to boundingbox s enlarged freelabeloffset ;
+ p := fullcircle scaled (2*length(loc-ori)) shifted ori ;
+ q := freesquare xyscaled (urcorner s - llcorner s) ;
+ l := point (xpart (p intersectiontimes (ori--loc))) of q ;
+ setbounds s to boundingbox s enlarged -freelabeloffset ;
+ (s shifted -l)
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+Watch how we temporarily enlarge the bounding box of the typeset label text. We
+will now test this macro on a slightly rotated circle, using labels typeset by
+\TEX. The \type {reverse} is there purely for cosmetic reasons, to suit the label
+texts.
+
+\startbuffer[b]
+pickup pencircle scaled 1mm ;
+path p ; p := reverse fullcircle rotated -25 scaled 3cm ;
+draw p withcolor .625yellow ; pair cp ; cp := center p ;
+freedotlabel (btex \strut We can etex, point 0 of p, cp) ;
+freedotlabel (btex \strut go on etex, point 1 of p, cp) ;
+freedotlabel (btex \strut and on etex, point 2 of p, cp) ;
+freedotlabel (btex \strut in etex, point 3 of p, cp) ;
+freedotlabel (btex \strut defining etex, point 4 of p, cp) ;
+freedotlabel (btex \strut funny etex, point 5 of p, cp) ;
+freedotlabel (btex \strut macros. etex, point 6 of p, cp) ;
+freedotlabel (btex \strut Can't we? etex, point 7 of p, cp) ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+\typebuffer[b]
+
+Unfortunately we can run into problems due to rounding errors. Therefore we use a
+less readable but more safe expression for calculating the intersection points.
+Instead of using point \type {loc} as endpoint we use \type {loc} shifted over a
+very small distance into the direction \type {loc} from \type{ori}. In the
+assignment to~\type {l} we replace \type {loc} by:
+
+\starttyping
+ ( (1+eps) * arclength(ori--loc) * unitvector(loc-ori) )
+\stoptyping
+
+\stopsection
+
+\startsection[title={Marking angles}]
+
+\index{angles}
+
+A convenient \METAPOST\ macro is \type {unitvector}. When we draw a line segment
+from the origin to the point returned by this macro, the segment has a length of
+1~base point. This macro has a wide range of applications, but some basic
+knowledge of vector algebra is handy. The following lines of \METAPOST\ code
+demonstrate the basics behind unitvectors.
+
+\startbuffer
+pair uv ; pickup pencircle scaled 1mm ; autoarrows := true ;
+draw fullcircle scaled 2cm withcolor .625red ;
+for i=(10,35), (-40,-20), (85,-15) :
+ draw origin--i dashed evenly withcolor .625white ;
+ drawarrow origin--unitvector(i) scaled 1cm withcolor .625yellow ;
+endfor ;
+draw origin withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+The circle has a radius of 1cm, and the three line segments are drawn from the
+origin in the direction of the points that are passed as arguments. Because the
+vector has length of~1, we scale it to the radius to let it touch the circle. By
+setting \type {autoarrows} we make sure that the arrowheads are scaled
+proportionally to the linewidth of 1~mm.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+An application of this macro is drawing the angle between two lines. In the
+\METAPOST\ manual you can find two macros for drawing angles: \type {mark_angle}
+and \type {mark_rt_angle}. You may want to take a look at their definitions
+before we start developing our own alternatives.
+
+\startbuffer[x]
+pickup pencircle scaled 1mm ; autoarrows := true ;
+drawoptions(withcolor .625white) ;
+\stopbuffer
+
+\startbuffer[a]
+def anglebetween (expr a, b) =
+ (unitvector(a){a rotated 90} .. unitvector(b))
+enddef ;
+\stopbuffer
+
+\startbuffer[b]
+pair a, b ; a := (2cm,-1cm) ; b := (3cm,1cm) ;
+drawarrow origin--a ; drawarrow origin--b ;
+drawarrow anglebetween(a,b) scaled 1cm withcolor .625red ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+The previous graphic demonstrates what we want to accomplish: a circular curve
+indicating the angle between two straight lines. The lines and curve are drawn
+with the code:
+
+\typebuffer[b]
+
+where \type {anglebetween} is defined as:
+
+\typebuffer[a]
+
+Both unitvectors return just a point on the line positioned 1~unit (later scaled
+to 1cm) from the origin. We connect these points by a curve that starts in the
+direction at the first point. If we omit the \type {a rotated 90} direction
+specifier, we get:
+
+\startbuffer[a]
+def anglebetween (expr a, b) =
+ (unitvector(a) .. unitvector(b))
+enddef ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+These definitions of \type {anglebetween} are far from perfect. If we don't start
+in the origin, we get the curve in the wrong place and when we swap both points,
+we get the wrong curve.
+
+\startbuffer[a]
+def anglebetween (expr endofa, endofb, common, length) =
+ (unitvector (endofa-common){(endofa-common) rotated 90} ..
+ unitvector (endofb-common)) scaled length shifted common
+enddef ;
+\stopbuffer
+
+\startbuffer[b]
+pair a, b, c ; a := (2cm,-1cm) ; b := (3cm,1cm) ; c := (-1cm,.5cm) ;
+drawarrow c--a ; drawarrow c--b ;
+drawarrow anglebetween(a,b,c,1cm) withcolor .625red ;
+\stopbuffer
+
+The solution for the displacement is given in the \METAPOST\ manual and looks
+like this (we package the macro a bit different):
+
+\typebuffer[a]
+
+As you can see, we compensate for the origin of both vectors. This macro is
+called with a few more parameters. We need to pass the length, since we want to
+add the shift to the macro and the shift takes place after the scaling.
+
+\typebuffer[b]
+
+That the results are indeed correct, is demonstrated by the output of following
+example:
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+However, when we swap the points, we get:
+
+\startbuffer[a]
+def anglebetween (expr endofb, endofa, common, length) =
+ (unitvector (endofa-common){(endofa-common) rotated 90} ..
+ unitvector (endofb-common)) scaled length shifted common
+enddef ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+This means that instead of rotating over $90$ degrees, we have to rotate over
+$-90$ or $270$ degrees. That way the arrow will also point in the other
+direction. There are undoubtedly more ways to determine the direction, but the
+following method also demonstrates the use of \type {turningnumber}, which
+reports the direction of a path. For this purpose we compose a dummy cyclic path.
+
+\startbuffer[a]
+vardef anglebetween (expr endofa, endofb, common, length) =
+ save tn ; tn := turningnumber(common--endofa--endofb--cycle) ;
+show tn ;
+ (unitvector(endofa-common){(endofa-common) rotated (tn*90)} ..
+ unitvector(endofb-common)) scaled length shifted common
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+Because we use an intermediate variable, just to keep things readable, we have to
+use \type {vardef} to hide the assignment for the outside world. We demonstrate
+this macro using the following code:
+
+\startbuffer[b]
+pair a, b, c ; a := (2cm,-1cm) ; b := (3cm,1cm) ; c := (-1cm,.5cm) ;
+drawarrow c--a ; drawarrow c--b ;
+drawarrow anglebetween(a,b,c,0.75cm) withcolor .625red ;
+drawarrow anglebetween(b,a,c,1.50cm) withcolor .625red ;
+\stopbuffer
+
+\typebuffer[b]
+
+Watch how both arrows point in the direction of the line that is determined by
+the second point.
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+We now have the framework of an angle drawing macro ready and can start working
+placing the label.
+
+\startbuffer[a]
+vardef anglebetween (expr endofa, endofb, common, length, str) =
+ save curve, where ; path curve ; numeric where ;
+ where := turningnumber (common--endofa--endofb--cycle) ;
+ curve := (unitvector(endofa-common){(endofa-common) rotated (where*90)}
+ .. unitvector(endofb-common)) scaled length shifted common ;
+ draw thefreelabel(str,point .5 of curve,common) withcolor black ;
+ curve
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+The macro \type {thefreelabel} is part of \METAFUN\ and is explained in detail in
+\in {section} [sec:free labels]. This macro tries to place the label as good as
+possible without user interference.
+
+\startbuffer[b]
+pair a ; a := (2cm,-1cm) ; drawarrow origin--a ;
+pair b ; b := (3cm, 1cm) ; drawarrow origin--b ;
+drawarrow
+ anglebetween(a,b,origin,1cm,btex $\alpha$ etex)
+ withcolor .625red ;
+\stopbuffer
+
+\typebuffer[b]
+
+Instead of a picture we may also pass a string, but using \TEX\ by means of \type
+{btex}||\type {etex} often leads to better results.
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+Because in most cases we want the length to be consistent between figures and
+because passing two paths is more convenient than passing three points, the final
+definition looks slightly different.
+
+\startbuffer[a]
+numeric anglelength ; anglelength := 20pt ;
+
+vardef anglebetween (expr a, b, str) = % path path string
+ save endofa, endofb, common, curve, where ;
+ pair endofa, endofb, common ; path curve ; numeric where ;
+ endofa := point length(a) of a ;
+ endofb := point length(b) of b ;
+ if round point 0 of a = round point 0 of b :
+ common := point 0 of a ;
+ else :
+ common := a intersectionpoint b ;
+ fi ;
+ where := turningnumber (common--endofa--endofb--cycle) ;
+ curve := (unitvector (endofa-common){(endofa-common) rotated (where*90)} ..
+ unitvector (endofb-common)) scaled anglelength shifted common ;
+ draw thefreelabel(str,point .5 of curve,common) withcolor black ;
+ curve
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+This macro has a few more \type {if}'s than its predecessor. First we test if the
+label is a string, and if so, we calculate the picture ourselves, otherwise we
+leave this to the user.
+
+\startbuffer[b]
+path a, b, c, d, e, f ;
+a := origin--( 2cm, 1cm) ; b := origin--( 1cm, 2cm) ;
+c := origin--(-2cm, 2cm) ; d := origin--(-2cm,-1cm) ;
+e := origin--(-1cm,-2cm) ; f := origin--( 1cm,-2cm) ;
+for i=a, b, c, d, e, f : drawarrow i ; endfor ;
+anglelength := 1.0cm ; drawoptions(withcolor .625red) ;
+drawarrow anglebetween(a,b,btex $\alpha $ etex) ;
+drawarrow anglebetween(c,d,btex $\gamma $ etex) ;
+drawarrow anglebetween(e,f,btex $\epsilon$ etex) ;
+anglelength := 1.5cm ; drawoptions(withcolor .625yellow) ;
+drawdblarrow anglebetween(b,c,btex $\beta $ etex) ;
+drawarrow reverse anglebetween(d,e,btex $\delta $ etex) ;
+drawarrow anglebetween(a,f,btex $\zeta $ etex) ;
+\stopbuffer
+
+\typebuffer[b]
+
+Because \type {anglebetween} returns a path, you can apply transformations to it,
+like reversing. Close reading of the previous code learns that the macro handles
+both directions.
+
+\startlinecorrection[blank]
+\processMPbuffer[x,a,b]
+\stoplinecorrection
+
+Multiples of 90 degrees are often identified by a rectangular symbol. We will now
+extend the previously defined macro in such a way that more types can be drawn.
+
+\startbuffer[a]
+numeric anglelength ; anglelength := 20pt ;
+numeric anglemethod ; anglemethod := 1 ;
+
+vardef anglebetween (expr a, b, str) = % path path string
+ save pointa, pointb, common, middle, offset ;
+ pair pointa, pointb, common, middle, offset ;
+ save curve ; path curve ;
+ save where ; numeric where ;
+ if round point 0 of a = round point 0 of b :
+ common := point 0 of a ;
+ else :
+ common := a intersectionpoint b ;
+ fi ;
+ pointa := point anglelength on a ;
+ pointb := point anglelength on b ;
+ where := turningnumber (common--pointa--pointb--cycle) ;
+ middle := ((common--pointa) rotatedaround (pointa,-where*90))
+ intersectionpoint
+ ((common--pointb) rotatedaround (pointb, where*90)) ;
+ if anglemethod = 1 :
+ curve := pointa{unitvector(middle-pointa)}.. pointb;
+ middle := point .5 along curve ;
+ elseif anglemethod = 2 :
+ middle := common rotatedaround(.5[pointa,pointb],180) ;
+ curve := pointa--middle--pointb ;
+ elseif anglemethod = 3 :
+ curve := pointa--middle--pointb ;
+ elseif anglemethod = 4 :
+ curve := pointa..controls middle..pointb ;
+ middle := point .5 along curve ;
+ fi ;
+ draw thefreelabel(str, middle, common) withcolor black ;
+ curve
+enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startbuffer[p]
+anglemethod := 1 ;
+\stopbuffer
+
+\startbuffer[q]
+anglemethod := 2 ;
+\stopbuffer
+
+\startbuffer[r]
+anglemethod := 3 ;
+\stopbuffer
+
+\startbuffer
+\startcombination[3*1]
+ {\processMPbuffer[x,a,p,b]} {method 1}
+ {\processMPbuffer[x,a,q,b]} {method 2}
+ {\processMPbuffer[x,a,r,b]} {method 3}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:three methods]
+ {Three ways of marking angles.}
+ {\getbuffer}
+
+\in {Figure} [fig:three methods] shows the first three alternative methods
+implemented here. Instead of using \typ {unitvectors}, we now calculate the
+points using the \typ {arctime} and \typ {arclength} primitives. Instead of
+complicated expressions, we use the \METAFUN\ operators \type {along} and \type
+{on}. The following expressions are equivalent.
+
+\starttyping
+pointa := point anglelength on a ;
+middle := point .5 along curve ;
+
+pointa := point (arctime anglelength of a) of a ;
+middle := arctime (.5(arclength curve)) of curve) of curve ;
+\stoptyping
+
+The third method can be implemented in different, more math intensive ways, but
+the current implementation suits rather well and is understood by the author.
+
+\stopsection
+
+\startsection[reference=sec:color circles,title={Color circles}]
+
+\index{color}
+
+In \in {chapter} [sec:embedding] we showed a few color circles. Drawing such a
+graphic can be done in several ways, and here we will show a few methods. First
+we will demonstrate how you can apply \type {cutafter} and \type {cutbefore},
+next we will show how the \METAPOST\ macro \type {buildpath} can be used, and
+finally we will present a clean solution using \type {subpath}. We will assume
+that the circle is called with the macro:
+
+\starttyping
+colorcircle (4cm, red, green, blue) ;
+\stoptyping
+
+\startbuffer[circle]
+vardef colorcircle (expr size, red, green, blue) =
+ save r, g, b, rr, gg, bb, cc, mm, yy ;
+ save b_r, b_g, g_r, g_b ;
+ save radius ;
+
+ path r, g, b, rr, bb, gg, cc, mm, yy ;
+ pair b_r, b_g, g_r, g_b ;
+
+ numeric radius ; radius := 3cm ;
+
+ pickup pencircle scaled (radius/20) ;
+
+ r := g := b := fullcircle scaled radius shifted (0,radius/4);
+
+ r := r rotatedaround(origin, 15) ; % drawarrow r withcolor red ;
+ g := g rotatedaround(origin,135) ; % drawarrow g withcolor green ;
+ b := b rotatedaround(origin,255) ; % drawarrow b withcolor blue ;
+
+ b_r := b intersectionpoint r ; % draw b_r ;
+ b_g := b intersectionpoint g ; % draw b_g ;
+ g_r := reverse g intersectionpoint r ; % draw g_r ;
+ g_b := reverse g intersectionpoint b ; % draw g_b ;
+
+ bb := b cutafter b_r ; bb := bb cutbefore b_g ; % drawarrow bb ;
+ gg := g cutbefore b_g ; gg := gg cutafter g_r ; % drawarrow gg ;
+ rr := r cutbefore g_r & r cutafter b_r ; % drawarrow rr ;
+
+ cc := b cutbefore b_r ; cc := cc cutafter g_b ; % drawarrow br ;
+ yy := g cutbefore g_r ; yy := yy cutafter g_b ; % drawarrow rg ;
+ mm := r cutbefore g_r & r cutafter b_r ; % drawarrow gb ;
+
+ bb := gg -- rr -- reverse bb -- cycle ;
+ gg := bb rotatedaround(origin,120) ;
+ rr := bb rotatedaround(origin,240) ;
+
+ cc := mm -- cc -- reverse yy -- cycle ;
+ yy := cc rotatedaround(origin,120) ;
+ mm := cc rotatedaround(origin,240) ;
+
+ fill fullcircle scaled radius withcolor white ;
+
+ fill rr withcolor red ; fill cc withcolor white-red ;
+ fill gg withcolor green ; fill mm withcolor white-green ;
+ fill bb withcolor blue ; fill yy withcolor white-blue ;
+
+ for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ;
+
+ currentpicture := currentpicture xsized size ;
+enddef ;
+\stopbuffer
+
+We need to calculate seven paths. The first implementation does all the handywork
+itself and thereby is rather long, complicated and unreadable. It does not really
+use the strength of \METAPOST\ yet.
+
+\typebuffer[circle]
+
+In determining the right intersection points, you need to know where the path
+starts and in what direction it moves. In case of doubt, drawing the path as an
+arrow helps. If you want to see the small paths used, you need to comment the
+lines with the \type {fill}'s and uncomment the lines with \type {draw}'s. Due to
+the symmetry and the fact that we keep the figure centered around the origin, we
+only need to calculate two paths since we can rotate them.
+
+There are for sure more (efficient) ways to draw such a figure, but this one
+demonstrates a few new tricks, like grouping. We use grouping here because we
+want to use \type {mm} to indicate the magenta path, and \type {mm} normally
+means millimeter. Within a group, you can save variables. These get their old
+values when the group is left.
+
+With \type {for} we process multiple paths after each other. In this case it
+hardly saves tokens, but it looks more clever.
+
+One of the more efficient methods is using the \type {buildcycle} macro. This
+macro takes two or more paths and calculates the combined path. Although this is
+a rather clever macro, you should be prepared to help it a bit when paths have
+multiple intersection points. Again, we could follow a more secure mathematical
+method, but the next one took only a few minutes of trial and error. To save some
+memory, we redefine the \type {colors} graphic.
+
+\startbuffer[demo]
+colorcircle(4cm, red, green, blue) ;
+\stopbuffer
+
+When we call this macro as:
+
+\typebuffer[demo]
+
+we get:
+
+\startlinecorrection[blank]
+\processMPbuffer[circle,demo]
+\stoplinecorrection
+
+Of course this macro is only used for demonstration purposes and has no real use.
+
+\startbuffer[circle]
+vardef colorcircle (expr size, red, green, blue) =
+ save r, g, b, rr, gg, bb, cc, mm, yy ; save radius ;
+ path r, g, b, rr, bb, gg, cc, mm, yy ; numeric radius ;
+
+ radius := 5cm ; pickup pencircle scaled (radius/25) ;
+
+ r := g := b := fullcircle scaled radius shifted (0,radius/4) ;
+
+ r := r rotatedaround (origin, 15) ;
+ g := g rotatedaround (origin,135) ;
+ b := b rotatedaround (origin,255) ;
+
+ r := r rotatedaround(center r,-90) ;
+ g := g rotatedaround(center g, 90) ;
+
+ gg := buildcycle(buildcycle(reverse r,b),g) ;
+ cc := buildcycle(buildcycle(b,reverse g),r) ;
+
+ rr := gg rotatedaround(origin,120) ;
+ bb := gg rotatedaround(origin,240) ;
+
+ yy := cc rotatedaround(origin,120) ;
+ mm := cc rotatedaround(origin,240) ;
+
+ fill fullcircle scaled radius withcolor white ;
+
+ fill rr withcolor red ; fill cc withcolor white-red ;
+ fill gg withcolor green ; fill mm withcolor white-green ;
+ fill bb withcolor blue ; fill yy withcolor white-blue ;
+
+ for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ;
+
+ currentpicture := currentpicture xsized size ;
+enddef ;
+\stopbuffer
+
+\typebuffer [circle]
+
+Since we don't want to duplicate a graphic, this time we show the dark
+alternatives.
+
+\startbuffer[demo]
+colorcircle(4cm, .5red, .5green, .5blue) ;
+\stopbuffer
+
+\typebuffer[demo]
+
+This kind of unsafe path calculations are very sensitive to breaking. Changing
+the \type {radius/4} into something else demonstrates this but we will not
+challenge this macro that much. Therefore, the 50\% color circle shows up as:
+
+\startlinecorrection[blank]
+\processMPbuffer[circle,demo]
+\stoplinecorrection
+
+This command is part of \METAFUN\ and can be used to determine nice color
+combinations by also looking at their complementary colors.
+
+\startbuffer[demo]
+colorcircle (4cm, .7red, .5green, .3blue) ;
+\stopbuffer
+
+\typebuffer[demo]
+
+\startlinecorrection[blank]
+\processMPbuffer[circle,demo]
+\stoplinecorrection
+
+The next circle that we draw shows the three main colors used in this document.
+This circle is not that beautiful.
+
+\startbuffer[demo]
+colorcircle(4cm,.625red,.625yellow,.625white) ;
+\stopbuffer
+
+\typebuffer[demo]
+
+\startlinecorrection[blank]
+\processMPbuffer[circle,demo]
+\stoplinecorrection
+
+This definition can be cleaned up a bit by using \type {transform}, but the fuzzy
+\type {buildcycle}'s remain.
+
+\startbuffer[circle]
+vardef colorcircle (expr size, red, green, blue) =
+ save r, g, b, rr, gg, bb, cc, mm, yy ; save radius ;
+ path r, g, b, rr, bb, gg, cc, mm, yy ; numeric radius ;
+
+ radius := 5cm ; pickup pencircle scaled (radius/25) ;
+
+ transform t ; t := identity rotatedaround(origin,120) ;
+
+ r := fullcircle scaled radius
+ shifted (0,radius/4) rotatedaround(origin,15) ;
+
+ g := r transformed t ; b := g transformed t ;
+
+ r := r rotatedaround(center r,-90) ;
+ g := g rotatedaround(center g, 90) ;
+
+ gg := buildcycle(buildcycle(reverse r,b),g) ;
+ cc := buildcycle(buildcycle(b,reverse g),r) ;
+
+ rr := gg transformed t ; bb := rr transformed t ;
+ yy := cc transformed t ; mm := yy transformed t ;
+
+ fill fullcircle scaled radius withcolor white ;
+
+ fill rr withcolor red ; fill cc withcolor white-red ;
+ fill gg withcolor green ; fill mm withcolor white-green ;
+ fill bb withcolor blue ; fill yy withcolor white-blue ;
+
+ for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ;
+
+ currentpicture := currentpicture xsized size ;
+enddef ;
+\stopbuffer
+
+\typebuffer [circle]
+
+\startbuffer[demo]
+colorcircle(4cm,(.4,.6,.8),(.8,.4,.6),(.6,.8,.4));
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[circle,demo]
+\stoplinecorrection
+
+This rather nice circle is defined as:
+
+\typebuffer[demo]
+
+The final implementation, which is part of \METAFUN, is slightly more efficient.
+
+\startbuffer[circle]
+vardef colorcircle (expr size, red, green, blue) =
+ save r, g, b, c, m, y, w ; save radius ;
+ path r, g, b, c, m, y, w ; numeric radius ;
+
+ radius := 5cm ; pickup pencircle scaled (radius/25) ;
+
+ transform t ; t := identity rotatedaround(origin,120) ;
+
+ r := fullcircle rotated 90 scaled radius
+ shifted (0,radius/4) rotatedaround(origin,135) ;
+
+ b := r transformed t ; g := b transformed t ;
+
+ c := buildcycle(subpath(1,7) of g, subpath(1,7) of b) ;
+ y := c transformed t ; m := y transformed t ;
+
+ w := buildcycle(subpath(3,5) of r,
+ subpath(3,5) of g, subpath(3,5) of b) ;
+
+ pushcurrentpicture ;
+
+ fill r withcolor red ;
+ fill g withcolor green ;
+ fill b withcolor blue ;
+ fill c withcolor white-red ;
+ fill m withcolor white-green ;
+ fill y withcolor white-blue ;
+ fill w withcolor white ;
+
+ for i = r,g,b,c,m,y : draw i withcolor .5white ; endfor ;
+
+ currentpicture := currentpicture xsized size ;
+
+ popcurrentpicture ;
+enddef ;
+\stopbuffer
+
+\typebuffer [circle]
+
+Here, we first fill the primary circles, next we fill the secondary ones. These
+also cover the center, which is why finally we fill the center with white.
+
+\startbuffer[demo]
+colorcircle(4cm,(.2,.5,.8),(.8,.2,.5),(.5,.8,.2));
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[circle,demo]
+\stoplinecorrection
+
+The circle uses the following colors:
+
+\typebuffer[demo]
+
+The next graphic demonstrates how the subpaths look that build the shapes.
+
+\startbuffer[circle]
+vardef colorcircle (expr size, red, green, blue) =
+ save r, g, b, c, m, y, w ; save radius ;
+ path r, g, b, c, m, y, w ; numeric radius ;
+
+ radius := 5cm ; pickup pencircle scaled (radius/25) ;
+
+ transform t ; t := identity rotatedaround(origin,120) ;
+
+ r := fullcircle rotated 90 scaled radius
+ shifted (0,radius/4) rotatedaround(origin,135) ;
+
+ b := r transformed t ; g := b transformed t ;
+
+ c := buildcycle(subpath(1,7) of g,subpath(1,7) of b) ;
+ y := c transformed t ; m := y transformed t ;
+
+ w := buildcycle(subpath(3,5) of r,
+ subpath(3,5) of g, subpath(3,5) of b) ;
+
+ pushcurrentpicture ;
+
+ def do_it =
+ fill r withcolor red ;
+ fill g withcolor green ;
+ fill b withcolor blue ;
+ fill c withcolor white-red ;
+ fill m withcolor white-green ;
+ fill y withcolor white-blue ;
+ fill w withcolor white ;
+ for i = r,g,b,c,m,y : draw i withcolor .5white ; endfor ;
+ enddef ;
+
+ autoarrows := true ;
+
+ do_it ;
+ for i=r,g,b : drawarrow i withcolor black ; endfor ;
+ currentpicture := currentpicture shifted (-2radius,0) ;
+
+ do_it ;
+ for i=r,g,b : drawarrow subpath(1,7) of i withcolor black ; endfor ;
+ currentpicture := currentpicture shifted (-2radius,0) ;
+
+ do_it ;
+ for i=r,g,b : drawarrow subpath(3,5) of i withcolor black ; endfor ;
+ currentpicture := currentpicture shifted (+4radius,2radius) ;
+
+ drawarrow r withpen pencircle scaled (radius/10) withcolor red ;
+ drawarrow g withpen pencircle scaled (radius/20) withcolor green ;
+ drawarrow b withpen pencircle scaled (radius/40) withcolor blue ;
+ currentpicture := currentpicture shifted (-2radius,0) ;
+
+ drawarrow c withpen pencircle scaled (radius/10) withcolor white-red ;
+ drawarrow m withpen pencircle scaled (radius/20) withcolor white-green ;
+ drawarrow y withpen pencircle scaled (radius/40) withcolor white-blue ;
+ currentpicture := currentpicture shifted (-2radius,0) ;
+
+ drawarrow w withcolor black ;
+
+ currentpicture := currentpicture xsized 3size ;
+
+ popcurrentpicture ;
+enddef ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[circle,demo]
+\stoplinecorrection
+
+We did not mention what the push and pop commands are responsible for. Scaling
+the current picture is well defined as long as we deal with one graphic. However,
+if the current picture already has some content, this content is also scaled. The
+push and pop commands let us add content to the current picture as well as
+manipulating the picture as a whole without any side effects. The final result is
+put on top of the already drawn content. Instead of the sequence:
+
+\starttyping
+pushcurrentpicture ;
+ ...
+ currentpicture := currentpicture ... transformations ... ;
+popcurrentpicture ;
+\stoptyping
+
+you can say:
+
+\starttyping
+pushcurrentpicture ;
+ ...
+popcurrentpicture ... transformations ... ;
+\stoptyping
+
+Both are equivalent to:
+
+\starttyping
+draw image ( ... ) ... transformations ... ;
+\stoptyping
+
+For larger sequences of commands, the push||pop alternative gives a bit more more
+readable code.
+
+\stopsection
+
+\startsection[title={Fool yourself}]
+
+When doing a literature search on the human perception of black||white edges, I
+ran into several articles with graphics that I remember having seen before in
+books on psychology, physiology and|/|or ergonomics. One of the articles was by
+Edward H.~Adelson of MIT and we will use a few of his example graphics in our
+exploration to what extend \METAPOST\ can be of help in those disciplines. Since
+such graphics normally occur in typeset documents, we will define them in the
+document source.
+
+\startbuffer[a]
+\startbuffer
+interim linecap := butt ; numeric u ; u := 1cm ;
+pickup pencircle scaled .5u ;
+for i=1u step u until 5u :
+ draw (0,i) -- (5u,i) ;
+endfor ;
+for i=2u step u until 4u :
+ draw (u,i) -- (2u,i) withcolor .5white ;
+ draw ((3u,i) -- (4u,i)) shifted (0,-.5u) withcolor .5white ;
+endfor ;
+\stopbuffer
+\stopbuffer
+
+\startbuffer[b]
+\placefigure
+ [here][fig:tricked 1]
+ {White's illusion.}
+ {\processMPbuffer}
+\stopbuffer
+
+\getbuffer[a,b]
+
+Unless you belong to the happy few whose visual capabilities are not distorted by
+neural optimizations, in \in {figure} [fig:tricked 1] the gray rectangles at the
+left look lighter than those on the right. Alas, you can fool yourself, but
+\METAPOST\ does not cheat. This graphic, referred to as White's illusion, is
+defined as follows.
+
+\typebuffer[a]
+
+Watch how we include the code directly. We have packaged this graphic in a buffer
+which we include as a floating figure.
+
+\typebuffer[b]
+
+When passed to \METAPOST, this code is encapsulated in its \type {beginfig} and
+\type {endfig} macros and thereby grouped. But any change to a variable that is
+not explicitly saved, migrates to the outer level. In order to prevent all
+successive graphics to have butt'd linecaps, we have to change this line
+characteristic locally. Because \type {linecap} is defined as an internal
+variable, we have to use \type {interim} to overload its value. Because \type {u}
+is a rather commonly used scratch variable, we don't save its value.
+
+Watch how we use \type {u} as the loop step. In spite of what your eyes tell you,
+this graphic only has two explicit color directives, both being 50\% black. In
+the next example we will use some real colors.
+
+\startbuffer[a]
+\startuseMPgraphic{first}
+ numeric size, delta ;
+ size := 2.5cm ; delta := size/3 ;
+ color mainshade, topshade, bottomshade, centershade ;
+ mainshade := \MPcolor{funcolor} ;
+ topshade := .9mainshade ; bottomshade := .5mainshade ;
+ centershade := .5[topshade,bottomshade] ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[b]
+\startuseMPgraphic{second}
+ \includeMPgraphic{first}
+ fill fullsquare scaled size withcolor topshade ;
+ fill fullsquare scaled delta withcolor centershade ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[c]
+\startuseMPgraphic{third}
+ \includeMPgraphic{first}
+ fill fullsquare scaled size withcolor bottomshade ;
+ fill fullsquare scaled delta withcolor centershade ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer[a,b,c]
+
+\startbuffer[d]
+\startcombination[5*2]
+ {\definecolor[funcolor][red] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][green] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][blue] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][yellow]\useMPgraphic{second}} {}
+ {\definecolor[funcolor][white] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][red] \useMPgraphic{third}} {}
+ {\definecolor[funcolor][green] \useMPgraphic{third}} {}
+ {\definecolor[funcolor][blue] \useMPgraphic{third}} {}
+ {\definecolor[funcolor][yellow]\useMPgraphic{third}} {}
+ {\definecolor[funcolor][white] \useMPgraphic{third}} {}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:tricked 2]
+ {The simultaneous contrast effect.}
+ {\getbuffer[d]}
+
+In \in {figure} [fig:tricked 2] the small squares in the center of each colored
+pair of big squares have the same shade, but the way we perceive them are
+influenced by their surroundings. Both sets of squares are defined using usable
+graphics. The top squares are defined as:
+
+\typebuffer[b]
+
+and the bottom squares are coded as:
+
+\typebuffer[c]
+
+Because both graphics share code, we have defined that code as a separate
+graphic, that we include. The only point of interest in this definition is the
+fact that we let \METAPOST\ interpolate between the two colors using \type {.5[
+]}.
+
+\typebuffer[a]
+
+The color \type {funcolor} is provided by \CONTEXT, and since we want to use this
+graphic with different colors, this kind of mapping is quite convenient. The
+bunch of graphics is packaged in a combination with empty captions. Note how we
+set the color before we include the graphic.
+
+\typebuffer[d]
+
+We use a similar arrangement for the following graphic, where we have replaced
+the definitions of \type {first}, \type {second} and \type {third} by new
+definitions.
+
+\startbuffer[a]
+\startuseMPgraphic{first}
+ numeric height, width, radius, gap ; gap := 1mm ;
+ height = 2.5cm ; width := height/2 ; radius := height/2.5 ;
+ color mainshade, leftshade, rightshade, centershade ;
+ mainshade := \MPcolor{funcolor} ;
+ leftshade := .9mainshade ; rightshade := .5mainshade ;
+ centershade := .5[leftshade,rightshade] ;
+ fill unitsquare xyscaled ( width,height) withcolor leftshade ;
+ fill unitsquare xyscaled (-width,height) withcolor rightshade ;
+ draw (fullcircle scaled radius) shifted (0,height/2)
+ withpen pencircle scaled (radius/2) withcolor centershade ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[b]
+\startuseMPgraphic{second}
+ \includeMPgraphic{first}
+ interim linecap := butt ; pickup pencircle scaled gap ;
+ draw (0,0) -- (0,height) withcolor white ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[c]
+\startuseMPgraphic{third}
+ \includeMPgraphic{first}
+ picture p, q ; p := q := currentpicture ;
+ clip p to unitsquare xscaled width yscaled height ;
+ clip q to unitsquare xscaled -width yscaled height ;
+ currentpicture := p ;
+ addto currentpicture also q shifted (0,radius/2) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer[a,b,c]
+
+\startbuffer[d]
+\startcombination[5*3]
+ {\definecolor[funcolor][red] \useMPgraphic{first}} {}
+ {\definecolor[funcolor][green] \useMPgraphic{first}} {}
+ {\definecolor[funcolor][blue] \useMPgraphic{first}} {}
+ {\definecolor[funcolor][yellow]\useMPgraphic{first}} {}
+ {\definecolor[funcolor][white] \useMPgraphic{first}} {}
+ {\definecolor[funcolor][red] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][green] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][blue] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][yellow]\useMPgraphic{second}} {}
+ {\definecolor[funcolor][white] \useMPgraphic{second}} {}
+ {\definecolor[funcolor][red] \useMPgraphic{third}} {}
+ {\definecolor[funcolor][green] \useMPgraphic{third}} {}
+ {\definecolor[funcolor][blue] \useMPgraphic{third}} {}
+ {\definecolor[funcolor][yellow]\useMPgraphic{third}} {}
+ {\definecolor[funcolor][white] \useMPgraphic{third}} {}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:tricked 3]
+ {Koffka's examples of manipulating contrast by changing
+ the spatial configuration.}
+ {\getbuffer[d]}
+
+The definition of the first row of \in {figure} [fig:tricked 3] is used in the
+second and third and therefore is the most complicated. We use quite some scratch
+variables to reach a high level of abstraction. The \type {xyscaled} operator is
+a \METAFUN\ macro.
+
+\typebuffer[a]
+
+The graphics of the second row extends those of the first by drawing a white line
+through the middle. In this example setting the linecap is not really needed,
+because rounded top and bottoms in white are invisible and the part that extends
+beyond the points does not count in calculating the bounding box.
+
+\typebuffer[b]
+
+The third row graphics again extend the first graphic. First we copy the picture
+constructed so far. Watch the double assignment. Next we clip the pictures in
+half, and shift the right half down over the width of the circle.
+
+\typebuffer[c]
+
+\stopsection
+
+% \startsection[title={Puzzles}]
+%
+% {\em Maybe.}
+%
+% \stopsection
+%
+% \startsection[title={Flow charts}]
+%
+% {\em Instead of starting anew every time, you can use predefined macros, like
+% those in the flow chart module. Let's see how we can influence the \METAPOST\
+% code. Maybe not here.}
+%
+% \stopsection
+%
+% \startsection[title={Chemistry}]
+%
+% {\em \METAPOST\ can do it's work unseen, as in the chemistry module that comes
+% with \CONTEXT. There, \METAPOST\ is used as one of the graphical plug||ins. It
+% demonstrates that we can put \METAPOST\ to work without seeing any code.}
+%
+% \stopsection
+
+\startsection[title={Growing graphics}]
+
+Although \METAPOST\ is not really suited as a simulation engine, it is possible
+to build graphics that are built and displayed incrementally with a sequence of
+mouse clicks. The following example is the result of an email discussion David
+Arnold and the author had while \METAFUN\ evolved.
+
+Instead of defining the graphics in a separate \METAPOST\ file, we will
+incorporate them in the document source in which they are used. We can use
+several methods.
+
+\startitemize[n]
+\startitem
+ Define macros and figures in a separate file and include the graphics as
+ external graphics.
+\stopitem
+\startitem
+ Define everything in the document source as usable graphics and include the
+ graphics using \type {\useMPgraphic}.
+\stopitem
+\startitem
+ Package the graphic components in buffers and paste those together as
+ graphics that can be processed at run time.
+\stopitem
+\stopitemize
+
+The first method is the most independent one, which has its advantages if we want
+to use the graphics in other applications too. The second method works well in
+graphics where parts of the definitions change between invocations of the
+graphic. This method follows the template:
+
+\starttyping
+\startuseMPgraphic{whatever}
+ ...
+\stopuseMPgraphic
+
+\startuseMPgraphic{result}
+ ...
+ \includeMPgraphic{whatever}
+ ...
+\stopuseMPgraphic
+
+\useMPgraphic{result}
+\stoptyping
+
+The disadvantage of this method is that it cannot be combined with \type
+{btex}||\type {etex} since it is nearly impossible to determine when, how, and to
+what extent the content of a graphic should be expanded before writing it to the
+temporary \METAPOST\ file.
+
+Therefore, we will demonstrate how buffers can be used. This third method closely
+parallels the first way of defining graphics. A nice side effect is that we can
+easily typeset these buffers verbatim, which we did to typeset this document.
+
+We are going to do a classic compass and straightedge construction, the bisection
+of a line segment joining two arbitrary points. We will construct five graphics,
+where each one displays one step of the construction. We will embed each graphic
+in a start||stop command. Later we will see the advantage of this strategy.
+
+\startbuffer
+\startbuffer[a]
+def start_everything = enddef ;
+def stop_everything = enddef ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startbuffer[b]
+numeric u, w ; u := .5cm ; w := 1pt ;
+
+pickup pencircle scaled w ;
+
+def draw_dot expr p =
+ draw p withpen pencircle scaled 3w ;
+enddef ;
+
+def stand_out =
+ drawoptions(withcolor .625red) ;
+enddef ;
+\stopbuffer
+\stopbuffer
+
+We are going to draw a few dots, and to force consistency we first define a macro
+\type {draw_dot}. The current step will be highlighted in red using \type
+{stand_out}.
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startbuffer[c]
+def draw_basics =
+ pair pointA, pointB ; path lineAB ;
+ pointA := origin ; pointB := pointA shifted (5u,0) ;
+ lineAB := pointA -- pointB ;
+ draw lineAB ;
+ draw_dot pointA ; label.lft(btex A etex, pointA) ;
+ draw_dot pointB ; label.rt (btex B etex, pointB) ;
+enddef ;
+\stopbuffer
+\stopbuffer
+
+First, we construct the macro that will plot two points $A$ and $B$ and connect
+them with a line segment.
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startbuffer[1]
+start_everything ;
+ stand_out ; draw_basics ;
+stop_everything ;
+\stopbuffer
+\stopbuffer
+
+The code in this buffer executes the preceding macros. The \type {..._everything}
+commands are still undefined, but later we can use these hooks for special
+purposes.
+
+\typebuffer \getbuffer
+
+This graphic can now be embedded by the \CONTEXT\ command
+\type {\processMPbuffer}. This command, like the ordinary
+buffer inclusion commands, accepts a list of buffers.
+
+\startbuffer
+\startlinecorrection[blank]
+\ruledhbox{\processMPbuffer[a,b,c,1]}
+\stoplinecorrection
+\stopbuffer
+
+\typebuffer
+
+We use \type {\ruledhbox} to show the tight bounding box of the graphic. The line
+correction takes care of proper spacing around non textual content, like
+graphics. \footnote {These spacing commands try to get the spacing around the
+content visually compatible, and take the height and depth of the preceding and
+following text into account.} This is only needed when the graphic is part of the
+text flow!
+
+\getbuffer
+
+Next, we draw two circles of equal radius, one centered at point $A$, the other
+at point $B$.
+
+\startbuffer
+\startbuffer[d]
+def draw_circles =
+ path circleA, circleB ; numeric radius, distance ;
+ distance := (xpart pointB) - (xpart pointA) ;
+ radius := 2/3 * distance ;
+ circleA := fullcircle scaled (2*radius) ;
+ circleB := circleA shifted pointB ;
+ draw circleA ;
+ draw circleB ;
+enddef ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startbuffer[2]
+start_everything ;
+ draw_basics ; stand_out ; draw_circles ;
+stop_everything ;
+\stopbuffer
+\stopbuffer
+
+As you can see, we move down the \type {stand_out} macro so that only the
+additions are colored red.
+
+\typebuffer \getbuffer
+
+We now use \type{\processMPbuffer[a,b,c,d,2]} to include the latest step.
+
+\startlinecorrection[blank]
+\ruledhbox{\processMPbuffer[a,b,c,d,2]}
+\stoplinecorrection
+
+The next step in the construction of the perpendicular bisector requires that we
+find and label the points of intersection of the two circles centered at points
+$A$ and $B$. The intersection points are calculated as follows. Watch the \type
+{reverse} operation, which makes sure that we get the second intersection point.
+
+\startbuffer
+\startbuffer[e]
+def draw_intersection =
+ pair pointC, pointD ;
+ pointC := circleA intersectionpoint circleB ;
+ pointD := (reverse circleA) intersectionpoint (reverse circleB) ;
+ draw_dot pointC ; label.lft(btex C etex, pointC shifted (-2w,0)) ;
+ draw_dot pointD ; label.lft(btex D etex, pointD shifted (-2w,0)) ;
+enddef ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startbuffer[3]
+start_everything ;
+ draw_basics ; draw_circles ; stand_out ; draw_intersection ;
+stop_everything ;
+\stopbuffer
+\stopbuffer
+
+In placing the label, we must make sure that the text runs free of the lines and
+curves. Again, move the \type {stand_out} macro just prior to \type
+{draw_intersection} macro, so that this step is highlighted in the drawing color,
+while prior steps are drawn in the default color (in this case black).
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\ruledhbox{\processMPbuffer[a,b,c,d,e,3]}
+\stoplinecorrection
+
+The line drawn through points $C$ and $D$ will be the perpendicular bisector of
+the line segment connecting points $A$ and $B$. In the next step we will draw a
+line using the plain \METAPOST\ \type {drawdblarrow} macro that draws arrowheads
+at each end of a path.
+
+\startbuffer
+\startbuffer[f]
+def draw_bisector =
+ path lineCD ;
+ lineCD := origin -- origin shifted (2*distance,0) ;
+ lineCD := lineCD rotated 90 shifted 0.5[pointA,pointB] ;
+ lineCD := lineCD shifted (0,-distance) ;
+ drawdblarrow lineCD ;
+enddef ;
+\stopbuffer
+
+\startbuffer[4]
+start_everything ;
+ draw_basics ; draw_circles ; draw_intersection ; stand_out ;
+ draw_bisector ;
+stop_everything ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\ruledhbox{\processMPbuffer[a,b,c,d,e,f,4]}
+\stoplinecorrection
+
+The following code draws the intersection of line $C-D$ and line segment $A-B$,
+which can be shown to be the midpoint of segment $A-B$.
+
+\startbuffer
+\startbuffer[g]
+def draw_midpoint =
+ pair pointM ;
+ pointM := lineCD intersectionpoint lineAB ;
+ draw_dot pointM ; label.llft(btex M etex, pointM) ;
+enddef ;
+\stopbuffer
+
+\startbuffer[5]
+start_everything ;
+ draw_basics ; draw_circles ; draw_intersection ; draw_bisector ;
+ stand_out ; draw_midpoint ;
+stop_everything ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\ruledhbox{\processMPbuffer[a,b,c,d,e,f,g,5]}
+\stoplinecorrection
+
+As long as we place the graphics as individual insertions in our document,
+everything is fine. However, if we wish to place them all at once, or as we shall
+see later, place them on top of one another in a fieldstack, it makes sense to
+give them all the same bounding box. We can do this by completing the \type
+{start_everything} and \type {stop_everything} commands.
+
+\startbuffer
+\startbuffer[a]
+def start_everything =
+ path bb ;
+ draw_basics ;
+ draw_circles ;
+ draw_intersection ;
+ draw_bisector ;
+ draw_midpoint ;
+ bb := boundingbox currentpicture ;
+ currentpicture := nullpicture ;
+enddef ;
+
+def stop_everything =
+ setbounds currentpicture to bb ;
+enddef ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer \getbuffer
+
+In \in {figure} [fig:1 till 5] we demonstrate the effect of this redefinition.
+For this purpose we scale down the graphic to a comfortable 40\%, of course by
+using an additional buffer. We also visualize the bounding box.
+
+\startbuffer
+\startbuffer[h]
+def stop_everything =
+ setbounds currentpicture to bb ;
+ draw bb withpen pencircle scaled .5pt withcolor .625yellow ;
+ currentpicture := currentpicture scaled .4 ;
+enddef ;
+\stopbuffer
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The graphic itself is defined as follows. Watch how we use the default buffer to
+keep the definitions readable.
+
+\startbuffer
+\startbuffer
+\startcombination[5*1]
+ {\processMPbuffer[a,b,c,h,d,e,f,g,1]} {step 1}
+ {\processMPbuffer[a,b,c,h,d,e,f,g,2]} {step 2}
+ {\processMPbuffer[a,b,c,h,d,e,f,g,3]} {step 3}
+ {\processMPbuffer[a,b,c,h,d,e,f,g,4]} {step 4}
+ {\processMPbuffer[a,b,c,h,d,e,f,g,5]} {step 5}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here][fig:1 till 5]
+ {The five graphics, each with the same bounding box.}
+ {\getbuffer}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+As the original purpose of these graphics was not to show them side by side, but
+to present them as field stack in a document to be viewed at the computer screen.
+For this purpose we have to define the graphics as symbols.
+
+\startbuffer
+\definesymbol[step 1][{\processMPbuffer[a,b,c,d,e,f,g,1]}]
+\definesymbol[step 2][{\processMPbuffer[a,b,c,d,e,f,g,2]}]
+\definesymbol[step 3][{\processMPbuffer[a,b,c,d,e,f,g,3]}]
+\definesymbol[step 4][{\processMPbuffer[a,b,c,d,e,f,g,4]}]
+\definesymbol[step 5][{\processMPbuffer[a,b,c,d,e,f,g,5]}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+A field stack is a sequence of overlayed graphics. We will arrange these to cycle
+manually, with clicks of the mouse, through the sequence of graphs depicting the
+construction of the midpoint of segment $A-B$. So, in fact we are dealing with a
+manual simulation. The definition of such a stack is as follows:
+
+\startbuffer
+\definefieldstack
+ [midpoint construction]
+ [step 1, step 2, step 3, step 4, step 5]
+ [frame=on,offset=3pt,framecolor=darkyellow,rulethickness=1pt]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The first argument is to be a unique identifier, the second argument takes a list
+of symbols, while the third argument accepts settings. More on this command can
+be found in the \CONTEXT\ manuals.
+
+The stack is shown as \in {figure} [fig:steps]. Its caption provides a button,
+which enables the reader to cycle through the stack. We call this a stack because
+the graphics are positioned on top of each other. Only one of them is visible at
+any time.
+
+\startbuffer
+\placefigure
+ [here][fig:steps]
+ {Bisecting a line segment with compass and straightedge? Just
+ click \goto {here} [JS(Walk_Field{midpoint construction})] to
+ walk through the construction! (This stack is only visible
+ in a \PDF\ viewer that supports widgets.)}
+ {\framed{\startoverlay
+ {\symbol[step 1]}
+ {\fieldstack[midpoint construction]}
+ \stopoverlay}}
+\stopbuffer
+
+\typebuffer
+
+We cheat a bit and overlay the stack over the first symbol because otherwise
+nothing shows up in print (nowadays I mostly use sumatrapdf).
+
+{\setupinteraction[color=darkred,contrastcolor=darkred]\getbuffer}
+
+At the start of this section, we mentioned three methods. When we use the first
+method of putting all the graphics in an external \METAPOST\ file, the following
+framework suits. We assume that the file is called \type {step.mp} and that it is
+kept by the user along with his document source. We start with the definitions of
+the graphic steps. These are the same as the ones shown previously.
+
+\starttyping
+def draw_basics = ... enddef ;
+def draw_circles = ... enddef ;
+def draw_intersection = ... enddef ;
+def draw_bisector = ... enddef ;
+def draw_midpoint = ... enddef ;
+def stand_out = ... enddef ;
+\stoptyping
+
+We can safe some code by letting the \type {..._everything} take care of the
+\type {beginfig} and \type {endfig} macros.
+
+\starttyping
+def start_everything (expr n) = beginfig(n) ; ... enddef ;
+def stop_everything = ... ; endfig ; enddef ;
+\stoptyping
+
+The five graphics now become:
+
+\starttyping
+start_everything (1) ;
+ stand_out ; draw_basics ;
+stop_everything ;
+
+start_everything (2) ;
+ draw_basics ; stand_out ; draw_circles ;
+stop_everything ;
+
+start_everything (3) ;
+ draw_basics ; draw_circles ; stand_out ; draw_intersection ;
+stop_everything ;
+
+start_everything (4) ;
+ draw_basics ; draw_circles ; draw_intersection ; stand_out ;
+ draw_bisector ;
+stop_everything ;
+
+start_everything (5) ;
+ draw_basics ; draw_circles ; draw_intersection ; draw_bisector ;
+ stand_out ; draw_midpoint ;
+stop_everything ;
+\stoptyping
+
+The definitions of the symbols now refer to an external
+figure.
+
+\starttyping
+\definesymbol[step 1][{\externalfigure[step.1]}]
+\definesymbol[step 2][{\externalfigure[step.2]}]
+\definesymbol[step 3][{\externalfigure[step.3]}]
+\definesymbol[step 4][{\externalfigure[step.4]}]
+\definesymbol[step 5][{\externalfigure[step.5]}]
+\stoptyping
+
+Which method is used, depends on the way the graphics are used. In this example
+we wanted to change the definition of \type {..._everything}, so here the third
+method was quite useful.
+
+\stopsection
+
+\startsection[title={Simple Logos}]
+
+\startbuffer[ns]
+numeric width, height, line, delta ;
+width = 5cm ; height = width/2 ; line = height/4 ; delta = line ;
+
+linejoin := mitered ; pickup pencircle scaled line ;
+
+color nsblue ; nsblue := (0,0,1) ;
+color nsyellow ; nsyellow := (1,1,0) ;
+
+z1 = (0, height/2) ;
+z2 = (width/2-height/4, y1) ;
+z3 = (width/2+height/4, y4) ;
+z4 = (width, 0) ;
+
+z5 = (x4+height/2, y1) ;
+z6 = (x4, 2y1) ;
+z7 = 1.5[z5,z6] ;
+
+path p ; p := z1--z2--z3--z4 ; path q ; q := z3--z4--z5--z7 ;
+
+numeric d, lx, ly, ux, uy ; d = line/2 ;
+
+lx = -3d - d/3 ; ly = -d ; ux = rt x5 + d/3 ; uy = top y6 ;
+
+path r ; r := (lx,ly)--(ux,ly)--(ux,uy)--(lx,uy)--cycle;
+
+lx := lx-delta ; ly := ly-delta ; ux := ux+delta ; uy := uy+delta ;
+
+path s ; s := (lx,ly)--(ux,ly)--(ux,uy)--(lx,uy)--cycle;
+
+draw p withcolor nsblue ; draw q withcolor nsblue ;
+
+addto currentpicture also currentpicture
+ rotatedaround (.5[z2,z3],180) shifted (height/4,height/2) ;
+
+picture savedpicture ; savedpicture := currentpicture ;
+
+clip currentpicture to r ;
+setbounds currentpicture to r ;
+
+savedpicture := currentpicture ; currentpicture := nullpicture ;
+
+fill s withcolor nsyellow ;
+addto currentpicture also savedpicture ;
+\stopbuffer
+
+Many company logos earn their beauty from their simplicity. One of the logos that
+most Dutch people have imprinted in their mind is that of the Dutch Railway
+Company (NS). An interesting feature of this logo is that, although it is widely
+known, drawing it on a piece of paper from mind is a task that many people fail.
+
+\startlinecorrection[blank]
+\processMPbuffer[ns]
+\stoplinecorrection
+
+This logo makes a good candidate for demonstrating a few fine points of drawing
+graphics, like using linear equations, setting line drawing characteristics,
+clipping and manipulating bounding boxes.
+
+The implementation below is quite certainly not according to the official
+specifications, but it can nevertheless serve as an example of defining such
+logos.
+
+\startbuffer[a]
+numeric width ; width = 3cm ;
+numeric height ; height = width/2 ;
+numeric line ; line = height/4 ;
+\stopbuffer
+
+As always, we need to determine the dimensions first. Here, both the height and
+line width depend on the width of the graphic.
+
+Instead of calculating the blue shape such that it will be a filled outline, we
+will draw the logo shape using line segments. This is why we need the \type
+{line} parameter.
+
+\typebuffer[a]
+
+We want sharp corners which can be achieved by setting \type {linejoin} to \type
+{mitered}.
+
+\startbuffer[b]
+linejoin := mitered ; pickup pencircle scaled line ;
+\stopbuffer
+
+\typebuffer[b]
+
+The colors are rather primary blue and yellow. At the time of writing this
+manual, Dutch trains are still painted yellow, so we will use that shade as
+background color.
+
+\startbuffer[c]
+color nsblue ; nsblue := (0,0,1) ;
+color nsyellow ; nsyellow := (1,1,0) ;
+\stopbuffer
+
+\typebuffer[c]
+
+We will now describe the main curves. Although these expressions are not that
+advanced, they demonstrate that we can express relationships instead of using
+assignments.
+
+\startbuffer[d]
+z1 = (0, height/2) ;
+z2 = (width/2-height/4, y1) ;
+z3 = (width/2+height/4, y4) ;
+z4 = (width, 0) ;
+
+path p ; p := z1--z2--z3--z4 ;
+\stopbuffer
+
+\typebuffer[d]
+
+Although it is accepted to consider \type {z} to be a variable, it is in fact a
+\type {vardef} macro, that expands into a pair \type {(x,y)}. This means that the
+previous definitions internally become:
+
+\starttyping
+(x1,y1) = (0, height/2) ;
+(x2,y2) = (width/2-height/4, y1) ;
+(x3,y3) = (width/2+height/4, y4) ;
+(x4,y4) = (width, 0) ;
+\stoptyping
+
+These 8 relations can be solved by \METAPOST, since all dependencies are known.
+
+\starttyping
+x1 = 0 ; y1 = height/2 ;
+x2 = width/2-height/4 ; y2 = y1 ;
+x3 = width/2+height/4 ; y3 = y4 ;
+x4 = width ; y4 = 0 ;
+\stoptyping
+
+Since we express the variables \type {x} and \type {y} in terms of relations, we
+cannot reuse them, because that would mean that inconsistent relations occur. So,
+the following lines will lead to an error message:
+
+\starttyping
+z1 = (10,20) ; z1 = (30,50) ;
+\stoptyping
+
+For similar reasons, we may not assign a value (using \type {:=}) to such a \type
+{z} variable. Within a \METAPOST\ figure, \type {z} variables are automatically
+saved, which means that they can be reused for each figure.
+
+\startbuffer[x]
+drawpath p ; drawpoints p ; drawpointlabels p ;
+\stopbuffer
+
+So far, we have defined the following segment of the logo.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,x]
+\stoplinecorrection
+
+\startbuffer[e]
+z5 = (x4+height/2, y1) ;
+z6 = (x4, 2y1) ;
+z7 = 1.5[z5,z6] ;
+
+path q ; q := z3--z4--z5--z7 ;
+\stopbuffer
+
+The next expressions are used to define the second segment. The third expression
+determines \type {z7} to be positioned on the line \type {z5--z6}, where we
+extend this line by 50\%.
+
+\typebuffer[e]
+
+\startbuffer[x]
+drawpath q ; drawpoints q ; drawpointlabels q ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,x]
+\stoplinecorrection
+
+If we combine these two segments, we get:
+
+\startbuffer[x]
+drawpath p ; drawpoints p ; drawpointlabels p ;
+swappointlabels := true ;
+drawpath q ; drawpoints q ; drawpointlabels q ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,x]
+\stoplinecorrection
+
+However, when we draw them using the right linewidth and color, you will notice
+that we're not yet done:
+
+\startbuffer[f]
+draw p withcolor nsblue ; draw q withcolor nsblue ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,f]
+\stoplinecorrection
+
+The second curve is similar to the first one, but rotated over 180 degrees.
+
+\startbuffer[g]
+addto currentpicture also currentpicture
+ rotatedaround (.5[z2,z3],180) shifted (height/4,height/2) ;
+\stopbuffer
+
+\typebuffer[g]
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,f,g]
+\stoplinecorrection
+
+In order to get the sharp edges, we need to clip off part of
+the curves and at first sight, we may consider using a
+scaled bounding box. However, when we show the natural
+bounding box, you will notice that a more complicated bit of
+calculations is needed.
+
+\startbuffer[x]
+draw boundingbox currentpicture
+ withpen pencircle scaled .5mm withcolor .625white ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,f,g,x]
+\stoplinecorrection
+
+The right clip path is calculated using the following expressions. Watch how we
+use \type {rt} and \type {top} to correct for the linewidth.
+
+\startbuffer[h]
+numeric d, lx, ly, ux, uy ; d = line/2 ;
+
+lx = -3d - d/3 ; ly = -d ; ux = rt x5 + d/3 ; uy = top y6 ;
+
+path r ; r := (lx,ly)--(ux,ly)--(ux,uy)--(lx,uy)--cycle;
+\stopbuffer
+
+\typebuffer[h]
+
+The clipping path is applied by saying:
+
+\startbuffer[i]
+clip currentpicture to r ;
+\stopbuffer
+
+\typebuffer[i]
+
+The result is quite acceptable:
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,f,g,h,i]
+\stoplinecorrection
+
+But, if you watch closely to how this graphic extends into to left margin of this
+document, you will see that the bounding box is not yet right.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,f,g,h,i,x]
+\stoplinecorrection
+
+\startbuffer[j]
+setbounds currentpicture to r ;
+\stopbuffer
+
+\typebuffer[j]
+
+We use the same path \type {r} to correct the bounding box.
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,f,g,h,i,j,x]
+\stoplinecorrection
+
+There are a few subtle points involved, like setting the \type {linejoin}
+variable. If we had not set it to \type {mitered}, we would have got round
+corners. We don't set the \type {linecap}, because a flat cap would not extend
+far enough into the touching curve and would have left a small hole. The next
+example shows what happens if we set these variables to the wrong values:
+
+\startbuffer[bb]
+linejoin := rounded ; linecap := mitered ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,bb,c,d,e,f,g,h,i,j]
+\stoplinecorrection
+
+In fact we misuse the fact that both curves overlay each other.
+
+\startbuffer[f]
+draw p withcolor nsblue ; draw q withcolor .625white ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b,c,d,e,f,g,h,i,j]
+\stoplinecorrection
+
+The complete logo definition is a bit more extensive because we also want to add
+a background. Because we need to clip the blue foreground graphic, we must
+temporarily store it when we fill the background.
+
+\typebuffer[ns]
+
+For practical use it makes sense to package this definition in a macro to which
+we pass the dimensions.
+
+\stopsection
+
+\startsection[title={Music sheets}]
+
+The next example demonstrates quite some features. Imagine that we want to make
+us a couple of sheets so that we can write a musical masterpiece. Let's also
+forget that \TEX\ can draw lines, which means that somehow we need to use
+\METAPOST.
+
+Drawing a bar is not that complicated as the following code demonstrates.
+
+\startbuffer
+\startusableMPgraphic{bar}
+ vardef MusicBar (expr width, gap, linewidth, barwidth) =
+ image
+ ( interim linecap := butt ;
+ for i=1 upto 5 :
+ draw ((0,0)--(width,0)) shifted (0,(i-1)*gap)
+ withpen pencircle scaled linewidth ;
+ endfor ;
+ for i=llcorner currentpicture -- ulcorner currentpicture ,
+ lrcorner currentpicture -- urcorner currentpicture :
+ draw i withpen pencircle scaled barwidth ;
+ endfor ; )
+ enddef ;
+\stopusableMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We can define the sidebars a bit more efficient using two predefined subpaths:
+
+\starttyping
+for i=leftboundary currentpicture, rightboundary currentpicture :
+\stoptyping
+
+We define a macro \type {MusicBar} that takes four arguments. The first two
+determine the dimensions, the last two concern the line widths. Now watch how we
+can use this macro:
+
+\startbuffer
+\includeMPgraphic{bar} ;
+draw MusicBar (200pt, 6pt, 1pt, 2pt) ;
+draw MusicBar (300pt, 6pt, 1pt, 2pt) shifted (0,-30pt) ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+As you can see in this example, the bar is a picture that can be transformed
+(shifted in our case). However, a close look at the macro teaches us that it does
+a couple of draws too. This is possible because we wrap the whole in an image
+using the \type {image} macro. This macro temporary saves the current picture,
+and at the end puts the old \type {currentpicture} under the new one.
+
+We wrap the whole in a \type {vardef}. This means that the image is returned as
+if it was a variable. Actually, the last thing in a \type {vardef} should be a
+proper return value, in our case a picture. This also means that we may not end
+the \type {vardef} with a semi colon. So, when the content of the \type {vardef}
+is expanded, we get something
+
+\starttyping
+draw some_picture ... ;
+\stoptyping
+
+Because we are still drawing something, we can add transform directives and set
+attributes, like the color.
+
+The second \type {for} loop demonstrates two nice features. Instead of repeating
+the draw operation by copying code, we apply it to a list, in our case a list of
+paths. This list contains two simple line paths. Because an \type {image} starts
+with a fresh \type {currentpicture}, we can safely use the bounding box data to
+determine the height of the line.
+
+The next step in producing the sheets of paper is to put several bars on a page,
+preferable with the width of the current text. This time we will use a reusable
+graphic, because each bar is the same.
+
+\startbuffer
+\startreusableMPgraphic{bars}
+ \includeMPgraphic{bar} ;
+ draw MusicBar (TextWidth, 6pt, 1pt, 2pt) withcolor .625yellow ;
+\stopreusableMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\reuseMPgraphic{bars}
+\stoplinecorrection
+
+Instead of going through the trouble of letting \METAPOST\ calculate the positions
+of the bars, we will use \TEX. We put 12 bars on a page and let \TEX\ take care
+of the inter||bar spacing. Because we only want stretchable space between bars,
+called glue in \TEX, we need to remove the last added glue.
+
+\startnotmode[screen]
+
+\startbuffer[music]
+\startstandardmakeup[doublesided=no,page=]
+ \dorecurse{15}{\reuseMPgraphic{bars}\vfill}\removelastskip
+\stopstandardmakeup
+\stopbuffer
+
+\stopnotmode
+
+\startmode[screen]
+
+\startbuffer[music]
+\startstandardmakeup[doublesided=no,page=]
+ \dorecurse{10}{\reuseMPgraphic{bars}\vfill}\removelastskip
+\stopstandardmakeup
+\stopbuffer
+
+\stopmode
+
+\typebuffer[music]
+
+\startusableMPgraphic{bar}
+ vardef MusicBar (expr width, gap, linewidth, barwidth) =
+ image
+ ( interim linecap := butt ;
+ for i=1 upto 5 :
+ draw ((0,0)--(width,0))
+ randomized (1pt,1.5pt)
+ shifted (0,(i-1)*gap)
+ withpen pencircle scaled linewidth ;
+ endfor ;
+ for i=llcorner currentpicture -- ulcorner currentpicture ,
+ lrcorner currentpicture -- urcorner currentpicture :
+ draw i randomized 2pt shifted (0,-1pt)
+ withpen pencircle scaled barwidth ;
+ endfor ; )
+ enddef ;
+\stopusableMPgraphic
+
+\startreusableMPgraphic{bars} % trigger a new one
+ \includeMPgraphic{bar} ;
+ draw MusicBar (TextWidth, 6pt, 1pt, 2pt) withcolor .625yellow ;
+\stopreusableMPgraphic
+
+It may add to the atmosphere of handy||work if you slightly randomize the lines.
+We leave it up to the reader to figure out how the code should be changed to
+accomplish this.
+
+\startlinecorrection[blank]
+\reuseMPgraphic{bars}
+\stoplinecorrection
+
+The complete result is shown on the next page.
+
+\startpostponing
+\getbuffer[music]
+\stoppostponing
+
+\stopsection
+
+\startsection[title={The euro symbol}]
+
+When Patrick Gundlach posted a nice \METAPOST\ version of the euro symbol to the
+\CONTEXT\ discussion list, he added the comment \quotation {The official
+construction is ambiguous: how thick are the horizontal bars? How much do they
+stick out to the left? Is this thing a circle or what? Are the angles on the left
+side of the bars the same as the one on the right side? \unknown} The alternative
+below is probably not as official as his, but permits a finetuning. You are
+warned: whatever you try, the euro {\em is} and {\em will remain} an ugly symbol.
+
+We use a couple of global variables to control the euro shape within reasonable
+bounds. Then we define two circles. Next we define a vertical line that we use in
+a couple of cut and paste operations. Watch how the top left point of the outer
+circle determines the slant of the line that we use to slice the vertical bars.
+
+\startbuffer[euro]
+boolean trace_euro ; trace_euro := false ;
+
+vardef euro_symbol = image ( % begin_of_euro
+
+if unknown euro_radius : euro_radius := 2cm ; fi ;
+if unknown euro_width : euro_width := 3euro_radius/16 ; fi ;
+if unknown euro_r_offset : euro_r_offset := euro_width ; fi ;
+if unknown euro_l_offset : euro_l_offset := euro_radius/32 ; fi ;
+if unknown euro_l_shift : euro_l_shift := euro_r_offset ; fi ;
+if unknown euro_v_delta : euro_v_delta := euro_width/4 ; fi ;
+
+save
+ outer_circle, inner_circle, hor_bar,
+ right_line, right_slant, top_slant, bot_slant,
+ euro_circle, euro_topbar, euro_botbar ;
+
+path
+ outer_circle, inner_circle, hor_bar,
+ right_line, right_slant, top_slant, bot_slant,
+ euro_circle, euro_topbar, euro_botbar ;
+
+outer_circle := fullcircle scaled euro_radius ;
+inner_circle := fullcircle scaled (euro_radius-euro_width) ;
+
+if trace_euro : for i = outer_circle, inner_circle :
+ draw i withpen pencircle scaled 1pt withcolor .5white ;
+endfor ; fi ;
+
+right_line :=
+ (lrcorner outer_circle -- urcorner outer_circle)
+ shifted (-euro_r_offset,0) ;
+
+outer_circle := outer_circle cutbefore right_line ;
+
+right_slant :=
+ point 0 of outer_circle
+ -- origin shifted (0,ypart lrcorner outer_circle) ;
+
+euro_circle := buildcycle(outer_circle, right_line,
+ reverse inner_circle, reverse right_slant) ;
+
+hor_bar := (-euro_radius,0) -- (euro_radius,0) ;
+
+top_slant :=
+ right_slant shifted (-euro_radius+euro_r_offset-euro_l_offset,0) ;
+
+bot_slant :=
+ top_slant shifted (0,-euro_l_shift) ;
+
+if trace_euro : for i = right_line, right_slant, top_slant, bot_slant :
+ draw i withpen pencircle scaled 1pt withcolor .5white ;
+endfor ; fi ;
+
+euro_topbar := buildcycle
+ (top_slant, hor_bar shifted (0, euro_v_delta),
+ right_slant, hor_bar shifted (0, euro_v_delta+euro_width/2)) ;
+
+euro_botbar := buildcycle
+ (bot_slant, hor_bar shifted (0,-euro_v_delta),
+ right_slant, hor_bar shifted (0,-euro_v_delta-euro_width/2)) ;
+
+for i = euro_circle, euro_topbar, euro_botbar :
+ draw i withpen pencircle scaled 0 ;
+endfor ;
+for i = euro_circle, euro_topbar, euro_botbar :
+ fill i withpen pencircle scaled 0 ;
+endfor ;
+
+if trace_euro :
+ drawpoints euro_circle withcolor red ;
+ drawpoints euro_topbar withcolor green ;
+ drawpoints euro_botbar withcolor blue ;
+fi ;
+
+) enddef ; % end_of_euro
+\stopbuffer
+
+\typebuffer[euro]
+
+We only set a parameter when it is not yet set. This has
+the advantage that we don't have to set them when we change
+one. This way of manipulating paths (cutting and building)
+does not always work well because of rounding errors, but
+here it does work.
+
+\startbuffer[demo]
+euro_radius := 4cm ; trace_euro := true ; draw euro_symbol ;
+\stopbuffer
+
+\typebuffer[demo]
+
+For educational purposes, we have added a bit of
+tracing. When enabled, the euro shows up as:
+
+\startlinecorrection[blank]
+\processMPbuffer[euro,demo]
+\stoplinecorrection
+
+Of course it would be best to define the euro as one shape, but we won't go
+though that process right now. By packaging the combined paths in an image, we
+can conveniently color the euro symbol:
+
+\startbuffer[demo]
+draw euro_symbol withcolor .625red ;
+\stopbuffer
+
+\typebuffer[demo]
+
+\startlinecorrection[blank]
+\processMPbuffer[euro,demo]
+\stoplinecorrection
+
+You may wonder why we both draw and fill the euro, using a pen with zero width.
+We've done this in order to demonstrate the \type {redraw} and \type {refill}
+macros.
+
+\startbuffer[extra]
+redraw currentpicture withpen pencircle scaled 4pt withcolor .625yellow ;
+refill currentpicture withcolor .625white ;
+setbounds currentpicture to boundingbox currentpicture enlarged 2pt ;
+\stopbuffer
+
+\typebuffer[extra]
+
+\startlinecorrection[blank]
+\processMPbuffer[euro,demo,extra]
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Killing time}]
+
+Not seldom \TEX\ users want to use this program and its meta||relatives as
+general purpose tools, even at the cost of quite some effort or suboptimal
+results. Imagine that you are under way from our planet to Mars. After a long
+period of sleep you wake up and start wondering on what track you are. You even
+start questioning the experts that send you on your way, so you pop open your
+laptop, launch your editor and start metaposting.
+
+First you need to determine the begin and end points of your journey. For now it
+is enough to know the relative angle of the paths that both planets follow as
+well as the path themselves. We assume circular paths.
+
+\startbuffer
+path a ; a := fullcircle scaled 3cm ;
+path b ; b := fullcircle scaled 2cm rotated 120 ;
+
+draw a withpen pencircle scaled 1mm withcolor .625red ;
+draw b withpen pencircle scaled 1mm withcolor .625yellow ;
+
+draw point 0 of a withpen pencircle scaled 2mm ;
+draw point 0 of b withpen pencircle scaled 2mm ;
+\stopbuffer
+
+\typebuffer
+
+The rotation 120 can be calculated from the relative starting points and time the
+journey will take. Alternatively we can use the time along the path, but this
+would be a bit more fuzzy later on. \footnote {In case you wonder why \METAPOST\
+talks about the time on a path, you now have a cue.}
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+After a bit of playing with drawing paths between the two points, you decide to
+make a macro. We want to feed the angle between the paths but also the connecting
+path. So, we have to pass a path, but unfortunately we don't have direct access
+to the points. By splitting the argument definition we can pass an expression
+first, and a wildcard argument next.
+
+\startbuffer
+\startuseMPgraphic{gamble}
+def Gamble (expr rot) (text track) =
+ path a ; a := fullcircle scaled 3cm ;
+ path b ; b := fullcircle scaled 2cm rotated rot ;
+
+ pair aa ; aa := point 0 of a ;
+ pair bb ; bb := point 0 of b ;
+ path ab ; ab := track ;
+
+ draw a withpen pencircle scaled 1mm withcolor .625red ;
+ draw b withpen pencircle scaled 1mm withcolor .625yellow ;
+
+ draw aa withpen pencircle scaled 2mm ;
+ draw bb withpen pencircle scaled 2mm ;
+
+ drawarrow ab withpen pencircle scaled 1mm withcolor .625white ;
+
+ setbounds currentpicture to boundingbox a enlarged 2mm ;
+ draw boundingbox currentpicture withpen pencircle scaled .25mm ;
+enddef ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Because at this distance nobody will bother us with the thickness of the pen and
+colors, we code them the hard way. We create our own universe by setting a fixed
+boundingbox.
+
+We leave the Earth in the most popular way, straight upwards and after a few
+cycles, we leave it parallel to the surface. The path drawn reminds much of the
+trajectories shown in popular magazines.
+
+\startbuffer
+\startMPcode
+\includeMPgraphic{gamble} ;
+Gamble(120, aa {(0,1)} .. bb) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+According to \METAPOST, when we leave the Earth straight upwards and want a
+smooth trajectory, we have to pass through outer space.
+
+\startbuffer
+\startMPcode
+\includeMPgraphic{gamble} ;
+Gamble(120,aa {(1,0)} .. bb) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+Given that we want a smooth path as well as a short journey, we can best follow
+Mars' path. Here we face the risk that when we travel slower than Mars does, we
+have a problem.
+
+\startbuffer
+\startMPcode
+\includeMPgraphic{gamble} ;
+Gamble(120,aa {dir 90} .. {precontrol 0 of b rotated 90} bb) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+We can even travel a shorter path when we leave Earth at the surface that faces
+the point of arrival.
+
+\startbuffer
+\startMPcode
+\includeMPgraphic{gamble} ;
+Gamble(120,aa .. {precontrol 0 of b rotated 90} bb) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+In the end we decide that although the trajectories look impressive, we will not
+trust our lives to \METAPOST. A beautiful path is not neccessarily a good path.
+But even then, this macro provides a nice way to experiment with directions,
+controls and tensions.
+
+\stopsection
+
+% \startsection[title={Animations}]
+%
+% {\em Although \METAPOST\ is not that well suited for free hand drawings, you can
+% use it to make stylistics animations.}
+%
+% \stopsection
+
+\startsection[title={Selective randomization}]
+
+In this document we have used a lot of randomization. Because \CONTEXT\ often
+needs multiple runs to sort out cross references, positions, tables of contents,
+and so on, being real random every run would result in endless runs to get things
+right, because the size of graphics changes. This is prevented by storing the
+random seed betweeen runs. You can remove the \type {tuc} file to get a new seed
+(or run \type {context --purgeall}).
+
+Here is another example of randomization. This time we only randomize the control
+points so the main shape sort of remains intact which can be handy when you use
+such random shapes around text but still want a predictable size.
+
+\startbuffer
+\startMPcode
+fill fullcircle scaled 2cm
+ randomizedcontrols 0.1cm
+ withcolor darkred
+ withtransparency (1,.5) ;
+fill ((1cm,0)--(0,1cm)--(-1cm,0)--cycle)
+ randomizedcontrols 0.1cm
+ withcolor darkblue
+ withtransparency (1,.5) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+\startbuffer
+\startMPcode
+draw image (
+ fill fullcircle scaled 2cm
+ withcolor darkred
+ withtransparency (1,.5) ;
+ fill ((1cm,0)--(0,1cm)--(-1cm,0)--cycle)
+ withcolor darkblue
+ withtransparency (1,.5) ;
+) randomizedcontrols 0.1cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+\stopsection
+
+\startsection[title=Snapping]
+
+There are quite some helpers in \METAFUN\ and I must admit that I forgot
+about most. Some just ended up in the core because they can be useful, others
+serve as illustration. Here's one of them: \type {snapped}. First we define
+a few helpers that we then use to check out a few shapes.
+
+\startbuffer
+\startMPdefinitions
+def ShowSnapGrid(text shape) =
+ fill (shape xsized 77mm) withcolor white/3 ;
+ draw image (
+ for i=10mm step 5mm until 100mm :
+ draw fullsquare scaled i ;
+ endfor ;
+ ) withcolor 2white/3 ;
+ drawpoints (shape xsized 77mm) withcolor black ;
+enddef ;
+
+vardef SnapShape expr shape =
+ image (
+ draw shape ;
+ drawpoints shape ;
+ )
+enddef ;
+
+vardef ShowSnapShape expr shape =
+ ShowSnapGrid(shape);
+
+ draw SnapShape(shape xsized 77mm snapped -5mm ) withcolor red ;
+ draw SnapShape(shape xsized 77mm snapped 5mm ) withcolor red ;
+ draw SnapShape(shape xsized 77mm snapped (5mm,10mm)) withcolor green ;
+ draw SnapShape(shape xsized 77mm snapped (5mm,15mm)) withcolor blue ;
+ draw SnapShape(shape xsized 77mm snapped (5mm,20mm)) withcolor yellow ;
+enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\typebuffer \getbuffer
+
+In \in {figures} [fig:snapper:1], \in [fig:snapper:2] and \in [fig:snapper:3] we
+see how the original shape gets snapped on the grid. Of course in more complex
+images the direction of the snapping can change the result in an unwanted way,
+like overlapping shapes that obscure others, but normally this snapping is only
+useful for simple predictable cases (like title pages).
+
+\startplacefigure[reference=fig:snapper:1,title={Messing with \type{fullcircle}.}]
+\startMPcode
+ ShowSnapShape(fullcircle);
+\stopMPcode
+\stopplacefigure
+
+\startplacefigure[reference=fig:snapper:2,title={\type{fullsquare}}]
+\startMPcode
+ ShowSnapShape(fullsquare);
+\stopMPcode
+\stopplacefigure
+
+\startplacefigure[reference=fig:snapper:3,title={\type{fulltriangle}}]
+\startMPcode
+ ShowSnapShape(fulltriangle);
+\stopMPcode
+\stopplacefigure
+
+\stopsection
+
+\startsection[title=Arrowheads]
+
+Arrows are actually drawn quite well in \METAPOST, as the arrowheads nicely adapt
+to the direction of the point where the arrowhead is attached. There are however
+some limitations as the following examples demonstrate: arrows don't work well
+with transparency and you can probably figure out why. Alan Braslau came up with
+an extension that allows to set the dimple of the head. You can see all this
+in \in {figure} [fig:arrowheads].
+
+\startbuffer[a]
+numeric unit ; unit := mm ;
+
+drawoptions(withcolor .6blue withtransparency (1,.25)) ;
+
+pickup pencircle scaled 2unit ; ahlength := 6unit ;
+
+picture p ; p := image (
+ drawarrow reverse fullcircle rotated - 5 scaled 50unit ;
+ drawarrow reverse fullcircle rotated -10 scaled 30unit ;
+) shifted ( -45unit, 0unit) ;
+
+for i=0 step 90 until 360 : draw p rotated i ; endfor ;
+
+currentpicture := currentpicture shifted - center currentpicture ;
+
+p := currentpicture ; p := image (
+ draw llcorner p -- center p ;
+ drawarrow llcorner p -- 0.875[llcorner p,center p] ;
+) ;
+
+for i=0 step 90 until 360 : draw p rotated i ; endfor ;
+
+clip currentpicture to boundingbox (fullcircle scaled 80unit) ;
+
+if lua.mp.mode("screen") :
+ currentpicture := currentpicture ysized .4TextHeight ;
+else :
+ currentpicture := currentpicture xsized .4TextWidth ;
+fi ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startbuffer[b]
+ resetarrows ;
+\stopbuffer
+
+\startbuffer[a1]
+ ahvariant := 1 ;
+\stopbuffer
+\startbuffer[a2]
+ ahvariant := 2 ;
+\stopbuffer
+
+\startbuffer[a3]
+ ahvariant := 1 ; ahdimple := 1/2 ;
+\stopbuffer
+\startbuffer[a4]
+ ahvariant := 1 ; ahdimple := 1 ;
+\stopbuffer
+\startbuffer[a5]
+ ahvariant := 1 ; ahdimple := 5/2 ;
+\stopbuffer
+
+\startplacefigure[reference=fig:arrowheads,title=The way arrowheads are constructed.]
+ \doifelsemode {screen} {
+ \setupcombination[nx=3,ny=2]
+ } {
+ \setupcombination[nx=2,ny=3]
+ }
+ \startcombination[distance=2em]
+ {\processMPbuffer[a, b]} {\tttf ahvariant=0}
+ {\processMPbuffer[a1,a,b]} {\tttf ahvariant=1}
+ {\processMPbuffer[a2,a,b]} {\tttf ahvariant=2}
+ {\processMPbuffer[a3,a,b]} {\tttf ahvariant=1, ahdimple=1/2}
+ {\processMPbuffer[a4,a,b]} {\tttf ahvariant=1, ahdimple=1}
+ {\processMPbuffer[a5,a,b]} {\tttf ahvariant=1, ahdimple=5/2}
+ \stopcombination
+\stopplacefigure
+
+\stopsection
+
+\startsection[title=Teaser]
+
+Sometimes, when playing with \METAPOST\ you run into interesting cases. Here is
+one. The result is shown in \in {figure} [fig:teaser:1].
+
+\startbuffer
+\startusableMPgraphic{BackgroundTeaser}
+ fill OverlayBox enlarged 1mm withcolor darkyellow ; % bleed
+ path p ; p := OverlayBox enlarged -5mm ;
+ path q ; q := OverlayBox enlarged -10mm ;
+ fill q withcolor white ;
+ drawoptions(withcolor darkred) ;
+ fill reverse topboundary q -- topboundary p -- cycle ;
+ fill reverse bottomboundary q -- bottomboundary p -- cycle ;
+ drawoptions(withcolor darkgreen) ;
+ fill reverse leftboundary q -- leftboundary p -- cycle ;
+ fill reverse rightboundary q -- rightboundary p -- cycle ;
+\stopusableMPgraphic
+
+\defineoverlay
+ [BackgroundTeaser]
+ [\useMPgraphic{BackgroundTeaser}]
+
+\framed
+ [frame=off,
+ offset=15mm,
+ background=BackgroundTeaser,
+ align=normal]
+ {\input knuth }
+\stopbuffer
+
+\typebuffer
+
+\startplacefigure[reference=fig:teaser:1,title=Can you guess what happens here?]
+ \getbuffer
+\stopplacefigure
+
+\stopsection
+
+\startsection[title={Lists}]
+
+For some specific purpose I needed to sort a list of paths and therefore
+\METAFUN\ comes with a quick sort macro. Its working can be demonstrated by an
+example.
+
+\startbuffer[a]
+pair p[], pp[] ; numeric n ; n := 25 ;
+for i=1 upto n : p[i] := origin randomized 4cm ; endfor ;
+\stopbuffer
+
+\startbuffer[b]
+copylist(p,pp) ; % unsorted
+drawarrow listtolines(pp) shifted ( 0,0) withcolor darkblue ;
+\stopbuffer
+
+\startbuffer[c]
+copylist(p,pp) ; sortlist(pp)() ; % sorted
+drawarrow listtolines(pp) shifted (300,0) withcolor darkyellow ;
+\stopbuffer
+
+\startbuffer[d]
+copylist(p,pp) ; sortlist(pp)(xpart) ;
+drawarrow listtolines(pp) shifted (100,0) withcolor darkred ;
+
+\stopbuffer
+\startbuffer[e]
+copylist(p,pp) ; sortlist(pp)(ypart) ;
+drawarrow listtolines(pp) shifted (200,0) withcolor darkgreen ;
+\stopbuffer
+
+\startbuffer[f]
+vardef whow expr p = (xpart p + ypart p) enddef ;
+
+copylist(p,pp) ; sortlist(pp)(whow) ;
+drawarrow listtolines(pp) shifted (400,0) withcolor darkcyan ;
+\stopbuffer
+
+\startbuffer[g]
+vardef whow expr p = (xpart p ++ ypart p) enddef ;
+
+copylist(p,pp) ; sortlist(pp)(whow) ;
+drawarrow listtolines(pp) shifted (500,0) withcolor darkmagenta ;
+\stopbuffer
+
+\typebuffer[a,b,c,d,e,f,g]
+
+The result of this code is shown in \in {figure} [fig:sorting].
+
+\startplacefigure[reference=fig:sorting,title={Using the sorter.}]
+ \startcombination[3*2]
+ {\processMPbuffer[a,b]} {\tttf unsorted}
+ {\processMPbuffer[a,c]} {\tttf sorted}
+ {\processMPbuffer[a,d]} {\tttf xpart}
+ {\processMPbuffer[a,e]} {\tttf ypath}
+ {\processMPbuffer[a,f]} {\tttf xpart p + ypart p}
+ {\processMPbuffer[a,g]} {\tttf xpart p ++ ypart p}
+ \stopcombination
+\stopplacefigure
+
+There is a helper that converts a list of paths into a shape that covers all
+of them. In \in {figure} [fig:shapedlist] three shaped lists are shown.
+
+\startbuffer[a]
+ def ShowShape(expr e) =
+ draw image (
+
+ save p ; path p[] ;
+
+ def MakeShape(expr i,w,h,x,y) =
+ p[i] := e
+ xysized ((w,h) randomized (2mm,1mm))
+ shifted ((x,y) randomized (2mm,1mm)) ;
+ enddef ;
+
+ MakeShape(1,40mm,6mm,10mm, 0mm) ;
+ MakeShape(2,50mm,5mm, 5mm,-10mm) ;
+ MakeShape(3,20mm,8mm,30mm,-20mm) ;
+ MakeShape(4,55mm,5mm,10mm,-30mm) ;
+ MakeShape(5,55mm,5mm, 5mm,-50mm) ;
+
+ save s ; path s ; s := shapedlist(p) ; drawarrow s ;
+
+ linejoin := butt ;
+
+ for i=1 upto 5 :
+ fill p[i] withcolor .75white withtransparency (1,.5) ;
+ draw thetextext("\tttf " & decimal i, center p[i]) ;
+ endfor ;
+
+ ) ysized 4cm ;
+ enddef ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startbuffer[b]
+ShowShape(unitsquare)
+\stopbuffer
+
+\startbuffer[c]
+ShowShape(unitcircle)
+\stopbuffer
+
+\startbuffer[d]
+ShowShape(unittriangle)
+\stopbuffer
+
+\startplacefigure[reference=fig:shapedlist,title={The \type {shapedlist} macro returns the envelope that covers all the paths in the list.}]
+ \startcombination[3*1]
+ {\processMPbuffer[a,b]} {\tttf unitsquare}
+ {\processMPbuffer[a,c]} {\tttf unitcircle}
+ {\processMPbuffer[a,d]} {\tttf unittriangle}
+ \stopcombination
+\stopplacefigure
+
+\stopsection
+
+\startsection[title=Table cells]
+
+Sometimes a standard \CONTEXT\ feature doesn't work out as expected. Take the
+following table:
+
+\startbuffer
+\bTABLE[frame=on,framecolor=blue,rulethickness=1pt]
+ \bTR
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD[framecolor=magenta] test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \eTR
+ \bTR
+ \bTD test \eTD
+ \bTD[framecolor=red] test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD[framecolor=green] test \eTD
+ \eTR
+\eTABLE
+\stopbuffer
+
+\typebuffer
+
+Because cells are drawn top|-|down and left|-|right a next cell border
+overruns the previous one.
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+\startbuffer
+\bTABLE[frame=on,framecolor=blue,rulethickness=1pt]
+ \bTR
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD[framecolor=magenta,frameoffset=-.5pt] test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \eTR
+ \bTR
+ \bTD test \eTD
+ \bTD[framecolor=red,frameoffset=-.5pt] test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD[framecolor=green,frameoffset=-.5pt] test \eTD
+ \eTR
+\eTABLE
+\stopbuffer
+
+You can try this:
+
+\typebuffer
+
+which gives us something that is not okay either for cells that touch an edge:
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+but we can cheat:
+
+\startlinecorrection
+\framed
+ [offset=overlay,
+ frameoffset=.5pt,
+ framecolor=blue,
+ rulethickness=1pt]
+ {\getbuffer}
+\stoplinecorrection
+
+This is achieved by framing the whole table:
+
+\starttyping
+\framed
+ [offset=overlay,
+ frameoffset=.5pt,
+ framecolor=blue,
+ rulethickness=1pt]
+ {...}
+\stoptyping
+
+\startbuffer
+\startuseMPgraphic{cell:innerframe}{innercolor}
+ draw OverlayBox enlarged -1.5OverlayLineWidth
+ withpen pensquare scaled OverlayLineWidth
+ withcolor \MPvar{innercolor} ;
+\stopuseMPgraphic
+
+\defineoverlay
+ [innerframe]
+ [{\uniqueMPgraphic{cell:innerframe}%
+ {innercolor=\framedparameter{innercolor}}}]
+
+\bTABLE[frame=on,framecolor=blue,rulethickness=1pt,innercolor=magenta]
+ \bTR
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD[background=innerframe] test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \eTR
+ \bTR
+ \bTD test \eTD
+ \bTD[background=innerframe,innercolor=red] test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD test \eTD
+ \bTD[background=innerframe,innercolor=green] test \eTD
+ \eTR
+\eTABLE
+\stopbuffer
+
+A \METAPOST\ alternative is also possible and it gives a bit nicer
+interface too:
+
+\typebuffer
+
+We get:
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-functions.tex b/doc/context/sources/general/manuals/metafun/metafun-functions.tex
new file mode 100644
index 000000000..780127408
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-functions.tex
@@ -0,0 +1,611 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-functions
+
+\environment metafun-environment
+
+\startchapter[title={Functions}]
+
+\index{functions}
+
+\startintro
+
+\METAPOST\ provides a wide range of functions, like \type {sind} and \type
+{floor}. We will discuss most of them here and define a few more. We will also
+introduce a few methods for drawing grids and functions.
+
+\stopintro
+
+\startsection[title={Overview}]
+
+What follows is a short overview of the functions that can be applied to numeric
+expressions and strings. Functions that operate on pairs, colors, paths and
+pictures are discussed in other chapters.
+
+First of all we have \type {+}, \type {-}, \type {/} and \type {*}. For as far as
+is reasonable, you can apply these to numerics, pairs and colors. Strings can be
+concatenated by \type {&}.
+
+Pythagorean addition is accomplished by \type {++}, while Pythagorean subtraction
+is handled by \type {+-+}. The \type {**} operator gives you exponentiation. The
+nature of the \METAPOST\ language is such that you can easily define interesting
+functions using such symbols.
+
+The logarithmic functions are based on bytes. This makes them quite accurate but
+forces you to think like a computer.
+
+\starttabulate[|lT|l|]
+\HL
+\NC mexp(x) \NC expential function with base 256 \NC \NR
+\NC mlog(x) \NC logarithm with base 256 \NC \NR
+\HL
+\stoptabulate
+
+The basic goniometric functions operate on degrees, which is why they have a
+\quote {d} in their name.
+
+\starttabulate[|lT|l|]
+\HL
+\NC cosd(x) \NC cosine of $x$ with $x$ in degrees \NC \NR
+\NC sind(x) \NC sine of $x$ with $x$ in degrees \NC \NR
+\HL
+\stoptabulate
+
+There are three ways to truncate numbers. The \type {round} function can also
+handle pairs and colors.
+
+\starttabulate[|lT|l|]
+\HL
+\NC ceiling(x) \NC the least integer greater than or equal to $x$ \NC \NR
+\NC floor(x) \NC the greatest integer less than or equal to $x$ \NC \NR
+\NC round(x) \NC round each component of $x$ to the nearest integer \NC \NR
+\HL
+\stoptabulate
+
+Of course we have:
+
+\starttabulate[|lT|l|]
+\HL
+\NC x mod y \NC the remainder of $x/y$ \NC \NR
+\NC x div y \NC the integer part of $x/y$ \NC \NR
+\NC abs(x) \NC the absolute value of $x$ \NC \NR
+\NC sqrt(x) \NC the square root of $x$ \NC \NR
+\NC x dotprod y \NC the dot product of two vectors \NC \NR
+\HL
+\stoptabulate
+
+What would life be without a certain randomness and uncertainty:
+
+\starttabulate[|lT|l|]
+\HL
+\NC normaldeviate \NC a number with mean 0 and standard deviation 1 \NC \NR
+\NC uniformdeviate(x) \NC a number between zero and $x$ \NC \NR
+\HL
+\stoptabulate
+
+The following functions are actually macros:
+
+\starttabulate[|lT|l|]
+\HL
+\NC decr(x,n) \NC decrement $x$ by $n$ \NC \NR
+\NC incr(x,n) \NC increment $x$ by $n$ \NC \NR
+\NC max(a,b,..) \NC return the maximum value in the list \NC \NR
+\NC min(a,b,..) \NC return the minimum value in the list \NC \NR
+\HL
+\stoptabulate
+
+The \type {min} and \type {max} funtions can be applied to numerics as well as
+strings.
+
+The following functions are related to strings:
+
+\starttabulate[|lT|l|]
+\HL
+\NC oct s \NC string representation of an octal number \NC \NR
+\NC hex s \NC string representation of a hexadecimal number \NC \NR
+\NC str s \NC string representation for a suffix \NC \NR
+\NC ASCII s \NC \ASCII\ value of the first character \NC \NR
+\NC char x \NC character of the given \ASCII\ code \NC \NR
+\NC decimal x \NC decimal representation of a numeric \NC \NR
+\HL
+\stoptabulate
+
+With \type {substring (i,j) of s} you can filter the substring bounded by the
+given indices from the given string.
+
+In \METAFUN\ we provide a few more functions (you can take a look in \type
+{mp-tool.mp} to see how they are defined. You need to be aware of very subtle
+rounding errors. Normally these only show up when you reverse an operation. This
+is a result from mapping to and from internal quantities.
+
+\starttabulate[|Tl|ml|]
+\HL
+\NC sqr(x) \NC x^2 \NC \NR
+\NC log(x) \NC \log(x) \NC \NR
+\NC ln(x) \NC \ln(x) \NC \NR
+\NC exp(x) \NC {\rm e}^x \NC \NR
+\NC pow(x, p) \NC x^p \NC \NR
+\NC inv(x) \NC 1/x \NC \NR
+\HL
+\stoptabulate
+
+The following sine and cosine functions take radians instead of angles in
+degrees.
+
+\starttabulate[|Tl|Tl|Tl|]
+\HL
+\NC sin(x) \NC asin(x) \NC invsin(x) \NC \NR
+\NC cos(x) \NC acos(x) \NC invcos(x) \NC \NR
+\HL
+\stoptabulate
+
+There are no tangent functions, so we provide both the radian and degrees
+versions:
+
+\starttabulate[|Tl|Tl|]
+\HL
+\NC tan(x) \NC tand(x) \NC \NR
+\NC cot(x) \NC cotd(x) \NC \NR
+\HL
+\stoptabulate
+
+Here are a couple of hyperbolic functions.
+
+\starttabulate[|Tl|Tl|]
+\HL
+\NC sinh(x) \NC asinh(x) \NC \NR
+\NC cosh(x) \NC acosh(x) \NC \NR
+\HL
+\stoptabulate
+
+We end with a few additional string converters.
+
+\starttabulate[|Tl|l|]
+\HL
+\NC ddecimal x \NC decimal representation of a pair \NC \NR
+\NC dddecimal x \NC decimal representation of a color \NC \NR
+\NC condition x \NC string representation of a boolean \NC \NR
+\HL
+\stoptabulate
+
+\stopsection
+
+\startsection[title={Grids}]
+
+\index{grids}
+\index{axis}
+
+Some day you may want to use \METAPOST\ to draw a function like graphic. In the
+regular \TEX\ distributions you will find a module \type {graph.mp} that provides
+many ways to accomplish this. For the moment, \METAFUN\ does not provide advanced
+features with respect to drawing functions, so this section will be relatively
+short.
+
+When drawing a functions (for educational purposes) we need to draw a couple of
+axis or a grid as well as a shape. Along the axis we can put labels. For this we
+can use the \METAPOST\ package \type {format.mp}, but this does not integrate
+that well into the way \METAFUN\ deals with text typeset by \TEX.
+
+For those who love dirty tricks and clever macros, close reading of the code in
+\type {format.mp} may be worthwhile. The format macros in there use \TEX\ to
+typeset the core components of a number, and use the dimensions of those
+components to compose combinations of signs, numbers and superscripts.
+
+In \METAFUN\ we have the module \type {mp-form.mp} which contains most of the
+code in \type {format.mp} but in a form that is a bit more suited for fine
+tuning. This permits us to use either the composition method, or to fall back on
+the \type {textext} method that is part of \METAFUN. That way we can also handle
+fonts that have digits with different dimensions. Another \quote {change}
+concerns the pattern separator. Instead of a \type {%} we use \type {@}; you can
+choose to set another separator, but for embedded definitions \type {%} is
+definitely a bad choice because \TEX\ sees it as a comment and ignores everything
+following it.
+
+\startbuffer[grd]
+drawoptions(withpen pencircle scaled 1pt withcolor .625yellow) ;
+
+draw hlingrid(0, 10, 1, 3cm, 3cm) ;
+draw vlingrid(0, 10, 1, 3cm, 3cm) ;
+
+draw hlingrid(0, 10, 1, 3cm, 3cm) shifted ( 3.5cm,0) ;
+draw vloggrid(0, 10, 1, 3cm, 3cm) shifted ( 3.5cm,0) ;
+
+draw hloggrid(0, 10, 1, 3cm, 3cm) shifted ( 7.0cm,0) ;
+draw vlingrid(0, 10, 1, 3cm, 3cm) shifted ( 7.0cm,0) ;
+
+draw hloggrid(0, 10, 1, 3cm, 3cm) shifted (10.5cm,0) ;
+draw vloggrid(0, 10, 1, 3cm, 3cm) shifted (10.5cm,0) ;
+\stopbuffer
+
+\typebuffer[grd]
+
+\startlinecorrection[blank]
+\processMPbuffer[grd]
+\stoplinecorrection
+
+\startbuffer[grd]
+drawoptions(withpen pencircle scaled 1pt withcolor .625yellow) ;
+
+draw hlingrid(0, 10, 1, 3cm, 3cm) slanted .5 ;
+draw vlingrid(0, 10, 1, 3cm, 3cm) slanted .5 ;
+\stopbuffer
+
+\typebuffer[grd]
+
+\startlinecorrection[blank]
+\processMPbuffer[grd]
+\stoplinecorrection
+
+Using macros like these often involves a bit of trial and error. The arguments to
+these macros are as follows:
+
+\starttyping
+hlingrid (Min, Max, Step, Length, Width)
+vlingrid (Min, Max, Step, Length, Height)
+hloggrid (Min, Max, Step, Length, Width)
+vloggrid (Min, Max, Step, Length, Height)
+\stoptyping
+
+The macros take the following text upto the semi||colon into account and return a
+picture. We will now apply this knowledge to a more meaningful example. First we
+draw a grid.
+
+You can use the grid drawing macros to produce your own paper, for instance using
+the following mixed \TEX ||\METAFUN\ code:
+
+\typebuffer[gridpage]
+
+This produces a page (as in \in {figure} [fig:gridpage]) with a metric grid. If
+you're hooked to the inch, you can set \type {unit := 1in}. If you want to
+process this code, you need to wrap it into the normal document producing
+commands:
+
+\starttyping
+\setupcolors[state=start]
+
+\starttext
+ ... definitions ...
+\stoptext
+\stoptyping
+
+\placefigure
+ [page]
+ [fig:gridpage]
+ {Quick and dirty grid paper.}
+ {\typesetfile
+ [mfun-901.tex]
+ [page=1,height=.9\textheight]}
+
+\stopsection
+
+\startsection[title={Drawing functions}]
+
+Today there are powerful tools to draw functions on grids, but for simple
+functions you can comfortably use \METAPOST. Let's first draw a simple
+log||linear grid.
+
+\startbuffer[grd]
+drawoptions(withpen pencircle scaled .25pt withcolor .5white) ;
+
+draw hlingrid (0, 20, .2, 20cm, 10cm) ;
+draw vloggrid (0, 10, .5, 10cm, 20cm) ;
+
+drawoptions(withpen pencircle scaled .50pt) ;
+
+draw hlingrid (0, 20, 1, 20cm, 10cm) ;
+draw vloggrid (0, 10, 1, 10cm, 20cm) ;
+\stopbuffer
+
+\typebuffer[grd]
+
+To this grid we add some labels:
+
+\startbuffer[txt]
+fmt_pictures := false ; % use TeX as formatting engine
+textextoffset := ExHeight ; % a variable set by ConTeXt
+
+draw hlintext.lft(0, 20, 5, 20cm, "@3e") ;
+draw vlogtext.bot(0, 10, 9, 10cm, "@3e") ;
+\stopbuffer
+
+\typebuffer[txt]
+
+The arguments to the text placement macros are similar to the ones for drawing
+the axes. Here we provide a format string.
+
+\starttyping
+hlintext (Min, Max, Step, Length, Format)
+vlintext (Min, Max, Step, Length, Format)
+hlogtext (Min, Max, Step, Length, Format)
+vlogtext (Min, Max, Step, Length, Format)
+\stoptyping
+
+When drawing a smooth function related curve, you need to provide enough sample
+points. The \type {function} macro will generate them for you, but you need to
+make sure that for instance the maximum and minimum values are part of the
+generated series of points. Also, a smooth curve is not always the right curve.
+Therefore we provide three drawing modes:
+
+\starttabulate[|cT|l|]
+\HL
+\NC \bf method \NC \bf result \NC \NR
+\HL
+\NC 1 \NC a punked curve, drawn using \type {--} \NC \NR
+\NC 2 \NC a smooth curve, drawn using \type {..} \NC \NR
+\NC 3 \NC a tight curve, drawn using \type {...} \NC \NR
+\HL
+\stoptabulate
+
+If method~2 or~3 do not give the desired outcome, you can try a smaller step
+combined with method~1.
+
+\startbuffer[log]
+draw
+ function(1,"log(x)","x",1,10,1) xyscaled (10cm,2cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,yellow) ;
+
+draw
+ function(2,".5log(x)","x",1,10,1) xyscaled (10cm,2cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,blue) ;
+\stopbuffer
+
+\typebuffer[log]
+
+\placefigure
+ [page]
+ {An example of a graphic with labels along the axes.}
+ {\doifmodeelse{screen}
+ {\scale[height=.85\textheight]{\processMPbuffer[grd,txt,log]}}
+ {\processMPbuffer[grd,txt,log]}}
+
+The first argument to the \type {function} macro specifies the drawing method.
+The last three arguments are the start value, end value and step. The second and
+third argument specify the function to be drawn. In this case the pairs \type
+{(x,x)} and \type {(.5log(x),x)} are calculated.
+
+\startbuffer[gon]
+textextoffset := ExHeight ;
+
+drawoptions(withpen pencircle scaled .50pt) ;
+
+draw hlingrid(-10, 10, 1, 10cm, 10cm) ;
+draw vlingrid( 0, 20, 1, 10cm, 20cm) shifted (0,-10cm) ;
+
+drawoptions() ;
+
+draw
+ function(2,"x","sind(x)",0,360,10) xyscaled (1cm/36,10cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,blue) ;
+
+draw
+ function(2,"x","sin(x*pi)",0,epsed(2),.1) xyscaled (10cm/2,5cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,yellow) ;
+
+draw
+ function(2,"x","cosd(x)",0,360,10) xyscaled (1cm/36,10cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,red) ;
+
+draw
+ function(2,"x","cos(x*pi)",0,epsed(2),.1) xyscaled (10cm/2,5cm)
+ withpen pencircle scaled 5mm withcolor transparent(1,.5,green) ;
+\stopbuffer
+
+\typebuffer[gon]
+
+\placefigure
+ [page]
+ {By using transparent colors, we don't have to calculate
+ and mark the common points: they already stand out.}
+ {\doifmodeelse{screen}
+ {\scale[height=.85\textheight]{\processMPbuffer[gon]}}
+ {\processMPbuffer[gon]}}
+
+In this example we draw sinus and cosine functions using degrees and radians. In
+the case of radians the end points are not calculated due to rounding errors. In
+such case you can use the \type {epsed} value, which gives slightly more
+playroom.
+
+\startbuffer[mix]
+draw function (1, "x", "sin(2x)" , 1, 10, .01) scaled 1.5cm
+ withpen pencircle scaled 1mm withcolor transparent(1,.5,red) ;
+draw function (1, "x", "sin(2x*x)" , 1, 10, .01) scaled 1.5cm
+ withpen pencircle scaled 1mm withcolor transparent(1,.5,green) ;
+draw function (1, "x", "sin(2x*x+x)", 1, 10, .01) scaled 1.5cm
+ withpen pencircle scaled 1mm withcolor transparent(1,.5,blue) ;
+\stopbuffer
+
+\typebuffer[mix]
+
+Of course you can do without a grid. The next example demonstrates a nice
+application of transparencies.
+
+\startlinecorrection[blank]
+\processMPbuffer[mix]
+\stoplinecorrection
+
+If we use the \type {exclusion} method for the transparencies, combined with no
+transparency, we get the following alternative.
+
+\startbuffer[mix]
+draw function (2, "x", "sin(x)" , 0, 2pi, pi/40) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,red) ;
+draw function (2, "x", "sin(2x)", 0, 2pi, pi/40) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,green) ;
+draw function (2, "x", "sin(3x)", 0, 2pi, pi/40) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,blue) ;
+\stopbuffer
+
+\typebuffer[mix]
+
+\startlinecorrection[blank]
+\processMPbuffer[mix,wipe]
+\stoplinecorrection
+
+The next alternative uses a larger step, and as a result (in drawing mode~2)
+gives worse results. (Without the \type {epsed} it would have looked even worse
+in the end points.
+
+ \startbuffer[mix]
+draw function (2, "x", "sin(x)" , 0, epsed(2pi), pi/10) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,red) ;
+draw function (2, "x", "sin(2x)", 0, epsed(2pi), pi/10) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,green) ;
+draw function (2, "x", "sin(3x)", 0, epsed(2pi), pi/10) scaled 2cm
+ withpen pencircle scaled 5mm withcolor transparent("exclusion",1,blue) ;
+\stopbuffer
+
+\typebuffer[mix]
+
+\startlinecorrection[blank]
+\processMPbuffer[mix,wipe]
+\stoplinecorrection
+
+There are enough applications out there to draw nice functions, like gnuplot for
+which Mojca Miklavec made a backend that works well with \CONTEXT. Nevertheless
+it can be illustrative to explore the possibilities of the \CONTEXT, \LUATEX,
+\METAPOST\ combination using functions.
+
+First of all you can use \LUA\ to make paths and this is used in some of the
+debugging and tracing options that come with \CONTEXT. For instance, if you
+process a document with
+
+\starttyping
+context --timing yourdoc.tex
+\stoptyping
+
+then you can afterwards process a file that is generated while processing this
+document:
+
+\starttyping
+context --extras timing yourdoc
+\stoptyping
+
+This will give you a document with graphics that show where \LUATEX\ spent its
+time on. Of course these graphics are generated with \METAPOST.
+
+There are a few helpers built in (and more might follow). For example:
+
+\startbuffer
+draw
+ \ctxlua {
+ metapost.metafun.topath {
+ { x=1, y=1 },
+ { x=1, y=3 },
+ { 4, 1},
+ "cycle"
+ }
+ }
+ xysized(4cm,3cm)
+ withpen pencircle scaled 1mm
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+The \type {topath} function takes a table of points or strings.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+You can pass a connector so
+
+\startbuffer
+draw
+ \ctxlua {
+ metapost.metafun.topath (
+ {
+ { x=1, y=1 },
+ { x=1, y=3 },
+ { 4, 1 },
+ "cycle"
+ },
+ "--"
+ )
+ }
+ xysized(4cm,3cm)
+ withpen pencircle scaled 1mm
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+gives:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Writing such \LUA\ functions is no big deal. For instance we have available:
+
+\starttyping
+function metapost.metafun.interpolate(f,b,e,s,c)
+ tex.write("(")
+ for i=b,e,(e-b)/s do
+ local d = loadstring (
+ string.formatters["return function(x) return %s end"](f)
+ )
+ if d then
+ d = d()
+ if i > b then
+ tex.write(c or "...")
+ end
+ tex.write(string.formatters["(%F,%F)"](i,d(i)))
+ end
+ end
+ tex.write(")")
+end
+\stoptyping
+
+An example of usage is:
+
+\startbuffer
+draw
+ \ctxlua{metapost.metafun.interpolate(
+ "math.sin(x^2+2*x+math.sqrt(math.abs(x)))",
+ -math.pi/2,math.pi/2,100
+ )}
+ xysized(6cm,3cm)
+ withpen pencircle scaled 1mm
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+And indeed we get some drawing:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Let's see what happens when we use less accuracy and a different connector:
+
+\startbuffer
+draw
+ \ctxlua{metapost.metafun.interpolate(
+ "math.sin(x^2+2*x+math.sqrt(math.abs(x)))",
+ -math.pi/2,math.pi/2,10,"--"
+ )}
+ xysized(6cm,3cm)
+ withpen pencircle scaled 1mm
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+Now we get:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Of course we could extend this \LUA\ function with all kind of options and we
+might even do that when we need it.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-gadgets.tex b/doc/context/sources/general/manuals/metafun/metafun-gadgets.tex
new file mode 100644
index 000000000..9010fc403
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-gadgets.tex
@@ -0,0 +1,548 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-gadgets
+
+\environment metafun-environment
+
+\startchapter[title={Shapes, symbols and buttons}]
+
+\startintro
+
+One can use \METAPOST\ to define symbols and enhance buttons. Here we introduce
+some of the gadgets that come with \CONTEXT, as well as explain how to integrate
+such gadgets yourself.
+
+\stopintro
+
+\startsection[title={Interfacing to \TEX}]
+
+\index {interfacing}
+
+\startbuffer[a]
+\setupMPvariables
+ [EnglishRule]
+ [height=1ex,
+ width=\availablehsize,
+ color=darkgray]
+
+\startuniqueMPgraphic{EnglishRule}{height,width,color}
+ numeric height ; height = \MPvar{height} ;
+ x1 = 0 ; x3 = \MPvar{width} ; x2 = x4 = .5x3 ;
+ y1 = y3 = 0 ; y2 := -y4 = height/2 ;
+ fill z1 .. z2 .. z3 & z3 .. z4 .. z1 & cycle
+ withcolor \MPvar{color} ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\startbuffer[b]
+\defineblank
+ [EnglishRule]
+ [medium]
+
+\unexpanded\def\EnglishRule
+ {\start
+ \dontcomplain
+ \startlinecorrection[EnglishRule]
+ \noindent \reuseMPgraphic{EnglishRule}
+ \stoplinecorrection
+ \stop}
+\stopbuffer
+
+\getbuffer[a,b]
+
+In the early days of \METAPOST\ support in \CONTEXT, Tobias Burnus asked me if it
+was possible to define English rules. What exactly does an english rule look
+like? Here is one:
+
+\EnglishRule
+
+As you can see, such a rule has to adapt itself to the current text width,
+normally \type {\hsize} in \TEX, or on request \type {\availablehsize} in
+\CONTEXT. We need to set the height to a reasonable size, related to the font
+size, and we also need to take care of proper spacing. Of course we want to run
+\METAPOST\ as less times as possible, so we need to use unique graphics. Let's
+start with the graphic.
+
+\typebuffer[a]
+
+As you can see, we pass two arguments to the graphic definition. The first
+argument is the name, the second argument is a comma separated list of variables.
+This list serves two purposes. First this list is used to create a unique profile
+for the graphic. This means that when we change the value of a variable, a new
+graphic is generated that reflects the change. A second purpose of the list is to
+convert \TEX\ data structures into \METAPOST\ ones, especially dimensions and
+colors. The graphic itself is not that spectacular. We use \type {&} because we
+don't want smooth connections.
+
+\typebuffer[b]
+
+When setting the variables, we used \type {\availablehsize}. We need to use \type
+{\noindent}, a rather familiar \TEX\ primitive, that we use here to start a non
+indented paragraph, being the graphic. The line correction is needed to get the
+spacing around the rule (graphic) right. We pass a blank skip identifier that is
+mapped to a convenient medium skip.
+
+\startbuffer[c]
+Why is this called an English line?
+
+\startnarrower
+ \EnglishRule
+ Is it because they cannot draw a straight one? This could be true
+ after a few strong beers, but then, how do Germans draw a line?
+ \EnglishRule
+\stopnarrower
+\stopbuffer
+
+\typebuffer[c]
+
+As expected, the rule adapts itself to the current width of the text. The height
+of the rule in the middle matches the height of a character with no ascenders and
+descenders.
+
+\getbuffer[c]
+
+\stopsection
+
+\startsection[title={Random graphics}]
+
+\index{randomization}
+
+\startbuffer[a]
+\startuseMPgraphic{fuzzycount}
+ begingroup
+ save height, vstep, hsize, span, drift, d, cp ;
+ height := 3/ 4 * \the \bodyfontsize * \currentfontscale ;
+ span := 1/ 3 * height ;
+ drift := 1/10 * height ;
+ hsize := \the\hsize ;
+ vstep := \the\lineheight ;
+ xmax := hsize div 5span ;
+ pickup pencircle scaled (1/12 * height) ;
+ def d = (uniformdeviate drift) enddef ;
+ for i := 1 upto \MPvar{n} :
+ xpos := ((i-1) mod (5*xmax))*span ;
+ ypos := ((i-1) div (5*xmax))*vstep ;
+ draw
+ if (i mod 5)=0 : ((-d-4.5span,d)--(+d-0.5span,height-d))
+ else : ((-d,+d)--(+d,height-d)) fi
+ shifted (xpos,-ypos+d-drift) ;
+ endfor;
+ picture cp ; cp := currentpicture ;
+ if (ypart ulcorner cp - ypart llcorner cp) <= vstep :
+ setbounds currentpicture to
+ (llcorner cp shifted (0,-ypart llcorner cp) --
+ lrcorner cp shifted (0,-ypart lrcorner cp) --
+ urcorner cp -- ulcorner cp -- cycle) ;
+ fi
+ endgroup ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[b]
+\useMPgraphic{fuzzycount}{n=1001}
+\stopbuffer
+
+Given enough time and paper, we can probably give you some
+
+\startlinecorrection[blank]
+\getbuffer[a,b]
+\stoplinecorrection
+
+reasons why \METAPOST\ is fun. To mention a few: you can enhance the layout with
+graphic ornaments, you can tune your graphics at runtime, and simple high quality
+graphics can be very effective.
+
+\startbuffer[c]
+\startuseMPgraphic{fuzzycount}
+ begingroup
+ save height, span, drift, d, cp ;
+ height := 3/ 5 * \baselinedistance ;
+ span := 1/ 3 * height ;
+ drift := 1/10 * height ;
+ pickup pencircle scaled (1/12 * height) ;
+ def d = (uniformdeviate drift) enddef ;
+ for i := 1 upto \MPvar{n} :
+ draw
+ if (i mod 5)=0 : ((-d-4.5span,d)--(+d-0.5span,height-d))
+ else : ((-d,+d)--(+d,height-d)) fi
+ shifted (span*i,d-drift) ;
+ endfor;
+ picture cp ; cp := currentpicture ; % for readability
+ setbounds currentpicture to
+ (llcorner cp shifted (0,-ypart llcorner cp) --
+ lrcorner cp shifted (0,-ypart lrcorner cp) --
+ urcorner cp -- ulcorner cp -- cycle) ;
+ endgroup ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[d]
+\setupMPvariables[fuzzycount][n=10]
+\stopbuffer
+
+\getbuffer[c,d]
+
+The previous graphics draws exactly 1001 lines in a scratch||numbers||in||a||wall
+fashion. In 1998, the \NTG\ did a survey among its members, and in the report, we
+used this fuzzy counter to enhance the rather dull tables.
+
+\startbuffer
+\starttabulate[|l|c|l|]
+\HL
+\NC system \NC \% \NC \# users \NC\NR
+\HL
+\NC Atari \NC 10.4 \NC \useMPgraphic{fuzzycount}{n=11} \NC\NR
+\NC MSDOS \NC 49.1 \NC \useMPgraphic{fuzzycount}{n=52} \NC\NR
+\NC OS/2 \NC ~9.4 \NC \useMPgraphic{fuzzycount}{n=10} \NC\NR
+\NC MacOS \NC ~5.7 \NC \useMPgraphic{fuzzycount}{n= 6} \NC\NR
+\NC UNIX \NC 51.9 \NC \useMPgraphic{fuzzycount}{n=55} \NC\NR
+\NC WINDOWS \NC 64.2 \NC \useMPgraphic{fuzzycount}{n=68} \NC\NR
+\HL
+\stoptabulate
+\stopbuffer
+
+\placetable
+ [here][tab:fuzzy]
+ {Operating system (n=106).}{\getbuffer}
+
+\in {Table} [tab:fuzzy] demonstrates how scratch numbers can be used. An
+interesting side effect is that when you look long enough to these kind of
+graphics, it looks like the lines are no longer horizontal. This table is defined
+as follows:
+
+\typebuffer
+
+You will notice that we pass a variable to the graphic using a second argument.
+We can access this variable with \type {\MPvar}. The graphic is defined as usable
+graphic, because we want to generate a unique random one each time.
+
+\typebuffer[c]
+
+The core of the macro is the \type {for} loop. Within this loop, we draw groups
+of four plus one lines. The draw path's look a bit complicated, but this has to
+do with the fact that a \type {mod} returns $0-4$ while we like to deal with
+$1-5$.
+
+The height adapts itself to the height of the line. The bounding box correction
+at the end ensures that the baseline is consistent and that the random vertical
+offsets fall below the baseline.
+
+Because we want to be sure that \type {n} has a value, we preset it by saying:
+
+\typebuffer[d]
+
+In the table, it makes sense to adapt the drawing to the lineheight, but a more
+general solution is to adapt the height to the fontsize.
+
+\starttyping
+height := 3/ 4 * \the \bodyfontsize * \currentfontscale ;
+\stoptyping
+
+\getbuffer[a]
+
+In the table we called the graphic directly, but how about making it available as
+a conversion macro? In \CONTEXT\ this is not that hard:
+
+\startbuffer
+\def\fuzzycount#1{{\tx\useMPgraphic{fuzzycount}{n=#1}}}
+\defineconversion[fuzzy][\fuzzycount]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Because such a counter should not be that large, we use \type {\tx} to switch to
+a smaller font. This also demonstrates how the graphic adapts itself to the font
+size.
+
+We can now use this conversion for instance in an itemize. To save space we use
+three columns and no white space between the lines. The \type {2*broad} directive
+makes sure that we have enough room for the number.
+
+\startbuffer
+\startitemize[fuzzy,pack,2*broad,columns,three]
+\item one \item two \item three
+\item four \item five \item six
+\item seven \item eight \item nine
+\stopitemize
+\stopbuffer
+
+\getbuffer
+
+\typebuffer
+
+A careful reader will have noticed that the previous definition of the fuzzy
+counter drawing is not suited to generate the graphics we started with.
+
+\typebuffer[b]
+
+This time we want to limit the width to the current \type {\hsize}. We only need
+to add a few lines of code. Watch how we don't recalculate the bounding box when
+more lines are used.
+
+\typebuffer[a]
+
+\stopsection
+
+\startsection[title={Graphic variables}]
+
+\index{graphics+variables}
+\index{variables}
+
+In the previous sections we have seen that we can pass information to the graphic
+by means of variables. How exactly does this mechanism work?
+
+\startbuffer[def]
+\setupMPvariables[smile][type=1,height=1.25ex,color=darkred]
+
+\startuniqueMPgraphic{smile}{type,height,color}
+ numeric size ; size := \MPvar{height} ;
+ drawoptions(withcolor \MPvar{color}) ;
+ pickup pencircle xscaled (size/6) yscaled (size/12) ;
+ draw halfcircle rotated -90 scaled size ;
+ pickup pencircle scaled (size/4) ;
+ if \MPvar{type}=1 :
+ for i=-1,+1 : draw origin shifted (0,i*size/4) ; endfor ;
+ elseif \MPvar{type}=2 :
+ for i=-1,+1 : draw origin shifted (-size/2,i*size/4) ; endfor ;
+ pickup pencircle scaled (size/6) ;
+ draw (size/4,0) -- (-size/4,0) ;
+ fi ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\startbuffer[sym]
+\definesymbol[smile] [\uniqueMPgraphic{smile}{type=1}]
+\definesymbol[smilemore][\uniqueMPgraphic{smile}{type=2}]
+\stopbuffer
+
+\startbuffer[exa]
+Say it with a \symbol [smile]\ or maybe even a \symbol
+[smilemore], although seeing too many \dorecurse {10}
+{\symbol [smile]\ } \unskip in one text may make you cry.
+\stopbuffer
+
+\getbuffer[def,sym]
+
+A nice application of setting up variables for a specific graphic (or class of
+graphics) is the following. In an email message the author can express his own or
+the readers expected emotions with so called smilies like: \symbol [smile]. If
+you want them in print, you can revert to combinations of characters in a font,
+but as a \TEX\ user you may want to include nicer graphics.
+
+A convenient way to implement these is to make them into symbols, one reason
+being that in that case they will adapt themselves to the current font size.
+
+\typebuffer[exa] \getbuffer[exa]
+
+Because we want an efficient implementation, we will use unique graphics, because
+these will only be generated when the circumstances change.
+
+\typebuffer[sym]
+
+The definition itself then becomes:
+
+\typebuffer[def]
+
+We can now change some characteristics of the smilies without the need to
+redefine the graphic.
+
+\startbuffer[set]
+\setupMPvariables[smile][height=1ex,color=darkred]
+\stopbuffer
+
+\typebuffer[set]
+
+\getbuffer[set,exa]
+
+In order to keep the smilies unique there is some magic involved, watch the
+second argument in the next line:
+
+\starttyping
+\startuniqueMPgraphic{smile}{type,height,color}
+\stoptyping
+
+Because unique graphics often are used in backgrounds, its uniqueness is
+determined by the overlay characteristics. In our case however the uniqueness is
+determined by the smilies type, height and color. By explicitly specifying these,
+we make sure that they count in the creation of the uniqueness stamp.
+
+\startbuffer[exa]
+\midaligned{\switchtobodyfont[60pt]\symbol[smile]}
+\stopbuffer
+
+\typebuffer[exa]
+
+Because we use the ex||height, the previous call works as expected.
+
+\startlinecorrection[blank]
+\getbuffer[exa]
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Shape libraries}]
+
+\index{graphics+libraries}
+
+Unfortunately it takes some effort to define graphics, attach them to an overlay,
+and invoke the background. However, the good news is that since in many cases we
+want a consistent layout, we only have to do it once. The next table has some
+hashed backgrounds. (More information about how to define tables can be found in
+the \CONTEXT\ documentation and Up||To||Date documents.)
+
+\startbuffer
+\bTABLE[frame=off,meta:hash:linecolor=darkyellow,offset=3ex]
+ \bTR
+ \bTD[background=meta:hash:right] right \eTD
+ \bTD[background=meta:hash:left] left \eTD
+ \bTD[background=meta:hash:horizontal] horizontal \eTD
+ \bTD[background=meta:hash:vertical] vertical \eTD
+ \eTR
+\eTABLE
+\stopbuffer
+
+\getbuffer[shape-a,shape-b,shape-c]
+
+\placetable
+ {A hashed table.}
+ {\getbuffer}
+
+This table is defined as:
+
+\typebuffer
+
+The graphics themselves are defined in a \METAPOST\ module. In this particular
+example, the macro \type {some_hash} is defined in the file \type {mp-back.mp}.
+This macro takes six arguments:
+
+\starttyping
+some_hash (width, height, linewidth, linecolor, angle, gap) ;
+\stoptyping
+
+Because we don't want to define a specific overlay for each color and linewidth,
+we will use variables in the definition of the unique graphic.
+
+\typebuffer[shape-a]
+
+These variables are preset using \type {\setupMPvariables}:
+
+\typebuffer[shape-b]
+
+The last step in this process is to define the different
+alternatives as overlays:
+
+\typebuffer[shape-c]
+
+As we can see in the definition of the table, we can pass settings to the \type
+{\bTABLE} command. Actually, we can pass such settings to each command that
+supports backgrounds, or more precisely \type {\framed}. \in {Table} [tab:hashes]
+is for instance defined as:
+
+\startbuffer
+\bTABLE[frame=off,meta:hash:linewidth=.4pt,align=middle,offset=2ex]
+ \bTR
+ \bTD[background={meta:hash:left,meta:hash:right},
+ meta:hash:linecolor=darkyellow]
+ left \par \& \par right \eTD
+ \bTD[background={meta:hash:horizontal,meta:hash:vertical},
+ meta:hash:linecolor=darkred]
+ horizontal \par \& \par vertical \eTD
+ \eTR
+\eTABLE
+\stopbuffer
+
+\typebuffer
+
+The long names are somewhat cumbersome, but in that way we can prevent name
+clashes. Also, since the \METAPOST\ interface is english, the variables are also
+english.
+
+\placetable
+ [here][tab:hashes]
+ {A double hashed table.}
+ {\getbuffer}
+
+\stopsection
+
+\startsection[title={Symbol collections}]
+
+\index{graphics+symbols}
+\index{symbols}
+
+In \CONTEXT, a symbol can be defined without much coding. The advantage of using
+symbols is that you can redefine them depending on the situation. So,
+
+\starttyping
+\definesymbol [yes] [\em Yes!]
+\stoptyping
+
+creates a symbol, that lets \type {\symbol[yes]} expand into {\em Yes!} Since
+nearly anything can be a symbol, we can also say:
+
+\starttyping
+\definesymbol [yes] [\mathematics{\star}]
+\stoptyping
+
+or even the already defined symbol \symbol[star], by saying:
+
+\starttyping
+\definesymbol [yes] [{\symbol[star]}]
+\stoptyping
+
+It may be clear that we can use a graphic as well:
+
+\typebuffer[symb-c]
+
+Since we have collected some nice buttons in a \METAPOST\ file already, we can
+use a rather simple definition:
+
+\typebuffer[symb-a]
+
+This leaves a few settings:
+
+\typebuffer[symb-b]
+
+These symbols are collected in \in {table} [tab:symbols], and are called up with
+the \CONTEXT\ commands like \type {\symbol[menu:left]}. If needed, we can collect
+these button symbols in a so called symbol set, which permits us to instantly
+switch between sets with similar symbols.
+
+\startbuffer
+\bTABLE[frame=off,width=36pt,align=middle]
+ \bTR \bTD \dontleavehmode \symbol[menu:left] \eTD
+ \bTD \dontleavehmode \symbol[menu:right] \eTD
+ \bTD \dontleavehmode \symbol[menu:list] \eTD
+ \bTD \dontleavehmode \symbol[menu:index] \eTD
+ \bTD \dontleavehmode \symbol[menu:person] \eTD
+ \bTD \dontleavehmode \symbol[menu:stop] \eTD
+ \bTD \dontleavehmode \symbol[menu:info] \eTD
+ \bTD \dontleavehmode \symbol[menu:down] \eTD
+ \bTD \dontleavehmode \symbol[menu:up] \eTD
+ \bTD \dontleavehmode \symbol[menu:print] \eTD \eTR
+ \bTR \bTD left \eTD
+ \bTD right \eTD
+ \bTD list \eTD
+ \bTD index \eTD
+ \bTD person \eTD
+ \bTD stop \eTD
+ \bTD info \eTD
+ \bTD down \eTD
+ \bTD up \eTD
+ \bTD print \eTD \eTR
+\eTABLE
+\stopbuffer
+
+\getbuffer[symb-a,symb-b,symb-c]
+
+\placetable
+ [here][tab:symbols]
+ {A collection of button symbols.}
+ {\getbuffer}
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-graphics.tex b/doc/context/sources/general/manuals/metafun/metafun-graphics.tex
new file mode 100644
index 000000000..79c5df0df
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-graphics.tex
@@ -0,0 +1,21 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-graphics
+
+\environment metafun-environment
+
+\startchapter[title={Example graphics}]
+
+\startintro
+
+In this chapter we will show some of the graphics that we made the last few years
+using \METAPOST. They give an impression of what kind of non||mathematical
+drawings can be made.
+
+\stopintro
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-index.tex b/doc/context/sources/general/manuals/metafun/metafun-index.tex
new file mode 100644
index 000000000..8be313d85
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-index.tex
@@ -0,0 +1,25 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-index
+
+\environment metafun-environment
+
+\startchapter[reference=index,title={Index}]
+
+ \startcolumns
+ \placeregister[index]
+ \stopcolumns
+
+\stopchapter
+
+% \startchapter[reference=commands,title={Commands}]
+%
+% \startcolumns
+% \placeregister[command]
+% \stopcolumns
+%
+% \stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-introduction.tex b/doc/context/sources/general/manuals/metafun/metafun-introduction.tex
new file mode 100644
index 000000000..b519055c0
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-introduction.tex
@@ -0,0 +1,101 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-introduction
+
+\environment metafun-environment
+
+\starttitle[title={Introduction}]
+
+This document is about \METAPOST\ and \TEX. The former is a graphic programming
+language, the latter a typographic programming language. However, in this
+document we will not focus on real programming, but more on how we can interface
+between those two languages. We will do so by using \CONTEXT, a macro package
+written in \TEX, in which support for \METAPOST\ is integrated in the core. The
+\TEX\ macros are integrated in \CONTEXT, and the \METAPOST\ macros are bundled in
+\METAFUN.
+
+When Donald Knuth wrote his typographical programming language \TEX\ he was in
+need for fonts, especially mathematical fonts. So, as a side track, he started
+writing \METAFONT, a graphical language. When you read between the lines in the
+\METAFONT\ book and the source code, the name John Hobby is mentioned alongside
+complicated formulas. It will be no surprise then, that, since he was tightly
+involved in the development of \METAFONT, after a few years his \METAPOST\ showed
+up.
+
+While its ancestor \METAFONT\ was originally targeted at designing fonts,
+\METAPOST\ is more oriented to drawing graphics as used in scientific
+publications. Since \METAFONT\ produced bitmap output, some of its operators make
+use of this fact. \METAPOST\ on the other hand produces \POSTSCRIPT\ code, which
+means that it has some features not present in \METAFONT\ and vice versa.
+
+With \METAFUN\ I will demonstrate that \METAPOST\ can also be used, or misused,
+for less technical drawing purposes. We will see that \METAPOST\ can fill in some
+gaps in \TEX, especially its lack of graphic capabilities. We will demonstrate
+that graphics can make a document more attractive, even if it is processed in a
+batch processing system like \TEX. Most of all, we will see that embedding
+\METAPOST\ definitions in the \TEX\ source enables a smooth communication between
+both programs.
+
+The best starting point for using \METAPOST\ is the manual written by its author
+John Hobby. You can find this manual at every main \TEX\ repository. Also, a copy
+of the \METAFONT\ book from Donald Knuth is worth every cent, if only because it
+will give you the feeling that many years of graphical fun lays ahead.
+
+In this \METAFUN\ manual we will demonstrate how you can embed graphics in a
+\TEX\ document, but we will also introduce most of the features of \METAPOST. For
+this reason you will see a lot of \METAPOST\ code. For sure there are better
+methods to solve problems, but I have tried to demonstrate different methods and
+techniques as much as possible.
+
+I started using \METAPOST\ long after I started using \TEX, and I never regret
+it. Although I like \TEX\ very much, I must admit that sometimes using \METAPOST\
+is even more fun. Therefore, before we start exploring both in depth, I want to
+thank their creators, Donald Knuth and John Hobby, for providing me these
+fabulous tools. Of course I also need to thank \THANH, for giving the \TEX\
+community \PDFTEX, as well as providing me the hooks I considered necessary for
+implementing some of the features presented here. In the meantime Taco Hoekwater
+has created the \METAPOST\ library so that it can be an integral component of
+\LUATEX. After that happened, the program was extended to deal with more than one
+number implementation: in addition to scaled integers we now can switch to floats
+and arbitrary precision decimal or binary calculations. I myself prototyped a
+simple but efficient \LUA\ script interface. With Luigi Scarso, who is now the
+maintainer of \METAPOST, we keep improving the system, so who knows what will
+show up next.
+
+I also want to thank David Arnold and Ton Otten for their fast proofreading, for
+providing me useful input, and for testing the examples. Without David's patience
+and help, this document would be far from perfect English and less complete.
+Without Ton's help, many small typos would have gone unnoticed.
+
+In the second version of this manual the content was been adapted to \CONTEXT\
+\MKIV\ that uses \LUATEX\ and the built in \METAPOST\ library. In the meantime
+some \LUA\ has been brought into the game, not only to help construct graphics,
+but also as a communication channel. In the process some extra features have been
+added and some interfacing has been upgraded. The third version of this document
+deals with that too. It makes no sense to maintain compatibility with \CONTEXT\
+\MKII, but many examples can be used there as well. In the meantime most
+\CONTEXT\ users have switched to \MKIV, so this is no real issue. In the fourth
+update some new features are presented and the discussion of obsolete ones have
+been removed.
+
+The fifth update describes the \MPIV\ version of \METAFUN\ which brings some more
+and improved functionality. Some examples are inspired from questions by users and
+examples that Alan Braslau, Luigi Scarso and I made when testing new features and
+macros. Some examples can be rewritten in a more efficient way but are kept as
+they are. Therefore this manual presents different ways to solve problems.
+Hopefully this is not too confusing. Numerous examples can be found in the other
+manuals and test suite.
+
+\blank[big,samepage]
+
+\startlines
+Hans Hagen
+Hasselt NL
+\currentdate[month,year]
+\stoplines
+
+\stoptitle
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-layout.tex b/doc/context/sources/general/manuals/metafun/metafun-layout.tex
new file mode 100644
index 000000000..2be7e19ff
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-layout.tex
@@ -0,0 +1,990 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-layout
+
+\environment metafun-environment
+
+\startchapter[title={Enhancing the layout}]
+
+\startintro
+
+One of the most powerful and flexible commands of \CONTEXT\ is \type {\framed}.
+We can use the background features of this command to invoke and position
+graphics that adapt themselves to the current situation. Once understood,
+overlays will become a natural part of the \CONTEXT\ users toolkit.
+
+\stopintro
+
+\startsection[title={Overlays}]
+
+\index{overlays}
+
+Many \CONTEXT\ commands support overlays. The term {\em overlay} is a bit
+confusing, since such an overlay in most cases will lay under the text. However,
+because there can be many layers on top of each other, the term suits its
+purpose.
+
+When we want to put a \METAPOST\ graphic under some text, we go through a three
+step process. First we define the graphic itself:
+
+\startbuffer
+\startuniqueMPgraphic{demo circle}
+ path p ;
+ p := fullcircle xscaled \overlaywidth yscaled \overlayheight ;
+ fill p withcolor .85white ;
+ draw p withpen pencircle scaled 2pt withcolor .625red ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+This graphic will adapt itself to the width and height of the overlay. Both \type
+{\overlaywidth} and \type {\overlayheight} are macros that return a dimension
+followed by a space. The next step is to register this graphic as an overlay.
+
+\startbuffer
+\defineoverlay[demo circle][\uniqueMPgraphic{demo circle}]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+We can now use this overlay in any command that provides the \type {\framed}
+functionality. Since this graphic is defined as unique, \CONTEXT\ will try to
+reuse already calculated and embedded graphics when possible.
+
+\startbuffer
+\framed[background=demo circle]{This text is overlayed.}
+\stopbuffer
+
+\typebuffer
+
+The background can be set to \type {color}, \type {screen}, an overlay
+identifier, like \typ {demo circle}, or a comma separated list of those.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+The \type {\framed} command automatically draws a ruled box, which can be quite
+useful when debugging a graphic. However, in this case we want to turn the frame
+off.
+
+\startbuffer
+\framed
+ [background=demo circle,frame=off]
+ {This text is overlayed.}
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+In this case, it would have made sense to either set the \type {offset} to a
+larger value, or to set \type {backgroundoffset}. In the latter case, the ellipse
+is positioned outside the frame.
+
+The difference between the three offsets \type {offset}, \type {frameoffset} and
+\type {backgroundoffset} is demonstrated in \in {figure} [fig:offsets]. While the
+\type {offset} is added to the (natural or specified) dimensions of the content
+of the box, the other two are applied to the frame and background and don't add
+to the dimensions.
+
+In the first row we only set the \type {offset}, while in the second row, the
+(text) offset is set to \type {3pt}. When not specified, the \type {offset} has a
+comfortable default value of \type {.25ex} (some 25\% of the height of an~x).
+
+\startbuffer
+\setupframed
+ [width=.3\textwidth,
+ background=demo circle]
+\startcombination[3*3]
+ {\framed[offset=none] {\TeX}} {\tt offset=none}
+ {\framed[offset=overlay] {\TeX}} {\tt offset=overlay}
+ {\framed[offset=0pt] {\TeX}} {\tt offset=0pt}
+ {\framed[offset=1pt] {\TeX}} {\tt offset=1pt}
+ {\framed[offset=2pt] {\TeX}} {\tt offset=2pt}
+ {\framed[offset=4pt] {\TeX}} {\tt offset=4pt}
+ {\framed[offset=3pt] {\TeX}} {\tt offset=3pt}
+ {\framed[frameoffset=3pt] {\TeX}} {\tt frameoffset=3pt}
+ {\framed[backgroundoffset=3pt]{\TeX}} {\tt backgroundoffset=3pt}
+\stopcombination
+\stopbuffer
+
+\typebuffer
+
+\placefigure
+ [here][fig:offsets]
+ {The three offsets.}
+ {\getbuffer}
+
+As the first row in \in {figure} [fig:offsets] demonstrates, instead of a value,
+one can pass a keyword. The \type {overlay} keyword implies that there is no
+offset at all and that the lines cover the content. With \type {none} the frame
+is drawn tight around the content. When the offset is set to \type {0pt} or more,
+the text is automatically set to at least the height of a line. You can turn this
+feature off by saying \type {strut=off}. More details can be found in the
+\CONTEXT\ manual.
+
+In \in {figure} [fig:all offsets] we have set {offset} to \type {3pt}, \type
+{frameoffset} to \type {6pt} and \type {backgroundoffset} to \type {9pt}. Both
+the frame and background offset are sort of imaginary, since they don't
+contribute to the size of the box.
+
+\startbuffer
+\ruledhbox
+ {\framed
+ [offset=3pt,frameoffset=6pt,backgroundoffset=9pt,
+ background=screen,backgroundscreen=.85]
+ {Welcome in the hall of frame!}}
+\stopbuffer
+
+\typebuffer
+
+\placefigure
+ [here][fig:all offsets]
+ {The three offsets.}
+ {\getbuffer}
+
+\stopsection
+
+\startsection[title={Overlay variables}]
+
+The communication between \TEX\ and embedded \METAPOST\ graphics takes place by
+means of some macros.
+
+\starttabulate[|l|p|]
+\HL
+\NC overlay status macro \NC meaning \NC \NR
+\HL
+\NC \tex {overlaywidth} \NC the width of the graphic, as
+ calculated from the actual
+ width and background offset \NC \NR
+\NC \tex {overlayheight} \NC the height of the graphic, as
+ calculated from the actual
+ height, depth and background
+ offset \NC \NR
+\NC \tex {overlaydepth} \NC the depth of the graphic, if
+ available \NC \NR
+\NC \tex {overlaycolor} \NC the background color, if given \NC \NR
+\NC \tex {overlaylinecolor} \NC the color of the frame \NC \NR
+\NC \tex {overlaylinewidth} \NC the width of the frame \NC \NR
+\HL
+\stoptabulate
+
+The dimensions of the overlay are determined by dimensions of the background,
+which normally is the natural size of a \type {\framed}. When a background offset
+is specified, it is added to \type {overlayheight} and \type {overlaywidth}.
+
+Colors can be converted by \type {\MPcolor} and in addition to the macros
+mentioned, you can use all macros that expand into a dimension or dimen register
+prefixed by the \TEX\ primitive \type {\the} (this and other primitives are
+explained in \quotation {The \TeX book}, by Donald Knuth).
+
+\stopsection
+
+\startsection[title={Stacking overlays}]
+
+A background can be a gray scale (\type {screen}), a color (\type {color}), a
+previously defined overlay identifier, or any combination of these. The next
+assignments are therefore valid:
+
+\starttyping
+\framed[background=color,backgroundcolor=red]{...}
+\framed[background=screen,backgroundscreen=.8]{...}
+\framed[background=circle]{...}
+\framed[background={color,cow},backgroundcolor=red]{...}
+\framed[background={color,cow,grid},backgroundcolor=red]{...}
+\stoptyping
+
+In the last three cases of course you have to define \type {circle}, \type {cow}
+and \type {grid} as overlay. These items are packed in a comma separated list,
+which has to be surrounded by \type {{}}.
+
+\stopsection
+
+\startsection[title={Foregrounds}]
+
+\startbuffer[a]
+\startuniqueMPgraphic{backfore}
+ draw fullcircle
+ xscaled \overlaywidth yscaled \overlayheight
+ withpen pencircle scaled 2pt
+ withcolor .625yellow ;
+\stopuniqueMPgraphic
+
+\defineoverlay[backfore][\uniqueMPgraphic{backfore}]
+\stopbuffer
+
+\startbuffer[b]
+\framed
+ [background=backfore,backgroundoffset=4pt]
+ {one, two, three, \unknown}
+\stopbuffer
+
+\startbuffer[c]
+\framed
+ [background={foreground,backfore},backgroundoffset=4pt]
+ {one, two, three, \unknown}
+\stopbuffer
+
+The overlay system is actually a system of layers. Sometimes we are confronted
+with a situation in which we want the text behind another layer. This can be
+achieved by explicitly placing the foreground layer, as in \in {figure}
+[fig:foreground].
+
+\getbuffer[a]
+
+\placefigure
+ [here][fig:foreground]
+ {Foreground material moved backwards.}
+ {\setupframed[linewidth=1pt]%
+ \startcombination
+ {\getbuffer[b]} {frame on top layer}
+ {\getbuffer[c]} {frame on bottom layer}
+ \stopcombination}
+
+The graphic layer is defined as follows:
+
+\typebuffer[a]
+
+The two framed texts have a slightly different definition. The leftmost graphic
+is defined as:
+
+\typebuffer[b]
+
+The rightmost graphic is specified as:
+
+\typebuffer[c]
+
+The current values of the frame color and frame width are passed to the overlay.
+It often makes more sense to use colors defined at the document level, if only to
+force consistency.
+
+\startbuffer
+\startuniqueMPgraphic{super ellipse}
+ path p ; p := unitsquare
+ xscaled \overlaywidth yscaled \overlayheight
+ superellipsed .85 ;
+ pickup pencircle scaled \overlaylinewidth ;
+ fill p withcolor \MPcolor{\overlaycolor} ;
+ draw p withcolor \MPcolor{\overlaylinecolor} ;
+\stopuniqueMPgraphic
+
+\defineoverlay[super ellipse][\uniqueMPgraphic{super ellipse}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This background demonstrates that a super ellipse is rather well suited as frame.
+
+\startbuffer
+\framed
+ [background=super ellipse,
+ frame=off,
+ width=3cm,
+ align=middle,
+ framecolor=darkyellow,
+ rulethickness=2pt,
+ backgroundcolor=darkgray]
+ {\white This is a\\Super Ellipsed\\sentence.}
+\stopbuffer
+
+\typebuffer
+
+Such a super ellipse looks quite nice and is a good candidate for backgrounds,
+for which the superness should be at least~.85.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Typesetting graphics}]
+
+I have run into people who consider it kind of strange when you want to use \TEX\
+for non||mathematical typesetting. If you agree with them, you may skip this
+section with your eyes closed.
+
+One of the \CONTEXT\ presentation styles (number 15, tagged as balls) stepwise
+builds screens full of sentences, quotes or concepts, packages in balloons and
+typesets them as a paragraph. We will demonstrate that \TEX\ can typeset graphics
+using the following statement.
+
+% \let\processword\relax
+
+\startbuffer[lions]
+\processwords{As you may know, \TEX's ambassador is a lion, while {\METAFONT}
+is represented by a lioness. It is still unclear if they have a relationship,
+but if so, and if a cub is born, may it enjoy \METAFUN.}
+\stopbuffer
+
+\startquotation
+\def\processwords#1{#1}\getbuffer[lions]
+\stopquotation
+
+The low level \CONTEXT\ macro \type {\processwords} provides a mechanism to treat
+the individual words of its argument. The macro is called as follows:
+
+\typebuffer[lions]
+
+In order to perform a task, you should also define a macro \type {\processword},
+which takes one argument. The previous quote was typeset with the following
+definition in place:
+
+\starttyping
+\def\processword#1{#1}
+\stoptyping
+
+A slightly more complicated definition is the following:
+
+\startbuffer
+\def\processword#1{\noindent\framed{#1}\space}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We now get:
+
+\blank\getbuffer[lions]\blank
+
+If we can use \type {\framed}, we can also use backgrounds.
+
+\startbuffer
+\def\processword#1%
+ {\noindent\framed[frame=off,background=lions]{#1} }
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We can add a supperellipsed frame using the following definition:
+
+\startbuffer
+\startuniqueMPgraphic{lions a}
+ path p ; p := fullsquare
+ xyscaled (\overlaywidth,\overlayheight) superellipsed .85 ;
+ pickup pencircle scaled 1pt ;
+ fill p withcolor .850white ; draw p withcolor .625yellow ;
+\stopuniqueMPgraphic
+
+\defineoverlay[lions][\uniqueMPgraphic{lions a}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\bgroup \blank \veryraggedright\getbuffer[lions]\unskip \blank \egroup
+
+\startbuffer
+\startuseMPgraphic{lions b}
+ path p ; p := fullsquare
+ xyscaled (\overlaywidth,\overlayheight) randomized 5pt ;
+ pickup pencircle scaled 1pt ;
+ fill p withcolor .850white ; draw p withcolor .625yellow ;
+\stopuseMPgraphic
+
+\defineoverlay[lions][\uniqueMPgraphic{lions b}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\bgroup \blank \veryraggedcenter\getbuffer[lions]\unskip \blank \egroup
+
+\startbuffer
+\startuniqueMPgraphic{lions c}
+ path p ; p := fullsquare
+ xyscaled (\overlaywidth,\overlayheight) squeezed 2pt ;
+ pickup pencircle scaled 1pt ;
+ fill p withcolor .850white ; draw p withcolor .625yellow ;
+\stopuniqueMPgraphic
+
+\defineoverlay[lions][\uniqueMPgraphic{lions c}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\bgroup \blank \veryraggedleft\getbuffer[lions]\unskip \blank \egroup
+
+These paragraphs were typeset with the following settings.
+
+\starttyping
+\setupalign[broad, right] % == \veryraggedright
+\setupalign[broad, middle] % == \veryraggedcenter
+\setupalign[broad, left] % == \veryraggedleft
+\stoptyping
+
+The \type {broad} increases the raggedness. We defined three different graphics
+(a, b and c) because we want some to be unique, which saves some processing. Of
+course we don't reuse the random graphics. In the definition of \type
+{\processword} we have to use \type {\noindent} because otherwise \TEX\ will put
+each graphic on a line of its own. Watch the space at the end of the macro.
+
+\stopsection
+
+\startsection[title={Graphics and macros}]
+
+Because \TEX's typographic engine and \METAPOST's graphic engine are separated,
+interfacing between them is not as natural as you may expect. In \CONTEXT\ we
+have tried to integrate them as much as possible, but using the interface is not
+always as convenient as it should be. What method you follow, depends on the
+problem at hand.
+
+The official \METAPOST\ way to embed \TEX\ code into graphics is to use \typ
+{btex ... etex}. As soon as \CONTEXT\ writes the graphic data to the intermediate
+\METAPOST\ file, it looks for these commands. When it has encountered an \type
+{etex}, \CONTEXT\ will make sure that the text that is to be typeset by \TEX\ is
+{\em not} expanded. This is what you may expect, because when you would embed
+those commands in a stand||alone graphic, they would also not be expanded, if
+only because \METAPOST\ does not know \TEX. With expansion we mean that \TEX\
+commands are replaced by their meaning (which can be quite extensive).
+
+{\em Users of \CONTEXT\ MKIV\ can skip the next paragraph}.
+
+When \METAPOST\ sees a \type {btex} command, it will consult a so called \type
+{mpx} file. This file holds the \METAPOST\ representation of the text typeset by
+\TEX. Before \METAPOST\ processes a graphic definition file, it first calls
+another program that filters the \type {btex} commands from the source file, and
+generates a \TEX\ file from them. This file is then processed by \TEX, and after
+that converted to a \type {mpx} file. In \CONTEXT\ we let \TEXEXEC\ take care of
+this whole process.
+
+Because the \typ {btex ... etex} commands are filtered from the raw \METAPOST\
+source code, they cannot be part of macro definitions and loop constructs. When
+used that way, only one instance would be found, while in practice multiple
+instances may occur.
+
+This drawback is overcome by \METAFUN's \type {textext} command. This command
+still uses \typ {btex ... etex} but writes these commands to a separate job
+related file each time it is used. \footnote {It took the author a while to find
+out that there is a \METAPOST\ module called \type {tex.mp} that provides a
+similar feature, but with the disadvantage that each text results in a call to
+\TEX. Each text goes into a temporary file, which is then included and results in
+\METAPOST\ triggering \TEX.} After the first \METAPOST\ run, this file is merged
+with the original file, and \METAPOST\ is called again. So, at the cost of an
+additional run, we can use text typeset by \TEX\ in a more versatile way. Because
+\METAPOST\ runs are much faster than \TEX\ runs, the price to pay in terms of run
+time is acceptable. Unlike \typ {btex ... etex}, the \TEX\ code in \type
+{textext} command is expanded, but as long as \CONTEXT\ is used this is seldom a
+problem, because most commands are somewhat protected.
+
+If we define a graphic with text to be typeset by \TEX, there is a good chance
+that this text is not frozen but passes as argument. A \TEX||like solution for
+passing arbitrary content to such a graphic is the following: \footnote {The \type
+{\unexpanded} prefix makes the command robust for being passed as argument. It is not
+to be confused with the primitive. We had this feature already when the primitive
+showed up and it was considered to be inconvenient for other macro packages to adapt to
+the \CONTEXT\ situation. So keep that in mind when you mix macro packages.}
+
+\startbuffer[def]
+\unexpanded\def\RotatedText#1#2%
+ {\startuseMPgraphic{RotatedText}
+ draw btex #2 etex rotated #1 ;
+ \stopuseMPgraphic
+ \useMPgraphic{RotatedText}}
+\stopbuffer
+
+\typebuffer[def] \getbuffer[def]
+
+This macro takes two arguments (the \type {#} identifies an
+argument):
+
+\startbuffer[exa]
+\RotatedText{15}{Some Rotated Text}
+\stopbuffer
+
+\typebuffer[exa]
+
+The text is rotated over 15 degrees about the origin in a counterclockwise
+direction.
+
+\startlinecorrection[blank]
+\getbuffer[exa]
+\stoplinecorrection
+
+In \CONTEXT\ we seldom pass settings like the angle of rotation in this manner.
+You can use \type {\setupMPvariables} to set up graphic||specific variables. Such
+a variable can be accessed with \type {\MPvar}.
+
+\startbuffer[def]
+\setupMPvariables[RotatedText][rotation=90]
+
+\startuseMPgraphic{RotatedText}
+ draw textext{Some Text} rotated \MPvar{rotation} ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[def] \getbuffer[def]
+
+An example:
+
+\startbuffer[exa]
+\RotatedText{-15}{Some Rotated Text}
+\stopbuffer
+
+\typebuffer[exa]
+
+\startlinecorrection[blank]
+\getbuffer[exa]
+\stoplinecorrection
+
+In a similar fashion we can isolate the text. This permits us to use the same
+graphics with different settings.
+
+\startbuffer[def]
+\setupMPvariables[RotatedText][rotation=270]
+
+\setMPtext{RotatedText}{Some Text}
+
+\startuseMPgraphic{RotatedText}
+ draw \MPbetex{RotatedText} rotated \MPvar{rotation} ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[def] \getbuffer[def]
+
+This works as expected:
+
+\startbuffer[exa]
+\RotatedText{165}{Some Rotated Text}
+\stopbuffer
+
+\typebuffer[exa]
+
+\startlinecorrection[blank]
+\getbuffer[exa]
+\stoplinecorrection
+
+It is now a small step towards an encapsulating macro (we assume that you are
+familiar with \TEX\ macro definitions).
+
+\startbuffer[def]
+\def\RotatedText[#1]#2%
+ {\setupMPvariables[RotatedText][#1]%
+ \setMPtext{RotatedText}{#2}%
+ \useMPgraphic{RotatedText}}
+
+\setupMPvariables[RotatedText][rotation=90]
+
+\startuseMPgraphic{RotatedText}
+ draw \MPbetex{RotatedText} rotated \MPvar{rotation} ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[def] \getbuffer[def]
+
+Again, we default to a 90 degrees rotation, and pass both the settings and text
+in an indirect way. This method permits you to build complicated graphics and
+still keep macros readable.
+
+\startbuffer[exa]
+\RotatedText[rotation=240]{Some Rotated Text}
+\stopbuffer
+
+\typebuffer[exa]
+
+\startlinecorrection[blank]
+\getbuffer[exa]
+\stoplinecorrection
+
+You may wonder why we don't use the variable mechanism to pass the text. The main
+reason is that the text mechanism offers a few more features, one of which is
+that it passes the text straight on, without the danger of unwanted expansion of
+embedded macros. Using \type {\setMPtext} also permits you to separate \TEX\ and
+\METAPOST\ code and reuse it multiple times (imagine using the same graphic in a
+section head command).
+
+There are three ways to access a text defined with \type {\setMPtext}. Imagine
+that we have the following definitions:
+
+\startbuffer
+\setMPtext {1} {Now is this \TeX\ or not?}
+\setMPtext {2} {See what happens here.}
+\setMPtext {3} {Text streams become pictures.}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The \type {\MPbetex} macro returns a \typ {btex ... etex} construct. The \type
+{\MPstring} returns the text as a \METAPOST\ string, between quotes. The raw text
+can be fetched with \type {\MPtext}.
+
+\startbuffer
+\startMPcode
+ picture p ; p := \MPbetex {1} ;
+ picture q ; q := textext( \MPstring{2} ) ;
+ picture r ; r := thelabel("\MPtext {3}",origin) ;
+
+ for i=p, boundingbox p : draw i withcolor .625red ; endfor ;
+ for i=q, boundingbox q : draw i withcolor .625yellow ; endfor ;
+ for i=r, boundingbox r : draw i withcolor .625white ; endfor ;
+
+ currentpicture := currentpicture scaled 2 ;
+ draw origin
+ withpen pencircle scaled 5.0mm withcolor white ;
+ draw origin
+ withpen pencircle scaled 2.5mm withcolor black ;
+ draw boundingbox currentpicture
+ withpen pencircle scaled .1mm
+ dashed evenly ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+The first two lines return text typeset by \TEX, while the last line leaves this
+to \METAPOST.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+If you watch closely, you will notice that the first (red) alternative is
+positioned with the baseline on the origin.
+
+\startbuffer
+\startMPcode
+ picture p ; p := \MPbetex {1} ;
+ picture q ; q := textext.origin( \MPstring{2} ) ;
+ picture r ; r := thelabel.origin("\MPtext {3}",origin) ;
+
+ for i=p, boundingbox p : draw i withcolor .625red ; endfor ;
+ for i=q, boundingbox q : draw i withcolor .625yellow ; endfor ;
+ for i=r, boundingbox r : draw i withcolor .625white ; endfor ;
+
+ currentpicture := currentpicture scaled 2 ;
+ draw origin withpen pencircle scaled 5.0mm
+ withcolor white ;
+ draw origin withpen pencircle scaled 2.5mm
+ withcolor black ;
+ draw boundingbox currentpicture
+ withpen pencircle scaled .1mm
+ dashed evenly ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+This draws:
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+This picture demonstrates that we can also position \type {textext}'s and \type
+{label}'s on the baseline. For this purpose the repertoire of positioning
+directives (\type {top}, \type {lft}, etc.) is extended with an \type {origin}
+directive. Another extra positioning directive is \type {raw}. This one does not
+do any positioning at all.
+
+\starttyping
+picture q ; q := textext.origin( \MPstring{2} ) ;
+picture r ; r := thelabel.origin("\MPtext {3}",origin) ;
+\stoptyping
+
+We will now apply this knowledge of text inclusion in graphics to a more advanced
+example. The next definitions are the answer to a question on the \CONTEXT\
+mailinglist with regards to framed texts with titles.
+
+\startbuffer[a]
+\defineoverlay[FunnyFrame][\useMPgraphic{FunnyFrame}]
+
+\defineframedtext[FunnyText][frame=off,background=FunnyFrame]
+
+\def\StartFrame{\startFunnyText}
+\def\StopFrame {\stopFunnyText }
+
+\def\FrameTitle#1%
+ {\setMPtext{FunnyFrame}{\hbox spread 1em{\hss\strut#1\hss}}}
+
+\setMPtext{FunnyFrame}{} % initialize the text variable
+\stopbuffer
+
+\startbuffer[b]
+\startuseMPgraphic{FunnyFrame}
+ picture p ; numeric w, h, o ;
+ p := textext.rt(\MPstring{FunnyFrame}) ;
+ w := OverlayWidth ; h := OverlayHeight ; o := BodyFontSize ;
+ p := p shifted (2o,h-ypart center p) ; draw p ;
+ drawoptions (withpen pencircle scaled 1pt withcolor .625red) ;
+ draw (2o,h)--(0,h)--(0,0)--(w,0)--(w,h)--(xpart urcorner p,h) ;
+ draw boundingbox p ;
+ setbounds currentpicture to unitsquare xyscaled(w,h) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[c1]
+\FrameTitle{Zapf (1)}
+
+\StartFrame
+Coming back to the use of typefaces in electronic
+publishing: many of the new typographers receive their
+knowledge and information about the rules of typography from
+books, from computer magazines or the instruction manuals
+which they get with the purchase of a PC or software.
+\StopFrame
+\stopbuffer
+
+\getbuffer[a,b,c1]
+
+In this example, the title is positioned on top of the frame. Title and text are
+entered as:
+
+\typebuffer[c1]
+
+The implementation is not that complicated and uses the frame commands that are
+built in \CONTEXT. Instead of letting \TEX\ draw the frame, we use \METAPOST,
+which we also use for handling the title. The graphic is defined as follows:
+
+\typebuffer[b]
+
+Because the framed title is partly positioned outside the main frame, and because
+the main frame will be combined with the text, we need to set the boundingbox
+explicitly. This is a way to create so called free figures, where part of the
+figure lays beyond the area that is taken into account when positioning the
+graphic. The shift
+
+\starttyping
+... shifted (2o,h-ypart center p)
+\stoptyping
+
+ensures that the title is vertically centered over the top line of the main box.
+
+The macros that use this graphic combine some techniques of defining macros,
+using predefined \CONTEXT\ classes, and passing information to graphics.
+
+\typebuffer[a]
+
+There is a little bit of low level \TEX\ code involved, like a horizontal box
+(\type {\hbox}) that stretches one em||space beyond its natural size (\type
+{spread 1em}) with a centered text (two times \type {\hss}). Instead of applying
+this spread, we could have enlarged the frame on both sides.
+
+\startbuffer[b]
+\startuseMPgraphic{FunnyFrame}
+ picture p ; numeric o ; path a, b ; pair c ;
+ p := textext.rt(\MPstring{FunnyFrame}) ;
+ a := unitsquare xyscaled(OverlayWidth,OverlayHeight) ;
+ o := BodyFontSize ;
+ p := p shifted (2o,OverlayHeight-ypart center p) ;
+ drawoptions (withpen pencircle scaled 1pt withcolor .625red) ;
+ b := a randomized (o/2) ;
+ fill b withcolor .85white ; draw b ;
+ b := (boundingbox p) randomized (o/8) ;
+ fill b withcolor .85white ; draw b ;
+ draw p withcolor black;
+ setbounds currentpicture to a ;
+ \stopuseMPgraphic
+\stopbuffer
+
+In the previous graphic we calculated the big rectangle taking the small one into
+account. This was needed because we don't use a background fill. The next
+definition does, so there we can use a more straightforward approach by just
+drawing (and filling) the small rectangle on top of the big one.
+
+\typebuffer[b] \getbuffer[b]
+
+\startbuffer[c2]
+\FrameTitle{Zapf (2)}
+
+\StartFrame
+There is not so much basic instruction, as of now, as there
+was in the old days, showing the differences between good
+and bad typographic design.
+\StopFrame
+\stopbuffer
+
+\getbuffer[c2]
+
+Because we use a random graphic, we cannot guarantee beforehand that the left and
+right edges of the small shape touch the horizontal lines in a nice way. The next
+alternative displaces the small shape plus text so that its center lays on the
+line. On the average, this looks better.
+
+\startbuffer[b]
+\startuseMPgraphic{FunnyFrame}
+ picture p ; numeric o ; path a, b ; pair c ;
+ p := textext.rt(\MPstring{FunnyFrame}) ;
+ a := unitsquare xyscaled(OverlayWidth,OverlayHeight) ;
+ o := BodyFontSize ;
+ p := p shifted (2o,OverlayHeight-ypart center p) ;
+ drawoptions (withpen pencircle scaled 1pt withcolor .625red) ;
+ b := a randomized (o/2) ;
+ fill b withcolor .85white ; draw b ;
+ c := center p ;
+ c := b intersectionpoint (c shifted (0,-o)--c shifted(0,o)) ;
+ p := p shifted (c-center p) ;
+ b := (boundingbox p) randomized (o/8) ;
+ fill b withcolor .85white ; draw b ;
+ draw p withcolor black;
+ setbounds currentpicture to a ;
+ \stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[b] \getbuffer[b]
+
+\getbuffer[c2]
+
+Yet another definition uses super ellipsed shapes instead of random ones. We need
+a high degree of superness (.95) in order to make sure that the curves don't
+touch the texts.
+
+\startbuffer[b]
+\startuseMPgraphic{FunnyFrame}
+ picture p ; numeric o ; path a, b ; pair c ;
+ p := textext.rt(\MPstring{FunnyFrame}) ;
+ o := BodyFontSize ;
+ a := unitsquare xyscaled(OverlayWidth,OverlayHeight) ;
+ p := p shifted (2o,OverlayHeight-ypart center p) ;
+ drawoptions (withpen pencircle scaled 1pt withcolor .625red) ;
+ b := a superellipsed .95 ;
+ fill b withcolor .85white ; draw b ;
+ b := (boundingbox p) superellipsed .95 ;
+ fill b withcolor .85white ; draw b ;
+ draw p withcolor black ;
+ setbounds currentpicture to a ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[b] \getbuffer[b]
+
+\startbuffer[c3]
+\FrameTitle{Zapf (3)}
+
+\StartFrame
+Many people are just fascinated by their PC's tricks, and
+think that a widely||praised program, called up on the
+screen, will make everything automatic from now on.
+\StopFrame
+\stopbuffer
+
+\getbuffer[c3]
+
+There are quite some hard coded values in these graphics, like the linewidths,
+offsets and colors. Some of these can be fetched from the \type {\framed}
+environment either by using \TEX\ macros or dimensions, or by using their
+\METAFUN\ counterparts. In the following table we summarize both the available
+\METAPOST\ variables and their \TEX\ counterparts. They may be used
+interchangeably.
+
+\starttabulate[|l|Tl|l|]
+\HL
+\NC \bf \METAPOST\ variable \NC \rm \bf \TEX\ command \NC \bf meaning \NC\NR
+\HL
+\NC OverlayWidth \NC \string\overlaywidth
+ \NC current width \NC\NR
+\NC OverlayHeight \NC \string\overlayheight
+ \NC current height \NC\NR
+\NC OverlayDepth \NC \string\overlayheight
+ \NC current depth (often zero) \NC\NR
+\NC OverlayColor \NC \string\MPcolor\string{\string\overlaycolor\string}
+ \NC background color \NC\NR
+\NC OverlayLineWidth \NC \string\overlaylinewidth
+ \NC width of the frame \NC\NR
+\NC OverlayLineColor \NC \string\MPcolor\string{\overlaylinecolor\string}
+ \NC color of the frame \NC\NR
+\NC BaseLineSkip \NC \string\the\string\baselineskip
+ \NC main line distance \NC\NR
+\NC LineHeight \NC \string\the\string\baselineskip
+ \NC idem \NC\NR
+\NC BodyFontSize \NC \string\the\string\bodyfontsize
+ \NC font size of the running text \NC\NR
+\NC StrutHeight \NC \string\strutheight
+ \NC space above the baseline \NC\NR
+\NC StrutDepth \NC \string\strutdepth
+ \NC space below the baseline \NC\NR
+\NC ExHeight \NC 1ex
+ \NC height of an x \NC \NR
+\NC EmWidth \NC 1em
+ \NC width of an m-dash \NC \NR
+\HL
+\stoptabulate
+
+\startbuffer[b]
+\startuseMPgraphic{FunnyFrame}
+ picture p ; numeric o ; path a, b ; pair c ;
+ p := textext.rt(\MPstring{FunnyFrame}) ;
+ o := BodyFontSize ;
+ a := unitsquare xyscaled(OverlayWidth,OverlayHeight) ;
+ p := p shifted (2o,OverlayHeight-ypart center p) ;
+ pickup pencircle scaled OverlayLineWidth ;
+ b := a superellipsed .95 ;
+ fill b withcolor OverlayColor ;
+ draw b withcolor OverlayLineColor ;
+ b := (boundingbox p) superellipsed .95 ;
+ fill b withcolor OverlayColor ;
+ draw b withcolor OverlayLineColor ;
+ draw p withcolor black ;
+ setbounds currentpicture to a ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer[b] \getbuffer[b]
+
+\startbuffer[d]
+\setupframedtexts
+ [FunnyText]
+ [backgroundcolor=lightgray,
+ framecolor=darkred,
+ rulethickness=2pt,
+ offset=\bodyfontsize,
+ before={\blank[big,medium]},
+ after={\blank[big]},
+ width=\textwidth]
+\stopbuffer
+
+\getbuffer[d,c3]
+
+We used the following command to pass the settings:
+
+\typebuffer[d]
+
+In a real implementation, we should also take care of some additional spacing
+before the text, which is why we have added more space before than after the
+framed text.
+
+We demonstrated that when defining graphics that are part of the layout, you need
+to have access to information known to the typesetting engine. Take \in {figure}
+[fig:penalty]. The line height needs to match the font and the two thin
+horizontal lines should match the {\em x}||height. We also need to position the
+baseline, being the lowest one of a pair of lines, in such a way that it suits
+the proportions of the line as specified by the strut. A strut is an imaginary
+large character with no width. You should be aware of the fact that while \TEX\
+works its way top||down, in \METAPOST\ the origin is in the lower left corner.
+
+\startmode[screen]
+
+\placefigure
+ [page][fig:penalty]
+ {Penalty lines.}
+ {\typesetfile[mfun-902.tex][page=1,frame=on,height=.85\textheight]}
+
+\stopmode
+
+\startnotmode[screen]
+
+\placefigure
+ [here][fig:penalty]
+ {Penalty lines.}
+ {\typesetfile[mfun-902.tex][page=1,frame=on,height=.50\textheight]}
+
+\stopnotmode
+
+\typebuffer[handwrit]
+
+This code demonstrates the use of \type {LineHeight}, \type {ExHeight}, \type
+{StrutHeight} and \type {StrutDepth}. We set the interline spacing to 1.5 so that
+we get a bit more loose layout. The variables mentioned are set each time a
+graphic is processed and thereby match the current font settings.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-lua.tex b/doc/context/sources/general/manuals/metafun/metafun-lua.tex
new file mode 100644
index 000000000..da35cccde
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-lua.tex
@@ -0,0 +1,1060 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+% this is an extension of about-lua
+
+\startcomponent mfun-lua
+
+\environment metafun-environment
+
+\startchapter[title={Lua}]
+
+\index{\LUA}
+
+\startintro
+
+Already for some years I have been wondering how it would be if we could escape
+to \LUA\ inside \METAPOST, or in practice, use \MPLIB\ in \LUATEX. The idea is
+simple: embed \LUA\ code in a \METAPOST\ file that gets run as soon as it's seen.
+In case you wonder why \LUA\ code makes sense, imagine generating graphics using
+external data. The capabilities of \LUA\ to deal with that is more flexible and
+advanced than in \METAPOST. Of course we could generate a \METAPOST\ definition
+of a graphic from data but often it makes more sense to do the reverse. I finally
+found time and reason to look into this and in the following sections I will
+describe how it's done.
+
+\stopintro
+
+\startsection[title=Introduction]
+
+\stopsection
+
+\startsection[title=The basics]
+
+The approach is comparable to \LUATEX's \type {\directlua}. That primitive can be
+used to execute \LUA\ code and in combination with \type {tex.print} we can pipe
+back strings into the \TEX\ input stream. There a complication is that that we
+have to be able to operate under different so called catcode regimes: the meaning
+of characters can differ per regime. We also have to deal with line endings in
+special ways as they relate to paragraphs and such. In \METAPOST\ we don't have
+that complication so getting back input into the \METAPOST\ input, we can do so
+with simple strings. For that a mechanism similar to \type {scantokens} can be
+used. That way we can return anything (including nothing) as long as \METAPOST\
+can interpret it and as long as it fulfils the expectations.
+
+\starttyping
+numeric n ; n := scantokens("123.456") ;
+\stoptyping
+
+A script is run as follows:
+
+\starttyping
+numeric n ; n := runscript("return '123.456'") ;
+\stoptyping
+
+This primitive doesn't have the word \type {lua} in its name so in principle any
+wrapper around the library can use it as hook. In the case of \LUATEX\ the script
+language is of course \LUA. At the \METAPOST\ end we only expect a string. How
+that string is constructed is completely up to the \LUA\ script. In fact, the
+user is completely free to implement the runner any way she or he wants, like:
+
+\starttyping
+local function scriptrunner(code)
+ local f = loadstring(code)
+ if f then
+ return tostring(f())
+ else
+ return ""
+ end
+end
+\stoptyping
+
+This is hooked into an instance as follows:
+
+\starttyping
+local m = mplib.new {
+ ...
+ run_script = scriptrunner,
+ ...
+}
+\stoptyping
+
+Now, beware, this is not the \CONTEXT\ way. We provide print functions and other
+helpers, which we will explain in the next section.
+
+\stopsection
+
+\startsection[title=Helpers]
+
+After I got this feature up and running I played a bit with possible interfaces
+at the \CONTEXT\ (read: \METAFUN) end and ended up with a bit more advanced runner
+where no return value is used. The runner is wrapped in the \type {lua} macro.
+
+\startbuffer
+numeric n ; n := lua("mp.print(12.34567)") ;
+draw textext(n) xsized 4cm withcolor darkred ;
+\stopbuffer
+
+\typebuffer
+
+This renders as:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+In case you wonder how efficient calling \LUA\ is, don't worry: it's fast enough,
+especially if you consider suboptimal \LUA\ code and the fact that we switch
+between machineries.
+
+\startbuffer
+draw image (
+ lua("statistics.starttiming()") ;
+ for i=1 upto 10000 : draw
+ lua("mp.pair(math.random(-200,200),math.random(-50,50))") ;
+ endfor ;
+ setbounds currentpicture to fullsquare xyscaled (400,100) ;
+ lua("statistics.stoptiming()") ;
+) withcolor darkyellow withpen pencircle scaled 1 ;
+draw textext(lua("mp.print(statistics.elapsedtime())"))
+ ysized 50 withcolor darkred ;
+\stopbuffer
+
+\typebuffer
+
+Here the line:
+
+\starttyping
+draw lua("mp.pair(math.random(-200,200),math.random(-50,50))") ;
+\stoptyping
+
+effectively becomes (for instance):
+
+\starttyping
+draw scantokens "(25,40)" ;
+\stoptyping
+
+which in turn becomes:
+
+\starttyping
+draw scantokens (25,40) ;
+\stoptyping
+
+The same happens with this:
+
+\starttyping
+draw textext(lua("mp.print(statistics.elapsedtime())")) ...
+\stoptyping
+
+This becomes for instance:
+
+\starttyping
+draw textext(scantokens "1.23") ...
+\stoptyping
+
+and therefore:
+
+\starttyping
+draw textext(1.23) ...
+\stoptyping
+
+We can use \type {mp.print} here because the \type {textext} macro can deal with
+numbers. The next also works:
+
+\starttyping
+draw textext(lua("mp.quoted(statistics.elapsedtime())")) ...
+\stoptyping
+
+Now we get (in \METAPOST\ speak):
+
+\starttyping
+draw textext(scantokens (ditto & "1.23" & ditto) ...
+\stoptyping
+
+Here \type {ditto} represents the double quotes that mark a string. Of course,
+because we pass the strings directly to \type {scantokens}, there are no outer
+quotes at all, but this is how it can be simulated. In the end we have:
+
+\starttyping
+draw textext("1.23") ...
+\stoptyping
+
+What you use, \type {mp.print} or \type {mp.quoted} depends on what the expected
+code is: an assignment to a numeric can best be a number or an expression
+resulting in a number.
+
+This graphic becomes:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The runtime on my current machine is some 0.25 seconds without and 0.12 seconds
+with caching. But to be honest, speed is not really a concern here as the amount
+of complex \METAPOST\ graphics can be neglected compared to extensive node list
+manipulation. With \LUAJITTEX\ generating the graphic takes 15\% less time.
+
+\startbuffer
+numeric n ; n := lua("mp.print(1) mp.print('+') mp.print(2)") ;
+draw textext(n) xsized 1cm withcolor darkred ;
+\stopbuffer
+
+The three print command accumulate their arguments:
+
+\typebuffer
+
+As expected we get:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\startbuffer
+numeric n ; n := lua("mp.print(1,'+',2)") ;
+draw textext(n) xsized 1cm withcolor darkred ;
+\stopbuffer
+
+Equally valid is:
+
+\typebuffer
+
+This gives the same result:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Of course all kind of action can happen between the prints. It is also legal to
+have nothing returned as could be seen in the 10.000 dot example: there the timer
+related code returns nothing so effectively we have \type {scantokens("")}. Another
+helper is \type {mp.quoted}, as in:
+
+\startbuffer
+draw
+ textext(lua("mp.quoted('@0.3f'," & decimal n & ")"))
+ withcolor darkred ;
+\stopbuffer
+
+\typebuffer
+
+This typesets \processMPbuffer. Watch the \type {@}. When no percent character is
+found in the format specifier, we assume that an \type {@} is used instead.
+
+\startbuffer
+\startluacode
+table.save("demo-data.lua",
+ {
+ { 1, 2 }, { 2, 4 }, { 3, 3 }, { 4, 2 },
+ { 5, 2 }, { 6, 3 }, { 7, 4 }, { 8, 1 },
+ }
+)
+\stopluacode
+\stopbuffer
+
+But, the real benefit of embedded \LUA\ is when we deal with data that is stored
+at the \LUA\ end. First we define a small dataset:
+
+\typebuffer
+
+\getbuffer
+
+There are several ways to deal with this table. I will show clumsy as well as
+better looking ways.
+
+\startbuffer
+lua("MP = { } MP.data = table.load('demo-data.lua')") ;
+numeric n ;
+lua("mp.print('n := ',\#MP.data)") ;
+for i=1 upto n :
+ drawdot
+ lua("mp.pair(MP.data[" & decimal i & "])") scaled cm
+ withpen pencircle scaled 2mm
+ withcolor darkred ;
+endfor ;
+\stopbuffer
+
+\typebuffer
+
+Here we load a \LUA\ table and assign the size to a \METAPOST\ numeric. Next we
+loop over the table entries and draw the coordinates.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+We will stepwise improve this code. In the previous examples we omitted wrapper
+code but here we show it:
+
+\startbuffer
+\startluacode
+ MP.data = table.load('demo-data.lua')
+ function MP.n()
+ mp.print(#MP.data)
+ end
+ function MP.dot(i)
+ mp.pair(MP.data[i])
+ end
+\stopluacode
+
+\startMPcode
+ numeric n ; n := lua("MP.n()") ;
+ for i=1 upto n :
+ drawdot
+ lua("MP.dot(" & decimal i & ")") scaled cm
+ withpen pencircle scaled 2mm
+ withcolor darkred ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+So, we create a few helpers in the \type {MP} table. This table is predefined so
+normally you don't need to define it. You may however decide to wipe it clean.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+You can decide to hide the data:
+
+\startbuffer
+\startluacode
+ local data = { }
+ function MP.load(name)
+ data = table.load(name)
+ end
+ function MP.n()
+ mp.print(#data)
+ end
+ function MP.dot(i)
+ mp.pair(data[i])
+ end
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+It is possible to use less \LUA, for instance in:
+
+\startbuffer
+\startluacode
+ local data = { }
+ function MP.loaded(name)
+ data = table.load(name)
+ mp.print(#data)
+ end
+ function MP.dot(i)
+ mp.pair(data[i])
+ end
+\stopluacode
+
+\startMPcode
+ for i=1 upto lua("MP.loaded('demo-data.lua')") :
+ drawdot
+ lua("MP.dot(",i,")") scaled cm
+ withpen pencircle scaled 4mm
+ withcolor darkred ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+Here we also omit the \type {decimal} because the \type {lua} macro is clever
+enough to recognize it as a number.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+By using some \METAPOST\ magic we can even go a step further in readability:
+
+\startbuffer
+\startMPcode{doublefun}
+ lua.MP.load("demo-data.lua") ;
+
+ for i=1 upto lua.MP.n() :
+ drawdot
+ lua.MP.dot(i) scaled cm
+ withpen pencircle scaled 4mm
+ withcolor darkred ;
+ endfor ;
+
+ for i=1 upto MP.n() :
+ drawdot
+ MP.dot(i) scaled cm
+ withpen pencircle scaled 2mm
+ withcolor white ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+Here we demonstrate that it also works ok in \type {double} mode, which makes
+much sense when processing data from other sources. Watch how we omit the
+type {lua.} prefix: the \type {MP} macro will deal with that.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+So in the end we can simplify the code that we started with to:
+
+\starttyping
+\startMPcode{doublefun}
+ for i=1 upto MP.loaded("demo-data.lua") :
+ drawdot
+ MP.dot(i) scaled cm
+ withpen pencircle scaled 2mm
+ withcolor darkred ;
+ endfor ;
+\stopMPcode
+\stoptyping
+
+\stopsection
+
+\startsection[title=Access to variables]
+
+The question with such mechanisms is always: how far should we go. Although
+\METAPOST\ is a macro language it has properties of procedural languages. It also
+has more introspective features at the user end. For instance, one can loop over
+the resulting picture and manipulate it. This means that we don't need full
+access to \METAPOST\ internals. However, it makes sense to provide access to
+basic variables: \type {numeric}, \type {string}, and \type {boolean}.
+
+\startbuffer
+draw textext(lua("mp.quoted('@0.15f',mp.get.numeric('pi')-math.pi)"))
+ ysized 1cm
+ withcolor darkred ;
+\stopbuffer
+
+\typebuffer
+
+In double mode you will get zero printed but in scaled mode we definitely get a
+difference:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\startbuffer
+boolean b ; b := true ;
+draw textext(lua("mp.quoted(mp.get.boolean('b') and 'yes' or 'no')"))
+ ysized 1cm
+ withcolor darkred ;
+\stopbuffer
+
+In the next example we use \type {mp.quoted} to make sure that indeed we pass a
+string. The \type {textext} macro can deal with numbers but an unquoted \type
+{yes} or \type {no} is asking for problems.
+
+\typebuffer
+
+Especially when more text is involved it makes sense to predefine a helper in
+the \type {MP} namespace if only because \METAPOST\ (currently) doesn't like
+newlines in the middle of a string, so a \type {lua} call has to be on one line.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Here is an example where \LUA\ does something that would be close to impossible,
+especially if more complex text is involved.
+
+% \enabletrackers[metapost.lua]
+
+\startbuffer
+string s ; s := "ΤΕΧ" ; % "τεχ"
+draw textext(lua("mp.quoted(characters.lower(mp.get.string('s')))"))
+ ysized 1cm
+ withcolor darkred ;
+\stopbuffer
+
+\typebuffer
+
+As you can see here, the whole repertoire of helper functions can be used in
+a \METAFUN\ definition.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=The library]
+
+In \CONTEXT\ we have a dedicated runner, but for the record we mention the
+low level constructor:
+
+\starttyping
+local m = mplib.new {
+ ...
+ script_runner = function(s) return loadstring(s)() end,
+ script_error = function(s) print(s) end,
+ ...,
+}
+\stoptyping
+
+An instance (in this case \type {m}) has a few extra methods. Instead you can use
+the helpers in the library.
+
+\starttabulate[|l|l|]
+\HL
+\NC \type {m:get_numeric(name)} \NC returns a numeric (double) \NC \NR
+\NC \type {m:get_boolean(name)} \NC returns a boolean (\type {true} or \type {false}) \NC \NR
+\NC \type {m:get_string (name)} \NC returns a string \NC \NR
+\HL
+\NC \type {mplib.get_numeric(m,name)} \NC returns a numeric (double) \NC \NR
+\NC \type {mplib.get_boolean(m,name)} \NC returns a boolean (\type {true} or \type {false}) \NC \NR
+\NC \type {mplib.get_string (m,name)} \NC returns a string \NC \NR
+\HL
+\stoptabulate
+
+In \CONTEXT\ the instances are hidden and wrapped in high level macros, so there
+you cannot use these commands.
+
+\stopsection
+
+\startsection[title=\CONTEXT\ helpers]
+
+The \type {mp} namespace provides the following helpers:
+
+\starttabulate[|l|l|]
+\HL
+\NC \type {print(...)} \NC returns one or more values \NC \NR
+\NC \type {pair(x,y)}
+ \type {pair(t)} \NC returns a proper pair \NC \NR
+\NC \type {triplet(x,y,z)}
+ \type {triplet(t)} \NC returns an \RGB\ color \NC \NR
+\NC \type {quadruple(w,x,y,z)}
+ \type {quadruple(t)} \NC returns an \CMYK\ color \NC \NR
+\NC \type {format(fmt,...)} \NC returns a formatted string \NC \NR
+\NC \type {quoted(fmt,...)}
+ \type {quoted(s)} \NC returns a (formatted) quoted string \NC \NR
+\NC \type {path(t[,connect][,close])} \NC returns a connected (closed) path \NC \NR
+\HL
+\stoptabulate
+
+The \type {mp.get} namespace provides the following helpers:
+
+\starttabulate[|l|l|]
+\HL
+\NC \type {numeric(name)} \NC gets a numeric from \METAPOST \NC \NR
+\NC \type {boolean(name)} \NC gets a boolean from \METAPOST \NC \NR
+\NC \type {string(name)} \NC gets a string from \METAPOST \NC \NR
+\HL
+\stoptabulate
+
+\stopsection
+
+\startsection[title=Paths]
+
+In the meantime we got several questions on the \CONTEXT\ mailing list about turning
+coordinates into paths. Now imagine that we have this dataset:
+
+\startbuffer[dataset]
+10 20 20 20 -- sample 1
+30 40 40 60
+50 10
+
+10 10 20 30 % sample 2
+30 50 40 50
+50 20
+
+10 20 20 10 # sample 3
+30 40 40 20
+50 10
+\stopbuffer
+
+\typebuffer[dataset]
+
+In this case I've put the data in a buffer so that it can be shown
+here as well as used in a demo. Watch how we can add comments. The
+following code converts this into a table with three subtables.
+
+\startbuffer
+\startluacode
+ MP.myset = mp.dataset(buffers.getcontent("dataset"))
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We use the \type {MP} (user) namespace to store the table. Next we turn
+these subtables into paths:
+
+\startbuffer
+\startMPcode
+ for i=1 upto lua("mp.print(mp.n(MP.myset))") :
+ draw
+ lua("mp.path(MP.myset[" & decimal i & "])")
+ xysized (HSize-.25ExHeight,10ExHeight)
+ withpen pencircle scaled .25ExHeight
+ withcolor basiccolors[i]/2 ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+This gives:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+Instead we can fill the path in which case we also need to close it. The
+\type {true} argument deals with that:
+
+\startbuffer
+\startMPcode
+ for i=1 upto lua("mp.print(mp.n(MP.myset))") :
+ path p ; p :=
+ lua("mp.path(MP.myset[" & decimal i & "],true)")
+ xysized (HSize,10ExHeight) ;
+ fill p
+ withcolor basiccolors[i]/2
+ withtransparency (1,.5) ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+We get:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+\startbuffer
+\startMPcode
+ for i=1 upto lua("mp.print(mp.n(MP.myset))") :
+ path p ; p :=
+ lua("mp.path(MP.myset[" & decimal i & "])")
+ xysized (HSize,10ExHeight) ;
+ p :=
+ (xpart llcorner boundingbox p,0) --
+ p --
+ (xpart lrcorner boundingbox p,0) --
+ cycle ;
+ fill p
+ withcolor basiccolors[i]/2
+ withtransparency (1,.25) ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+The following makes more sense:
+
+\typebuffer
+
+So this gives:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+This (area) fill is so common that we have a helper for it:
+
+\startbuffer
+\startMPcode
+ for i=1 upto lua("mp.size(MP.myset)") :
+ fill area
+ lua("mp.path(MP.myset[" & decimal i & "])")
+ xysized (HSize,5ExHeight)
+ withcolor basiccolors[i]/2
+ withtransparency (2,.25) ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+So this gives:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+A variant call is the following: \footnote {Getting that to work properly in the
+library was non||trivial as the loop variable \type {i} is an abstract nameless
+variable at the \METAPOST\ end. When investigating this Luigi Scarso and I found out
+that the internals of \METAPOST\ are not really geared for interfacing this way
+but in the end it worked out well.}
+
+\startbuffer
+\startMPcode
+ for i=1 upto lua("mp.size(MP.myset)") :
+ fill area
+ lua("mp.path(MP.myset[mp.get.numeric('i')])")
+ xysized (HSize,5ExHeight)
+ withcolor basiccolors[i]/2
+ withtransparency (2,.25) ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+The result is the same:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+\startbuffer
+\startluacode
+ MP.mypath = function(i)
+ return mp.path(MP.myset[mp.get.numeric(i)])
+ end
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startMPcode
+ for i=1 upto lua("mp.size(MP.myset)") :
+ fill area
+ lua("MP.mypath('i')")
+ xysized (HSize,5ExHeight)
+ withcolor basiccolors[i]/2
+ withtransparency (2,.25) ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+This snippet of \METAPOST\ code still looks kind of horrible so how can we make
+it look better? Here is an attempt, First we define a bit more \LUA:
+
+\startbuffer
+\startluacode
+local data = mp.dataset(buffers.getcontent("dataset"))
+
+MP.dataset = {
+ Line = function(n) mp.path(data[n]) end,
+ Size = function() mp.size(data) end,
+}
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We can now make the \METAPOST\ look more natural. Of course this is possible
+because in \METAFUN\ the \type {lua} macro does some extra work.
+
+\startbuffer
+\startMPcode
+ for i=1 upto lua.MP.dataset.Size() :
+ path p ; p :=
+ lua.MP.dataset.Line(i)
+ xysized (HSize-ExHeight,20ExHeight) ;
+ draw
+ p
+ withpen pencircle scaled .25ExHeight
+ withcolor basiccolors[i]/2 ;
+ drawpoints
+ p
+ withpen pencircle scaled ExHeight
+ withcolor basiccolors[i]/2 ;
+ endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+As expected, we get the desired result:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+Once we start making things look nicer and more convenient, we quickly end up
+with helpers like the once in the next example. First we save some demo data
+in files:
+
+\startbuffer
+\startluacode
+ io.savedata("foo.tmp","10 20 20 20 30 40 40 60 50 10")
+ io.savedata("bar.tmp","10 10 20 30 30 50 40 50 50 20")
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We load the data in datasets:
+
+\startbuffer
+\startMPcode
+ lua.mp.datasets.load("foo","foo.tmp") ;
+ lua.mp.datasets.load("bar","bar.tmp") ;
+ fill area
+ lua.mp.datasets.foo.Line()
+ xysized (HSize/2-EmWidth-.25ExHeight,10ExHeight)
+ withpen pencircle scaled .25ExHeight
+ withcolor darkyellow ;
+ fill area
+ lua.mp.datasets.bar.Line()
+ xysized (HSize/2-EmWidth-.25ExHeight,10ExHeight)
+ shifted (HSize/2+EmWidth,0)
+ withpen pencircle scaled .25ExHeight
+ withcolor darkred ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+Because the datasets are stores by name we can use them without worrying about
+them being forgotten:
+
+\startlinecorrection[blank] \getbuffer \stoplinecorrection
+
+If no tag is given, the filename (without suffix) is used as tag, so the following is
+valid:
+
+\starttyping
+\startMPcode
+ lua.mp.datasets.load("foo.tmp") ;
+ lua.mp.datasets.load("bar.tmp") ;
+\stopMPcode
+\stoptyping
+
+The following methods are defined for a dataset:
+
+\starttabulate[|l|pl|]
+\HL
+\NC \type {method} \NC usage \NC \NR
+\HL
+\NC \type {Size} \NC the number of subsets in a dataset \NC \NR
+\NC \type {Line} \NC the joined pairs in a dataset making a non|-|closed path \NC \NR
+\NC \type {Data} \NC the table containing the data (in subsets, so there is always at least one subset) \NC \NR
+\HL
+\stoptabulate
+
+{\em In order avoid interference with suffix handling in \METAPOST\ the methods
+start with an uppercase character.}
+
+\stopsection
+
+\startsection[title=Passing variables]
+
+You can pass variables from \METAPOST\ to \CONTEXT. Originally that happened via
+a temporary file and so called \METAPOST\ specials. Nowadays it's done via \LUA.
+Here is an example:
+
+\startbuffer
+\startMPcalculation
+
+passvariable("version","1.0") ;
+passvariable("number",123) ;
+passvariable("string","whatever") ;
+passvariable("point",(1.5,2.8)) ;
+passvariable("triplet",(1/1,1/2,1/3)) ;
+passvariable("quad",(1.1,2.2,3.3,4.4)) ;
+passvariable("boolean",false) ;
+passvariable("path",fullcircle scaled 1cm) ;
+path p[] ; p[1] := fullcircle ; p[2] := fullsquare ;
+passarrayvariable("list",p,1,2,1) ; % first last step
+\stopMPcalculation
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+We can visualize the result with
+
+\startbuffer
+\startluacode
+context.tocontext(metapost.variables)
+\stopluacode
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+In \TEX\ you can access these variables as follows:
+
+\startbuffer
+\MPrunvar{version}
+\MPruntab{quad}{3}
+(\MPrunset{triplet}{,})
+
+$(x,y) = (\MPruntab{point}{1},\MPruntab{point}{2})$
+$(x,y) = (\MPrunset{point}{,})$
+\stopbuffer
+
+\typebuffer
+
+This becomes: % we need a hack as we cross pages and variables get replace then
+
+\startlines
+\getbuffer
+\stoplines
+
+Here we passed the code between \type {\startMPcalculation} and \type
+{\stopMPcalculation} which does not produce a graphic and therefore takes no
+space in the flow. Of course it also works with normal graphics.
+
+\startbuffer
+\startMPcode
+path p ; p := fullcircle xyscaled (10cm,2cm) ;
+path b ; b := boundingbox p ;
+startpassingvariable("mypath")
+ passvariable("points",p) ;
+ startpassingvariable("metadata")
+ passvariable("boundingbox",boundingbox p) ;
+ stoppassingvariable ;
+stoppassingvariable ;
+fill p withcolor .625red ;
+draw b withcolor .625yellow ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+ \getbuffer
+\stoplinecorrection
+
+This time we get:
+
+\ctxlua{context.tocontext(metapost.variables)}
+
+You need to be aware of the fact that a next graphic resets the previous
+variables. You can easily overcome that limitation by saving the variables (in
+\LUA). It helps that when a page is being shipped out (which can involve
+graphics) the variables are protected. You can push and pop variable sets with
+\type {\MPpushvariables} and \type {\MPpopvariables}. Because you can nest
+the \type {start}||\type{stop} pairs you can create quite complex indexed
+and hashed tables. If the results are not what you expect, you can enable a
+tracker to follow what gets passed:
+
+\starttyping
+\enabletrackers[metapost.variables]
+\stoptyping
+
+Serializing variables can be done with the \type {tostring} macro, for instance:
+
+\startbuffer
+\startMPcode
+message("doing circle",fullcircle);
+draw fullcircle ;
+\stopMPcode
+\stopbuffer
+
+In this case the \type {tostring} is redundant as the message already does the
+serialization.
+
+\stopsection
+
+\stopchapter
+
+% \startMPcode{doublefun}
+% numeric n ; n := 123.456 ;
+% lua("print('>>>>>>>>>>>> number',mp.get.number('n'))") ;
+% lua("print('>>>>>>>>>>>> number',mp.get.boolean('n'))") ;
+% lua("print('>>>>>>>>>>>> number',mp.get.string('n'))") ;
+% boolean b ; b := true ;
+% lua("print('>>>>>>>>>>>> boolean',mp.get.number('b'))") ;
+% lua("print('>>>>>>>>>>>> boolean',mp.get.boolean('b'))") ;
+% lua("print('>>>>>>>>>>>> boolean',mp.get.string('b'))") ;
+% string s ; s := "TEST" ;
+% lua("print('>>>>>>>>>>>> string',mp.get.number('s'))") ;
+% lua("print('>>>>>>>>>>>> string',mp.get.boolean('s'))") ;
+% lua("print('>>>>>>>>>>>> string',mp.get.string('s'))") ;
+% \stopMPcode
+
+% \usemodule[graph]
+%
+% \startluacode
+% local d = nil
+% function MP.set(data)
+% d = data
+% end
+% function MP.n()
+% mp.print(d and #d or 0)
+% end
+% function MP.get(i,j)
+% mp.print(d and d[i] and d[i][j] or 0)
+% end
+% \stopluacode
+%
+% \startluacode
+% MP.set {
+% { 1, 0.5, 2.5 },
+% { 2, 1.0, 3.5 },
+% }
+% \stopluacode
+%
+% \startMPpage[instance=graph,offset=2mm]
+%
+% draw begingraph(3cm,5cm);
+% numeric a[];
+% for j = 1 upto MP.n() :
+% path b;
+% augment.b(MP.get(j,1),MP.get(j,2));
+% augment.b(MP.get(j,1),MP.get(j,3));
+% setrange(0,0,3,4);
+% gdraw b;
+% endfor ;
+% endgraph ;
+% \stopMPpage
+
+% \starttext
+%
+% % \enabletrackers[metapost.variables]
+%
+% \startMPcode
+% numeric n[] ; for i=1 upto 10: n[i] := 1/i ; endfor ;
+% path p[] ; for i=1 upto 10: p[i] := fullcircle xyscaled (cm*i,cm/i) ; endfor ;
+% numeric r[][] ; for i=1 upto 4 : for j=1 upto 3 : r[i][j] := uniformdeviate(1) ; endfor ; endfor ;
+% pair u[][] ; for i=1 step 0.5 until 4 : for j=1 step 0.1 until 2 : u[i][j] := (i,j) ; endfor ; endfor ;
+%
+% passvariable("x",12345) ;
+% passarrayvariable("n-array",n,1,7,1) ;
+% passarrayvariable("p-array",p,1,7,1) ;
+% passvariable("p",(1,1) .. (2,2)) ;
+%
+% startpassingvariable("b")
+% for i=1 upto 4 :
+% startpassingvariable(i)
+% for j=1 upto 3 :
+% passvariable(j,r[i][j])
+% endfor
+% stoppassingvariable
+% endfor
+% stoppassingvariable ;
+%
+% startpassingvariable("a")
+% startpassingvariable("test 1")
+% passvariable(1,123)
+% passvariable(2,456)
+% stoppassingvariable ;
+% startpassingvariable("test 2")
+% passvariable(0,123)
+% passvariable(1,456)
+% passvariable(2,789)
+% passvariable(999,987)
+% stoppassingvariable ;
+% startpassingvariable("test 3")
+% passvariable("first",789)
+% passvariable("second",987)
+% stoppassingvariable
+% stoppassingvariable ;
+%
+% startpassingvariable("c")
+% for i=1 step 0.5 until 4 :
+% startpassingvariable(i)
+% for j=1 step 0.1 until 2 :
+% passvariable(j,u[i][j])
+% endfor
+% stoppassingvariable
+% endfor
+% stoppassingvariable ;
+%
+% draw fullcircle scaled 1cm ;
+% \stopMPcode
+%
+% \ctxluacode{inspect(metapost.variables)}
+%
+% \ctxcommand{mprunvar("x")}
+
+\stoptext
+
+
diff --git a/doc/context/sources/general/manuals/metafun/metafun-macros.tex b/doc/context/sources/general/manuals/metafun/metafun-macros.tex
new file mode 100644
index 000000000..e1df13c92
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-macros.tex
@@ -0,0 +1,91 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-macros
+
+\environment metafun-environment
+
+\startchapter[title={\METAFUN\ macros}]
+
+\index{metafun}
+
+\startintro
+
+\CONTEXT\ comes with a series of \METAPOST\ modules. In this chapter we will
+summarize the most important \TEX\ and \METAPOST\ macros. More information can be
+found in the documentation of the modules.
+
+\stopintro
+
+There are several ways to use the power of \METAFUN, either or not using
+\CONTEXT.
+
+\startitemize[n]
+
+\startitem
+ You can create an independent \type {mp} file and process it with the
+ \METAPOST\ program or \MPTOPDF. Depending on what features you use, the
+ succes of a run depends on the proper set up of the programs that take care
+ of running \TEX\ for \type {btex}.
+\stopitem
+
+\startitem
+ You can embed the graphic in a \type {\startMPpage} construct and process it
+ with \CONTEXT\ \MKIV. In that case you have the full \METAFUN\ functionality
+ available. If for some reason you still want to use \MKII, you need to use
+ \TEXEXEC\ as before processing the file, it will do a couple of checks on the
+ file. It will also make sure that the temporary files (\type {mpt} for \type
+ {textext}'s and \type {mpo} for outline fonts) are taken care of too.
+\stopitem
+
+\startitem
+ You can integrate the graphic in the document flow, using buffers, \METAPOST\
+ code sections, or (reusable) graphic containers. In that case the graphics
+ are processed runtime or between runs. This happens automatically.
+\stopitem
+
+\stopitemize
+
+Unless you want to write low level \CONTEXT\ code yourself, there is no real
+reason to look into the modules that deal with \METAPOST\ support. The
+traditional (partly generic) code is collected in:
+
+\starttabulate[|lT|p|]
+\NC supp-mps.tex \NC low level inclusion macros and housekeeping \NC\NR
+\NC supp-mpe.tex \NC experimental extensions (like specials) \NC\NR
+\NC supp-pdf.tex \NC \METAPOST\ to \PDF\ conversion \NC\NR
+\stoptabulate
+
+Especially the last two can be used in other macro packages. However, in
+\CONTEXT\ we have regrouped the code (plus more) in other files:
+
+\starttabulate[|lT|p|]
+\NC meta-***.tex \NC definition and managing \NC\NR
+\NC mlib-***.tex \NC processing and conversion \NC\NR
+\stoptabulate
+
+The last category will certainly grow. Some of these modules are preloaded,
+others can be loaded using the command \type {\useMPlibrary}, like
+
+\starttyping
+\useMPlibrary[clp,txt]
+\stoptyping
+
+for loading the predefined clipping paths and text tricks.
+
+The \METAPOST\ code is organized in files named \type {mp-****.mp}. The core file
+is \type {mp-tool.mp} and this file can comfortably be used in stand||alone
+graphics. The file \type {metafun.mp} is used to load the collection of modules
+into a format. The collection of \METAPOST\ code files will grow in due time, but
+as long as you use the \METAFUN\ format, you don't have to keep track of the
+organization of files. Most files relate to subsystems and are loaded
+automatically, like the files that implement page layout support and flow charts.
+
+Although this document is the main source of information, occasionally the source
+code of \METAFUN, and in many cases the source code of \CONTEXT\ may contain
+additional information and examples.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-positioning.tex b/doc/context/sources/general/manuals/metafun/metafun-positioning.tex
new file mode 100644
index 000000000..5a3b1ece0
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-positioning.tex
@@ -0,0 +1,1013 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-positioning
+
+\environment metafun-environment
+
+\startchapter[reference=sec:positioning,title={Positional graphics}]
+
+\startintro
+
+In this chapter, we will explore one of the more advanced, but also conceptually
+more difficult, graphic capabilities of \CONTEXT. It took quite a few experiments
+to find the {\em right} way to support these kind of graphics, and you can be
+sure that in due time extensions will show up. You can skip this chapter if you
+are no \CONTEXT\ user. Because we're now a decade into \MKIV\ the tricks here
+will assume that you use \CONTEXT\ \MKIV\ because we have a more convenient
+interface there. For old|-|school \MKII\ usage you can look in old \METAFUN\
+manuals or in the \type {mkii} source files. Of course we remain compatible, it's
+just that more (convenient) interfaces were added.
+
+\stopintro
+
+\startsection[title={The status quo}]
+
+After \TEX\ has read a paragraph of text, it will try to break this paragraph
+into lines. When this is done, the result is flushed and after that \TEX\ will
+check if a page should be split off. As a result, we can hardly predict how a
+document will come out. Therefore, when we want graphics to adapt themselves to
+this text, maybe even to text broken across lines, we have to deal with this
+asynchronous feature of \TEX\ in a rather advanced way. Before we present a way
+of dealing with this complexity, we will elaborate on the nature of embedded
+graphics in \TEX.
+
+When \TEX\ entered the world of typesetting, desktop printers were not that
+common, let alone color desktop printers. But times have changed and nowadays we
+want color and graphics and if possible we want them integrated in the text. When
+\METAPOST\ showed up it depended on the \DVI\ processor to recognize the
+\POSTSCRIPT\ code as being produced by \METAPOST\ and therefore also include the
+fonts that were used. But color was still limited to \RGB. When \PDFTEX\ evolved
+I wrote an interpreter (in \TEX) that could translate the output to \PDF. This
+also opened up the possibility to add features to \METAPOST, like \CMYK\ colors,
+shading, transparencies etc. But basically the \TEX\ and \METAPOST\ processes
+were rather isolated. We could of course pass information to \METAPOST\ and pick
+up information from \METAPOST\ in a second pass. That has changed in \LUATEX.
+
+In order to really integrate \METAPOST\ graphics into the flow you need to know
+where you are on the page and how large graphics should be, especially when you
+want them to depend on the layout. A first solution to this was to embed specials
+in the \DVI\ that could later be used to extract positions. In retrospect this
+was a relative trivial extension, something that could have been around much
+earlier but somehow didn't happen. Anyhow, after some experiments \PDFTEX\ got a
+native position tracker which meant that no post processor was needed. Of course
+\LUATEX\ inherited this feature too. Because positioning is rather bound to the
+macro package reading this chapter only makes sense when you use \CONTEXT.
+
+\stopsection
+
+\startbuffer[arrow:1]
+\startMPpositionmethod{mypos:arrow}
+ \startMPpositiongraphic{mypos:arrow}
+ save pa, pb, pm, pab, na, nb, sa, sb ;
+ path pa, pb, pm, pab ; numeric na, nb ; string sa, sb ;
+ % the tags
+ sa := texstr("from") ;
+ sb := texstr("to") ;
+ % we need to check page crossing so we fetch the page numbers
+ na := positionpage(sa) ;
+ nb := positionpage(sb) ;
+ % we use the repositioned shapes
+ pa := positionbox(sa) ;
+ pb := positionbox(sb) ;
+ % but want circles instead of rectangles
+ pa := llcorner pa .. lrcorner pa .. urcorner pa .. ulcorner pa .. cycle ;
+ pb := llcorner pb .. lrcorner pb .. urcorner pb .. ulcorner pb .. cycle ;
+ pickup pencircle scaled 1pt ;
+ if na = nb :
+ % both are on the same page
+ fill pa withcolor .800white ;
+ fill pb withcolor .800white ;
+ draw pa withcolor .625yellow ;
+ draw pb withcolor .625yellow ;
+ pm := .5[center pa,center pb] shifted (0,2*LineHeight) ;
+ pab := center pa .. pm .. center pb ;
+ pab := pab cutbefore (pab intersectionpoint pa) ;
+ pab := pab cutafter (pab intersectionpoint pb) ;
+ drawarrow pab dashed evenly withcolor .625red ;
+ positionatanchor(sa) ;
+ elseif nb < na :
+ % they are on different pages and we're at the first one
+ fill pb withcolor .800white ;
+ draw pb withcolor .625yellow ;
+ pab := center pb {up} .. ulcorner bbox pb ;
+ pab := pab cutbefore (pab intersectionpoint pb) ;
+ drawarrow pab dashed evenly withcolor .625red ;
+ positionatanchor(sb) ;
+ else :
+ % they are on different pages and we're at the last one
+ fill pa withcolor .800white ;
+ draw pa withcolor .625yellow ;
+ pab := center pa {up} .. urcorner bbox pa ;
+ pab := pab cutbefore (pab intersectionpoint pa) ;
+ drawarrow pab dashed evenly withcolor .625red ;
+ positionatanchor(sa) ;
+ fi ;
+ \stopMPpositiongraphic
+ % we put it here at the first position
+ \MPpositiongraphic{mypos:arrow}
+ % we need to carry information forward and make sure that we also
+ % check and flush at the second position of the pair
+ \ifnum\MPp{\MPvar{from}}<\MPp{\MPvar{to}}\relax
+ \expanded{\setMPpositiongraphic{\MPvar{to}}{mypos:arrow}{to=\MPvar{from}}}
+ \fi
+\stopMPpositionmethod
+\stopbuffer
+
+\startbuffer[arrow:2]
+\setMPpositiongraphic{A-1}{mypos:arrow}{to=A-2}
+\stopbuffer
+
+\startbuffer[box:1]
+\startMPpositiongraphic{mpos:box}{fillcolor,linecolor,linewidth}
+ string tag; tag := "\MPvar{self}" ;
+ path box ; box := positionbox(tag) ;
+ box := box enlarged \MPvar{filloffset} ;
+ fill box
+ withcolor \MPvar{fillcolor} ;
+ draw box
+ withcolor \MPvar{linecolor}
+ withpen pencircle scaled \MPvar{linewidth} ;
+ positioninregion ;
+\stopMPpositiongraphic
+\stopbuffer
+
+\startbuffer[box:1:also]
+\startMPpositiongraphic{mpos:box}{fillcolor,linecolor,linewidth}
+ path box ; box := positionbox(texstr("self")) ;
+ box := box enlarged texvar("filloffset") ;
+ fill box
+ withcolor texvar("fillcolor") ;
+ draw box
+ withcolor texvar("linecolor")
+ withpen pencircle scaled texvar("linewidth") ;
+ positioninregion ;
+\stopMPpositiongraphic
+\stopbuffer
+
+\startbuffer[box:2]
+\setupMPvariables
+ [mpos:box]
+ [linecolor=blue,
+ linewidth=\linewidth,
+ fillcolor=lightgray,
+ filloffset=2pt]
+
+\setupMPvariables[mpos:box][linecolor=darkred]
+\setupMPvariables[mpos:par][linecolor=darkred]
+
+\startpositionoverlay{backgraphics}
+ \setMPpositiongraphic{A-0}{mpos:box}{self=A-0}
+ \setMPpositiongraphic{A-3}{mpos:box}{self=A-3}
+ \setMPpositiongraphic{A-4}{mpos:box}{self=A-4}
+\stoppositionoverlay
+\stopbuffer
+
+\getbuffer[arrow:1,arrow:2]
+\getbuffer[box:1,box:2]
+
+\startsection[title={The concept}]
+
+\index {graphics+positioning}
+\index {positioning}
+\index {anchoring}
+
+Because we have a \LUA\ connection in \MPLIB, we have implemented a couple of
+helpers that make live easier. This is also why the following examples are \MKIV\
+specific, although \MKII\ can do the same, but with a bit different set of
+helpers. We can for instance query properties of \hpos {A-0} {positions} without
+using \TEX\ macros but can use \METAPOST\ macros instead. Let's give an example.
+The background and frame behind the word \type {position} in this paragraph is
+not done with \type {\framed} but using a different mechanism:
+
+\starttyping
+to get \hpos {A-0} {positions} sorted
+\stoptyping
+
+The \type {\hpos} refers to a position and we have bound that position to a graphic:
+
+\starttyping
+\setMPpositiongraphic{A-0}{mpos:box}{self=A-0}
+\stoptyping
+
+The graphic itself is defined with:
+
+\typebuffer[box:1]
+
+A variant that has no macro calls and does all via the \LUA\ intercaface in \MKIV\ is
+the following:
+
+\typebuffer[box:1:also]
+
+A \type {\hpos} position has several properties: the coordinates of the origin:
+\type {x} and \type {y}, the dimensions of the boxed content, \type {w}, \type
+{h} and \type {d}, and the page number \type {p}. An additional helper \type
+{positioninregion} will move the drawing to the right spot in the region.
+Examples or regions are the page, text area or some overlay. The \type
+{positionatanchor} variant relocates to the anchor of the given tag. The first
+helper is actually a shortcut for:
+
+\starttyping
+currentpicture := currentpicture shifted - positionxy(positionanchor) ;
+\stoptyping
+
+In our case we use a dedicated layer \type {backgraphics} that we have hooked into
+the page backgrounds:
+
+\starttyping
+\setupbackgrounds
+ [page]
+ [background={backgraphics,foreground,foregraphics}]
+
+\defineoverlay [backgraphics] [\positionoverlay{backgraphics}]
+\defineoverlay [foregraphics] [\positionoverlay{foregraphics}]
+\stoptyping
+
+The relation between position graphics and that layer are defined as follows
+(we will come back to this in a moment):
+
+\typebuffer[box:2]
+
+\stopsection
+
+\startsection[title={A more detailed view}]
+
+As we know, a decent portion of \TEX's attention is focused on breaking
+paragraphs into lines and determining the optimal point to split off the page.
+Trying to locate the optimal points to break lines is a dynamic process. The
+space between words is flexible and we don't know in advance when a \hpos {A-1}
+{word} or piece of a word |<|maybe it's best to talk of typographic \hpos {A-2}
+{globs} instead|>| will end up on the page. It might even cross the page
+boundary.
+
+In the previous section we saw \hpos {A-3} {word} and \hpos {A-4} {globs}
+encircled and connected by an arrow. This graphic can be drawn only when the
+position and dimensions are known. Unfortunately, this information is only
+available after the paragraph is typeset and the best breakpoints are chosen.
+\bpos {A-5} Because the text must be laid on top of the graphic, the graphic must
+precede the first word in the typeset stream or it must be positioned on a
+separate layer. In the latter case it can be calculated directly after the
+paragraph is typeset, but in the former case a second pass is needed. \epos {A-5}
+Because such graphics are not bound to one paragraph, the multi||pass option
+suits better because it gives us more control: the more we know about he final
+state, the better we can act upon it. Think of graphics on the first page that
+depend on the content of the last page \bpos {A-6} or, as in this paragraph,
+backgrounds that depend on the typeset text. \epos {A-6}
+
+The arrows that connect the shapes are drawn with the following code that now
+looks familiar:
+
+\typebuffer[arrow:1]
+
+and
+
+\typebuffer[arrow:2]
+
+However, here we anchor at one of the positions because we don't flush in a layer
+but at the position itself. Indeed it looks complex.
+
+It may be clear now that we need some positional information in order to provide
+features like the ones shown here. The fact that we will act upon in a second
+pass simplifies the task, although it forces us to store the positional
+information between runs in some place. This may look uncomfortable at first
+sight, but it also enables us to store some additional information. Now why is
+that needed?
+
+A position has no dimensions, it's just a place somewhere on the page. In order
+to do tricks like those shown here, we also need to know the height and depth of
+lines at a specific point as well as the width of the box(es) we're dealing with.
+In the encircled examples, the dimensions of the box following the positional
+node are stored along with the position.
+
+In order to process the graphics, we tag each point with a name, so that we can
+attach actions to those points. In fact they become trigger points. As we will
+demonstrate, we also need to store the current page number. This brings the data
+stored with a point to:
+
+\starttyping
+<identifier> <pagenumber> <x> <y> <width> <height> <depth>
+\stoptyping
+
+Actually we store more information, for example the region in which the positions
+sit. Depending on the use we can also get access to paragraph and line properties
+but discussing these is beyond this manual. These are for instance used in the
+text backgrounds.
+
+The page number is needed in order to let the graphics engine determine boundary
+conditions. Backgrounds like those shown here can span multiple pages. In order
+to calculate the right backgrounds, some additional information must be
+available, like the top and bottom of the current text area. In fact, these are
+just normal points that can be saved while processing the split off page. So,
+apart from positioning anchors in the text we need anchors on crucial points of
+the layout. This means that this kind of support cannot be fully integrated into
+the \TEX\ kernel, unless we also add extensive support for layout definitions,
+and that is probably not what we want.
+
+As soon as something like $(x,y)$ shows up, a logical question is where $(0,0)$
+is located. Although this is a valid question, the answer is less important than
+you may expect. Even if we know that ($0,0)$ is \quote {officially} located in
+the bottom left corner of the page, the simple fact that in \CONTEXT\ we are
+dealing with a mixed page concept, like paper size and print paper size, or left
+and right pages, forces us to think in relative positions instead of absolute
+ones. Therefore, graphics, even those that involve multiple positions, are
+anchored to a position on the layer on which they are located.
+
+Users who simply want to use these features may wonder why we go into so much
+detail. The main reason is that in the end many users will want to go beyond the
+simple cases, and when dealing with these issues, you must be aware not only of
+height, depth and width, but also of the crossing of a page boundary, and the
+height and depth of lines. In some cases your graphics may have to respond to
+layout characteristics, like differences between odd and even pages. Given that
+unique identifiers are used for anchor points, in \CONTEXT\ you can have access
+to all the information needed. Here are some of the helpers:
+
+\starttabulate[|T||]
+\NC positionpath (tag) \NC the path determined by width, height and depth \NC \NR
+\NC positionxy (tag) \NC the origin \NC \NR
+\NC positionwhd (tag) \NC the dimensions (in a triplet) \NC \NR
+\NC positionpage (tag) \NC the page number fo the position \NC \NR
+\NC positionregion(tag) \NC the region that the position sits in \NC \NR
+\NC positionbox (tag) \NC the positioned box (path shifted over coordinates) \NC \NR
+\NC positionanchor \NC the current anchor of the region \NC \NR
+\stoptabulate
+
+The \type {positionwhd} macro returns a triplet that you can query, like:
+
+\starttyping
+triplet whd ; whd := positionwhd("\MPvar{from}");
+numeric wd; wd := wdpart whd ;
+\stoptyping
+
+We will add more such convenient helpers in the future. In the \CONTEXT\
+distribution you can find examples (in manuals or librarties) that demonstrate
+other tricks with positioning.
+
+\stopsection
+
+\startsection[title={Anchors and layers}]
+
+\index{anchoring}
+\index{layers}
+
+\startbuffer[g-circle]
+\startMPpositiongraphic{mypos:circle}
+ path p ; p := positionbox(texstr("self")) ;
+ p := fullcircle xsized (bbwidth(p)+4pt) shifted center p ;
+ pickup pencircle scaled 1pt ;
+ fill p withcolor .800white ;
+ draw p withcolor .625yellow ;
+ positioninregion ;
+\stopMPpositiongraphic
+\stopbuffer
+
+\startbuffer[g-line]
+\startMPpositiongraphic{mypos:line}
+ path pa, pb, pab ; numeric na, nb ; string ta, tb ;
+ ta := texstr("from") ;
+ tb := texstr("to") ;
+ na := positionpage(ta) ;
+ nb := positionpage(tb) ;
+ pa := positionbox(ta) ;
+ pb := positionbox(tb) ;
+ pa := fullcircle xsized (bbwidth(pa)+4pt) shifted center pa ;
+ pb := fullcircle xsized (bbwidth(pb)+4pt) shifted center pb ;
+ if na = nb :
+ pab := center pa -- center pb ;
+ pab := pab cutbefore (pab intersectionpoint pa) ;
+ pab := pab cutafter (pab intersectionpoint pb) ;
+ pickup pencircle scaled 1pt ;
+ draw pab withcolor .625yellow ;
+ positioninregion ;
+ fi ;
+\stopMPpositiongraphic
+\stopbuffer
+
+\getbuffer[g-circle,g-line]
+
+\startbuffer[a]
+\setMPpositiongraphic{X-1}{mypos:arrow}{to=X-2}
+\setMPpositiongraphic{X-2}{mypos:arrow}{to=X-3}
+\stopbuffer
+
+\startbuffer[b]
+In a previous section we saw that some \hpos {X-1} {words} were
+\hpos {X-2} {circled} and connected by an \hpos {X-3} {arrow}.
+As with most things in \CONTEXT, marking these words is separated
+from declaring what to do with those words. This paragraph is keyed
+in as:
+\stopbuffer
+
+\getbuffer[a,b]
+
+\typebuffer[b]
+
+We see three position anchors, each marked by an identifier: \type {X-1}, \type
+{X-2} and \type {X-3}. Each of these anchors can be associated with a (series) of
+graphic operations. Here we defined:
+
+\typebuffer[a]
+
+These examples clearly demonstrate that we cannot control to what extent graphics
+will cover text and vice versa. A solution to this problem is using position
+overlays. We can define such an overlay as follows:
+
+\startbuffer
+\startpositionoverlay{backgraphics}
+ \setMPpositiongraphic{G-1}{mypos:circle}
+ \setMPpositiongraphic{G-2}{mypos:circle}
+ \setMPpositiongraphic{G-3}{mypos:circle}
+ \setMPpositiongraphic{G-4}{mypos:circle}
+\stoppositionoverlay
+
+\startpositionoverlay{foregraphics}
+ \setMPpositiongraphic{G-1}{mypos:line}{to=G-2}
+ \setMPpositiongraphic{G-2}{mypos:line}{to=G-3}
+ \setMPpositiongraphic{G-3}{mypos:line}{to=G-4}
+\stoppositionoverlay
+\stopbuffer
+
+\getbuffer \typebuffer
+
+\startbuffer
+First we have defined an \hpos {G-1} {\strut overlay}. This
+overlay can be attached to some overlay layer, like, in our
+case, the \hpos {G-2} {\strut page}. We define four small \hpos
+{G-3} {\strut circles}. These are drawn as soon as the page
+overlay is typeset. Because they are located in the
+background, they don't cover the \hpos {G-4} {\strut text}, while
+the lines do. The previous paragraph was typeset by saying:
+\stopbuffer
+
+\getbuffer \typebuffer
+
+As said, the circles are on the background layer, but the lines are not! They are
+positioned on top of the text. This is a direct result of the definition of the
+page background:
+
+\starttyping
+\defineoverlay [foregraphics] [\positionoverlay{foregraphics}]
+\defineoverlay [backgraphics] [\positionoverlay{backgraphics}]
+
+\setupbackgrounds
+ [page]
+ [background={backgraphics,foreground,foregraphics}]
+\stoptyping
+
+\doifmode{screen}{\writestatus{CHECK}{POSITION GRAPHICS}}
+
+In this definition, the predefined overlay \type {foreground} inserts the page
+data itself, so the foreground graphics end up on top. This example also
+demonstrates that you should be well aware of the way \CONTEXT\ builds a page.
+There are six main layers, in some cases with sublayers. The body text goes into
+the main text layer, which, unless forced otherwise, lays on top.
+
+\startitemize[packed,n,columns,three]
+\item paper background
+\item area backgrounds
+\item page backgrounds
+\item text areas
+\item logo areas
+\item main text
+\stopitemize
+
+The paper background is used for special (sometimes internal) purposes. There are
+three page backgrounds: left, right and both. The text areas, logo areas and
+backgrounds form a $5 \times 5$ matrix with columns containing the leftedge,
+leftmargin, text, rightmargin, and rightedge. The rows of the matrix contain the
+top, header, text, footer, and bottom. The main text is what you are reading now.
+
+Since the page background is applied last, the previous layers can be considered
+to be the foreground to the page background layer. And, indeed, it is available
+as an overlay under the name \type {foreground}, as we already saw in the
+example. Foregrounds are available in most cases, but (for the moment) not when
+we are dealing with the text area. Since anchoring the graphics is implemented
+rather independent of the position of the graphics themselves, this is no real
+problem, we can put them all on the page layer, if needed in separate overlays.
+
+How is such a graphic defined? In fact these graphics are a special case of the
+already present mechanism of including \METAPOST\ graphics. The circles are
+defined as follows:
+
+\typebuffer[g-circle]
+
+Drawing the lines is handled in a similar fashion.
+
+\typebuffer[g-line]
+
+The command \tex {startMPpositiongraphic} defines a graphic, in this example we
+have called it \type {mypos:circle}. Here we show the definition out of order but
+normally you need to define it before you refer to it.
+
+The \METAPOST\ macro \type {positionbox} returns a box that is constructed from
+the coordinates and dimensions. After this call, the corners are available via
+\type {llcorner}, \type {lrcorner}, \type {urcorner} and \type {ulcorner}. The
+center is accessible by \type {center}. When we are finished drawing the graphic,
+we can anchor the result with \type {positioninregion}. This macro automatically
+handles positioning on specific layers. The helper macros are not loaded by
+default, you do that with:
+
+\typebuffer[g-include]
+
+The position macro \type {\MPpos} returns the current characteristics of a
+position. The previously defined G~positions return:
+
+\starttabulate[|c|c|c|c|c|c|c|]
+\HL
+\NC position\NC page\NC$x$\NC$y$\NC width\NC height\NC depth\NC\NR
+\HL
+\NC G-1\NC\MPp{G-1}\NC\MPx{G-1}\NC\MPy{G-1}\NC\MPw{G-1}\NC\MPh{G-1}\NC\MPd{G-1}\NC\NR
+\NC G-2\NC\MPp{G-2}\NC\MPx{G-2}\NC\MPy{G-2}\NC\MPw{G-2}\NC\MPh{G-2}\NC\MPd{G-2}\NC\NR
+\NC G-3\NC\MPp{G-3}\NC\MPx{G-3}\NC\MPy{G-3}\NC\MPw{G-3}\NC\MPh{G-3}\NC\MPd{G-3}\NC\NR
+\NC G-4\NC\MPp{G-4}\NC\MPx{G-4}\NC\MPy{G-4}\NC\MPw{G-4}\NC\MPh{G-4}\NC\MPd{G-4}\NC\NR
+\HL
+\stoptabulate
+
+The numbers represent the real pagenumber~$p$, the current position $(x,y)$, and
+the dimensions of the box $(w,h,d)$ if known. These values are fed directly into
+\METAPOST\ graphics but the individual components can be asked for by \type
+{\MPp}, \type {\MPx}, \type {\MPy}, \type {\MPw}, \type {\MPh} and \type {\MPd}.
+
+In the previous definition of the graphic, we saw another macro, \type {\MPvar}.
+When we invoke a graphic or attach a graphic to a layer, we can pass variables.
+We can also set specific variables in other ways, as we will see later.
+
+\starttyping
+\setMPpositiongraphic{G-1}{mypos:circle}
+\setMPpositiongraphic{G-1}{mypos:line}{to=G-2}
+\stoptyping
+
+In the second definition, we let the variable \type {to} point to another
+position. When needed, we can ask for the value of \type {to} by \type
+{\MPvar{to}}. For reasons of convenience, the current position is assigned
+automatically to \type {from} and \type {self}. This means that in the line we
+saw in the graphic:
+
+\starttyping
+path p ; p := positionbox(texstr("self")) ;
+\stoptyping
+
+\type {texstr("self")} will return the current position, which, fed to \type
+{positionbox} will return a box with the right dimensions. We already warned the
+reader: this is not an easy chapter.
+
+\stopsection
+
+\startsection[title={More layers}]
+
+\index{layers}
+
+\setupbackgrounds
+ [state=repeat]
+
+Overlays are one of the nicer features of \CONTEXT\ and even more nice things can
+be build on top of them. Overlays are defined first and then assigned to framed
+boxes using the \type {background} variable.
+
+You can stack overlays, which is why they are called as such. You can use the
+special overlay called \type {foreground} to move the topmost (often text) layer
+down in the stack.
+
+\starttabulate
+\HL
+\NC background overlay \NC a text, graphic, hyperlink or widget \NC \NR
+\NC position overlay \NC a series of macros triggered by positions \NC \NR
+\NC background layer \NC a box that can hold boxes with offsets \NC \NR
+\HL
+\stoptabulate
+
+The last kind of layer can be used in other situations as well, but in most cases
+it will be hooked into a background overlay.
+
+\startbuffer
+\definelayer[MyLayer][option=test]
+
+\setupbackgrounds[text][leftmargin][background=MyLayer]
+
+\setlayer[MyLayer][x=.5cm,y=5cm]
+ {\rotate{\framed{This goes to the background}}}
+\stopbuffer
+
+\typebuffer \getbuffer \setuplayer[MyLayer][option=] % no frames
+
+In this case the framed text will be placed in the background of the (current)
+page with the given offset to the topleft corner. Instead of a fixed position,
+you can inherit the current position using the \type {position} directive. Say
+that we have a layer called \type {YourLayer} which we put in the background of
+the text area.
+
+\startbuffer
+\definelayer[YourLayer]
+\setupbackgrounds[text][text][background=YourLayer]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We can now move some framed text to this layer using \type {\setlayer} with the
+directive \type {position} set to \type {yes}.
+
+\startbuffer
+here: \setlayer[YourLayer][position=yes]{\inframed{Here}}
+\stopbuffer
+
+\typebuffer
+
+You can influence the placement by explicitly providing an offset (\type
+{hoffset} and|/|or \type {voffset}), a position (\type {x} and|/|or \type {y}) or
+a location directive (\type {location}). Normally you will use the offsets for
+the layer as a whole and the positions for individual contributions. The next
+example demonstrates the use of a location directive.
+
+\startbuffer
+here: \setlayer[YourLayer][position=yes,location=c]{\inframed{Here}}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Many layers can be in use at the same time. In the next example we put something
+in the page layer. By default, we turn on position tracking, which visualizes the
+bounding box of the content and shows the reference point.
+
+\startbuffer
+\definelayer[BackLayer][position=yes]
+\setupbackgrounds[page][background=BackLayer]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\setupbackgrounds
+ [page]
+ [background={PageFrame,BackLayer,backgraphics,foreground,foregraphics}]
+
+Next we define an overlay that we can put behind for instance framed texts. We
+use \METAPOST\ to draw \type {Shape}.
+
+\startbuffer
+\defineoverlay[Shape] [BackLayer] [\uniqueMPgraphic{Shape}]
+
+\startuniqueMPgraphic{Shape}
+ path p ; p := fullcircle xyscaled(OverlayWidth,OverlayHeight) ;
+ fill p withcolor \MPcolor{lightgray} ;
+ draw p withpen pencircle scaled 1pt withcolor \MPcolor{darkred} ;
+\stopuniqueMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer[def]
+\defineframed[Shaped][background=Shape,frame=off,location=low]
+\stopbuffer
+
+\getbuffer[def]
+
+We can now put this background shape behind the running text, for instance with:
+
+\startbuffer
+.... some \inframed[background=Shape]{text} with a frame ...
+.... some \Shaped{text} with a frame ...
+\stopbuffer
+
+\typebuffer
+
+\startlines
+\getbuffer
+\stoplines
+
+The \type {\Shaped} macro was defined as:
+
+\typebuffer[def]
+
+Watch how the graphics are moved to the background while the frame of the first
+text stays on top, since it remains part of the text flow.
+
+\startbuffer[def]
+\setuplayer[BackLayer][direction=reverse]
+\stopbuffer
+
+\getbuffer[def]
+
+\startlines
+\getbuffer
+\stoplines
+
+In the previous instance of the example we have reversed the stacking. Reversal
+can be done with the \type {direction} directive.
+
+\typebuffer[def]
+
+% next series
+
+\startbuffer
+\setuplayer
+ [BackLayer]
+ [position=no,corner=bottom,height=\paperheight]
+
+\setlayer[BackLayer][x=2cm,y=10cm,location=bl]
+ {\externalfigure[somecow.pdf][width=1cm]}
+
+\setlayer[BackLayer][x=1cm,y=8cm,location=br]
+ {\externalfigure[somecow.pdf][width=1cm]}
+
+\setlayer[BackLayer][x=2cm,y=4cm,location=tl]
+ {\externalfigure[somecow.pdf][width=1cm]}
+
+\setlayer[BackLayer][x=10cm,y=1cm,location=tr]
+ {\externalfigure[somecow.pdf][width=1cm]}
+\stopbuffer
+
+You can influence the placement of a background component by using a different
+anchor point.
+
+\typebuffer {\setuplayer[option=test]\getbuffer}
+
+\startbuffer[xx]
+\setuplayer
+ [BackLayer]
+ [position=no,corner=bottom,height=\paperheight]
+
+\setlayer[BackLayer][x=15cm,y=5cm,location=bl]
+ {\externalfigure[somecow.pdf][width=3cm]}
+
+\setlayer[BackLayer][x=15cm,y=5cm,location=br]
+ {\externalfigure[somecow.pdf][width=3cm]}
+
+\setlayer[BackLayer][x=15cm,y=5cm,location=tl]
+ {\externalfigure[somecow.pdf][width=2cm]}
+
+\setlayer[BackLayer][x=15cm,y=5cm,location=tr]
+ {\externalfigure[somecow.pdf][width=2cm]}
+
+\setlayer[BackLayer][x=15cm,y=5cm,location=c]
+ {\externalfigure[somecow.pdf][width=3cm]}
+\stopbuffer
+
+% \startpostponing
+
+Instead of using relative positions, you can also use absolute ones. Of course
+you need to know how your coordinates relate to the rest of the layout
+definition.
+
+\typebuffer[xx]
+
+These examples again demonstrate how we can influence the placement by assigning
+an anchor point to \type {position}. Here we also put the reference point in the
+lower left corner (\type {bottom}). This mechanism only works when we also use
+\type {height}.
+
+{\setuplayer[option=test]\getbuffer[xx]}
+
+\page
+
+% \stoppostponing
+
+\setupbackgrounds
+ [page]
+ [background={PageFrame,DemoLayer,backgraphics,foreground,foregraphics}]
+
+\definelayer
+ [DemoLayer]
+ [position=yes]
+
+\startbuffer
+\definelayer
+ [DemoLayer]
+ [position=yes]
+
+\startplacefigure[title={Demo 1}]
+ \ruledhbox\bgroup
+ \setlayerframed
+ [DemoLayer] [hoffset=-10mm,voffset=5mm]
+ {\startMPcode
+ fill fullcircle scaled 2cm withcolor .625red ;
+ \stopMPcode}%
+ \setlayerframed
+ [DemoLayer] [voffset=-10mm]
+ {\startMPcode
+ fill fullcircle scaled 2cm withcolor .625green ;
+ \stopMPcode}%
+ \setlayerframed
+ [DemoLayer] [hoffset=10mm,voffset=5mm]
+ {\startMPcode
+ fill fullcircle scaled 2cm withcolor .625blue ;
+ \stopMPcode}%
+ \egroup
+\stopplacefigure
+\stopbuffer
+
+\getbuffer
+
+One of the reasons for developing the layer mechanism was that we needed to
+slightly change the position of figures in the final stage of typesetting. The
+previous pages demonstrate how one can position anything anywhere on the page,
+but in the case of figures the position may depend on where the text ends up on
+the page.
+
+Normally, when you manipulate a document this way, you are in the final stage of
+typesetting. You may qualify this as desk top publishing without actually using a
+desktop.
+
+\typebuffer
+
+\startbuffer[demo]
+\startbuffer
+\setlayer [DemoLayer]
+ [position=yes,
+ voffset=-1.5cm,
+ width=3cm,
+ height=2cm]
+ {\MPfigure{somecow.pdf}{scaled .5 slanted .5}}
+\stopbuffer
+
+\placefigure[right]{}{\ruledhbox{\getbuffer}}
+\stopbuffer
+
+{\setuplayer[option=test]\getbuffer[demo]}
+
+The previous example also demonstrated the use of \METAPOST\ for rotating the
+picture. The \type {\MPfigure} macro encapsulates the code in a shortcut. You can
+achieve special effects by using the layers behind floating bodies and alike, but
+always keep in mind that the readability of the text should not be violated too
+much.
+
+\typebuffer[demo]
+
+In these examples we added a \type {\ruledhbox} around the pseudo graphics so
+that you can see what the size is of those graphics.
+
+% summary
+
+We have already seen a lot of parameters that can be used to control the content
+of a layer. There are a few more. General housekeeping takes place with:
+
+\starttabulate[|Tl|Tl|l|]
+\HL
+\NC state \NC start \NC enable the layer \NC \NR
+\NC \NC stop \NC disable the layer \NC \NR
+\NC position \NC no \NC use absolute positions \NC \NR
+\NC \NC yes \NC use relative positions \NC \NR
+\NC \NC overlay \NC idem, but ignore the size \NC \NR
+\NC direction \NC normal \NC put new data on top \NC \NR
+\NC \NC reverse \NC put new data below old data \NC \NR
+\HL
+\stoptabulate
+
+Sometimes all data needs to be offset in a similar way. You can use both offset
+parameters for that.
+
+\starttabulate[|Tl|l|]
+\HL
+\NC hoffset \NC an additional horizontal displacement \NC \NR
+\NC voffset \NC an additional vertical displacement \NC \NR
+\HL
+\stoptabulate
+
+You can position data anywhere in the layer. When positioning is turned on, the
+current position will get a placeholder. You can change the dimensions of that
+placeholder (when \type {position} is set to \type {overlay}), zero dimensions
+are used.
+
+\starttabulate[|Tl|l|]
+\HL
+\NC x \NC the horizontal displacement \NC \NR
+\NC y \NC the vertical displacement \NC \NR
+\NC width \NC the (non natural) width \NC \NR
+\NC height \NC the (non natural) height \NC \NR
+\NC location \NC \tttf l r t b c lt lb rt rb \NC \NR
+\HL
+\stoptabulate
+
+The \type {location} directive determines what point of the data is used as
+reference point. You can keep track of this point and the placement when you
+enable test mode. This is how the rectangles in the previous examples were
+drawn.
+
+\starttabulate[|Tl|Tl|l|]
+\HL
+\NC option \NC test \NC show positioning information \NC \NR
+\HL
+\stoptabulate
+
+When you are enhancing the final version of a document, you can explicitly
+specify on what page the data will go. Use this option with care.
+
+\starttabulate[|Tl|l|]
+\HL
+\NC page \NC the page where the data will go \NC \NR
+\HL
+\stoptabulate
+
+Because layers can migrate to other pages, they may disappear due to the
+background not being recalculated. In case of doubt, you can force repetitive
+background calculation by:
+
+\starttyping
+\setupbackgrounds[state=repeat]
+\stoptyping
+
+% restore 'm
+
+\setupbackgrounds
+ [page]
+ [background={PageFrame,backgraphics,foreground,foregraphics}]
+
+\setupbackgrounds
+ [state=start]
+
+\stopsection
+
+\startsection[title={Complex text in graphics}]
+
+\index{text}
+
+If you like to embed \METAPOST\ snippets in \CONTEXT, you may want to combine
+text and graphics and let \METAPOST\ provide the position and the dimensions of
+the text to be typeset outside by \TEX. For most applications using the \METAFUN\
+\type {textext} macro works well enough, but when the typeset text needs to
+communicate with the typesetting engine, for instance because it contains
+hyperlinks or references, you can use the following method:
+
+\startitemize[packed]
+\item define a layer
+\item define a (reusable) graphic
+\item put your text into the layer
+\item combine the graphic with the text
+\stopitemize
+
+You must be aware of the fact that when the layer is flushed, its content is
+gone. You can take advantage of this by using the same graphic with multiple
+texts.
+
+\startbuffer
+\definelayer[test]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+You don't need to pass the width and height explicitly, but when you do so, you
+have access to them later.
+
+\startbuffer
+\startuseMPgraphic{oeps}
+ path p ; p := fullcircle scaled 6cm ;
+ fill p withcolor .8white ;
+ draw p withpen pencircle scaled 1mm withcolor .625red ;
+ register ("somepos-1",0cm,0cm,center currentpicture) ;
+ register ("somepos-2",3cm,1cm,(-1cm,-1cm)) ;
+ register ("somepos-3",2cm,0cm,(-2cm,2cm)) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The \METAFUN\ \type {register} macro takes the following arguments:
+
+\starttyping
+register ("tag",width,height,(x offset,y offset)) ;
+\stoptyping
+
+The width and height are available in the macros \type {\MPlayerwidth} and \type
+{\MPlayerheight} and are equivalent to \type {\MPw{tag}} and \type {\MPh{tag}},
+
+\startbuffer
+\setMPlayer [test] [somepos-1] [location=c]
+ {Does it work al right?}
+
+\setMPlayer [test] [somepos-2]
+ {\framed
+ [width=\MPlayerwidth,height=\MPlayerheight,
+ background=color,backgroundcolor=white]
+ {It Works!}}
+
+\setMPlayer [test] [somepos-3]
+ {\externalfigure[cow-fun.mps][width=2cm]}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Combining the graphic and the text is handled by the macro \type {\getMPlayer}.
+
+\startbuffer
+\getMPlayer [test] {\useMPgraphic{oeps}}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The macro \type {\getMPlayer} is built on top of \type {\framed}. The settings
+passed in the (optional) second argument are the same as those to \type
+{\framed}.
+
+\starttyping
+\getMPlayer
+ [test]
+ [frame=on,offset=5pt]
+ {\useMPgraphic{oeps}}
+\stoptyping
+
+As you see, you need a bit of a twisted mind to handle graphics this way, but at
+least the functionality is there to create complex graphics in a declarative way.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-reference.tex b/doc/context/sources/general/manuals/metafun/metafun-reference.tex
new file mode 100644
index 000000000..6eb177949
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-reference.tex
@@ -0,0 +1,659 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-reference
+
+\environment metafun-environment
+
+\startchapter[reference=reference,title={Reference}]
+
+\startintro
+
+In this chapter, we will demonstrate most of the drawing related primitives and
+macros as present in plain \METAPOST\ and \METAFUN\ extensions.
+
+If a path is shown and|/|or a transformation is applied, we show the original in
+red and the transformed path or point in yellow. The small dark gray crosshair is
+the origin and the black rectangle the bounding box. In some drawings, in light
+gray we show the points that make up the path.
+
+This list describes traditional \METAPOST\ and the stable part of \METAFUN. As
+\METAPOST\ evolves, new primitives are added but they are not always that
+relevant to us. If you browse the \METAFUN\ sources you will for sure notice more
+functionality than summarized here. Most of that is meant for usage in \CONTEXT\
+and not exposed to the user. Other macros are still somewhat experimental but
+might become more official at some point. The same is true for \METAFUN\
+commands: not all make sense for daily usage and some are just there as helper
+for additional modules.
+
+\stopintro
+
+\startsection[title={Paths}]
+
+\index{paths}
+
+\ShowSampleA {mc} {pair} {(1,.5)}
+\ShowSampleA {mm} {pair .. pair} {(0,0)..(.75,0)..(1,.25)..(1,1)}
+\ShowSampleA {mm} {pair ... pair} {(0,0)..(.75,0)...(1,.25)..(1,1)}
+\ShowSampleA {mm} {pair -- pair\quad (a)} {(0,0)--(.75,0)--(1,.25)--(1,1)}
+\ShowSampleA {mm} {pair -- pair\quad (b)} {(0,0)..(.75,0)--(1,.25)..(1,1)}
+\ShowSampleA {mm} {pair --- pair} {(0,0)..(.75,0)---(1,.25)..(1,1)}
+
+\ShowSampleA {mm} {pair softjoin pair} {(0,0)..(.75,0) softjoin (1,.25)..(1,1)}
+\ShowSampleA {mp} {controls pair} {(0,0)..controls (.75,0)..(1,1)}
+\ShowSampleA {mp} {controls pair and pair} {(0,0)..controls (.75,0) and (1,.25)..(1,1)}
+\ShowSampleA {mp} {tension numeric} {(0,0)..(.75,0)..tension 2.5..(1,.25)..(1,1)}
+\ShowSampleA {mp} {tension num.. and num..} {(0,0)..(.75,0)..tension 2.5 and 1.5..(1,.25)..(1,1)}
+\ShowSampleA {mp} {tension atleast numeric} {(0,0)..(.75,0)..tension atleast 1..(1,.25)..(1,1)}
+
+\ShowSampleA {mp} {cycle} {(0,0)--(1,0)--(1,1)--cycle}
+\ShowSampleA {mp} {curl numeric} {(0,0){curl 1}..(.75,0)..(1,.25)..(1,1)}
+\ShowSampleA {mp} {dir numeric} {(0,0){dir 30}..(1,1)}
+\ShowSampleA {mm} {left} {(0,0){left}..(1,1)}
+\ShowSampleA {mm} {right} {(0,0){right}..(1,1)}
+\ShowSampleA {mm} {up} {(0,0){up}..(1,1)}
+\ShowSampleA {mm} {down} {(0,0){down}..(1,1)}
+
+\ShowSampleA {mp} {path \& path} {(0,0)..(.75,.25) \& (.75,.25)..(1,1)}
+
+\ShowSampleA {mv} {unitvector} {origin--unitvector(1,1)}
+\ShowSampleA {mp} {dir} {origin--dir(45)}
+\ShowSampleA {mp} {angle} {origin--dir(angle(1,1))}
+
+\ShowSampleA {mv} {fullcircle} {fullcircle}
+\ShowSampleA {fv} {unitcircle} {unitcircle}
+\ShowSampleA {fv} {fullsquare} {fullsquare}
+\ShowSampleA {mv} {unitsquare} {unitsquare}
+\ShowSampleA {fv} {fulltriangle}{fulltriangle}
+\ShowSampleA {fv} {unittriangle}{unittriangle}
+\ShowSampleA {fv} {fulldiamond} {fulldiamond}
+\ShowSampleA {fv} {unitdiamond} {unitdiamond}
+
+\ShowSampleA {mv} {halfcircle} {halfcircle}
+\ShowSampleA {mv} {quartercircle} {quartercircle}
+
+\ShowSampleA {fv} {llcircle} {llcircle}
+\ShowSampleA {fv} {lrcircle} {lrcircle}
+\ShowSampleA {fv} {urcircle} {urcircle}
+\ShowSampleA {fv} {ulcircle} {ulcircle}
+\ShowSampleA {fv} {tcircle} {tcircle}
+\ShowSampleA {fv} {bcircle} {bcircle}
+\ShowSampleA {fv} {lcircle} {lcircle}
+\ShowSampleA {fv} {rcircle} {rcircle}
+
+\ShowSampleA {fv} {triangle} {triangle}
+\ShowSampleA {fv} {righttriangle} {righttriangle}
+\ShowSampleA {fv} {uptriangle} {uptriangle}
+\ShowSampleA {fv} {lefttriangle} {lefttriangle}
+\ShowSampleA {fv} {downtriangle} {downtriangle}
+
+\ShowSampleA {fv} {lltriangle} {lltriangle}
+\ShowSampleA {fv} {lrtriangle} {lrtriangle}
+\ShowSampleA {fv} {urtriangle} {urtriangle}
+\ShowSampleA {fv} {ultriangle} {ultriangle}
+
+\ShowSampleA {mm} {flex(pair,pair,pair)}
+ {flex ((0,0),(1,1),(1,0))}
+\ShowSampleA {mm} {superellipse(pair,p..,p..,p..,num..)}
+ {superellipse((1,.5),(.5,1),(0,.5),(.5,0),.75)}
+
+\ShowSampleA {fm} {path smoothed numeric/pair} {unitsquare scaled 1.5 smoothed .2}
+\ShowSampleA {fm} {path cornered numeric/pair} {lltriangle scaled 1.5 cornered .2}
+\ShowSampleA {fm} {path superellipsed numeric} {unitsquare scaled 1.5 superellipsed .75}
+\ShowSampleA {fm} {path randomized numeric/pair} {unitsquare scaled 1.5 randomized (.2,.2)}
+\ShowSampleA {fm} {path randomizedcontrols numeric/pair} {fullcircle scaled 1.5 randomizedcontrols (.2,.2)}
+\ShowSampleA {fm} {path squeezed numeric/pair} {unitsquare scaled 1.5 squeezed (.2,.1)}
+\ShowSampleA {fm} {path snapped numeric/pair} {fullcircle scaled 1.5 snapped (.2,.1)}
+
+\ShowSampleB {fm} {punked path}
+ {unitcircle scaled 1.5}
+ {punked unitcircle scaled 1.5}
+
+\ShowSampleB {fm} {curved path}
+ {((0,0)--(.2,1)--(1,.2)--cycle)}
+ {curved ((0,0)--(.2,1)--(1,.2)--cycle)}
+
+\ShowSampleB {fm} {laddered path}
+ {((0,0)--(1.4,.8)--(2.8,1.2)--(6.2,1.6))}
+ {laddered ((0,0)--(1.4,.8)--(2.8,1.2)--(6.2,1.6))}
+
+\ShowSampleB {fm} {path paralleled distance}
+ {((0,0)--(5,1))}
+ {((0,0)--(5,1)) paralleled .25}
+
+\ShowSampleB {fm} {shortened path}
+ {((0,0)--(6,1))}
+ {((0,0)--(6,1)) shortened 1}
+
+\ShowSampleB {fm} {unspiked path}
+ {((0,0)--(1,0)--(1,1)--(2,1)--(1,1)--(0,1)) shifted (-3,0)}
+ {unspiked ((0,0)--(1,0)--(1,1)--(2,1)--(1,1)--(0,1))}
+
+\ShowSampleB {fm} {simplified path}
+ {((0,0)--(1,0)--(2,0)--(2,1)--(0,1)--cycle) shifted (-3,0)}
+ {simplified ((0,0)--(1,0)--(2,0)--(2,1)--(0,1)--cycle)}
+
+\ShowSampleB {fm} {path blownup numeric/pair}
+ {fullcircle scaled 1.5}
+ {(fullcircle scaled 1.5) blownup .1}
+
+\ShowSampleB {fm} {path stretched numeric/pair\quad (a)}
+ {fullcircle scaled 1.5}
+ {(fullcircle scaled 1.5) stretched (1.1,0.8)}
+
+\ShowSampleB {fm} {path stretched numeric\quad (b)}
+ {((0,0)--(1,1))}
+ {((0,0)--(1,1)) stretched 1.5}
+
+\ShowSampleB {fm} {path xstretched numeric}
+ {fullcircle}
+ {fullcircle xstretched 5}
+
+\ShowSampleB {fm} {path ystretched numeric}
+ {fullcircle}
+ {fullcircle ystretched 1.5}
+
+\ShowSampleB {fm} {path enlonged numeric}
+ {((0,0)--(1,1))}
+ {((0,0)--(1,1)) enlonged 1.5}
+
+\ShowSampleB {fm} {path shorted numeric}
+ {((0,0)--(2,2))}
+ {((0,0)--(2,2)) shortened 0.5}
+
+\ShowSampleA {fm} {roundedsquare(num..,num..,num..)}
+ {roundedsquare(2,1,.2)}
+
+\ShowSampleA {fm} {tensecircle(num..,num..,num..)}
+ {tensecircle(2,1,.2)}
+
+\ShowSampleA {fm} {pair crossed size}
+ {origin crossed 1}
+
+\ShowSampleA {fm} {path crossed size}
+ {fullcircle scaled 2 crossed .5}
+
+\ShowSampleA {fm} {(constructed)function}
+ {constructedfunction("--")("x","sin(x)",0,2pi,pi/10)}
+
+\ShowSampleA {fm} {curvedfunction}
+ {curvedfunction("x","sin(x)",0,2pi,pi/10)}
+
+\ShowSampleA {fm} {straightfunction}
+ {straightfunction("x","sin(x)",0,2pi,pi/10)}
+
+\ShowSampleA {fm} {constructedpath}
+ {constructedpath("..")((0,0),(1,2),(2,1),(3,2))}
+
+\ShowSampleA {fm} {curvedpath}
+ {curvedpath((0,0),(1,2),(2,1),(3,2))}
+
+\ShowSampleA {fm} {straightpath}
+ {straightpath((0,0),(1,2),(2,1),(3,2))}
+
+\ShowSampleA {fm} {leftarrow}
+ {leftarrow(fullcircle,3,2)}
+
+\ShowSampleA {fm} {rightarrow}
+ {rightarrow(fullcircle,3,2)}
+
+\ShowSampleA {fm} {centerarrow}
+ {centerarrow(fullcircle,3,2)}
+
+\ShowSampleX {fm} {arrowhead} {draw arrowhead fullcircle}
+\ShowSampleX {fm} {arrowpath} {draw arrowpath fullcircle}
+
+\ShowSampleA {mm} {buildcycle}
+ {buildcycle(fullcircle,fullsquare)}
+
+\ShowSampleA {fm} {circularpath} {circularpath(4)}
+\ShowSampleA {fm} {squarepath} {squarepath(4)}
+\ShowSampleA {fm} {linearpath} {linearpath(4)}
+
+\stopsection
+
+\startsection[title={Transformations}]
+
+\index{transformations}
+
+\ShowSampleB {mp} {path scaled numeric} {fullcircle} {fullcircle scaled .50}
+\ShowSampleB {mp} {path xscaled numeric} {fullcircle} {fullcircle xscaled .25}
+\ShowSampleB {mp} {path yscaled numeric} {fullcircle} {fullcircle yscaled .25}
+\ShowSampleB {mp} {path zscaled pair} {fullcircle} {fullcircle zscaled (2,.25)}
+\ShowSampleB {mp} {path xyscaled numeric/pair} {fullcircle} {fullcircle xyscaled (.5,.7)}
+\ShowSampleB {mp} {path xyscaled pair} {fullcircle} {fullcircle xyscaled (2,.25)}
+\ShowSampleB {mp} {path shifted pair} {fullcircle} {fullcircle shifted (2,.25)}
+
+\ShowSampleB {fm} {path leftenlarged numeric} {fullsquare} {fullsquare leftenlarged .25}
+\ShowSampleB {fm} {path topenlarged numeric} {fullsquare} {fullsquare topenlarged .25}
+\ShowSampleB {fm} {path rightenlarged numeric} {fullsquare} {fullsquare rightenlarged .25}
+\ShowSampleB {fm} {path bottomenlarged numeric} {fullsquare} {fullsquare bottomenlarged .25}
+
+\ShowSampleB {fm} {path enlarged numeric} {fullcircle} {fullcircle enlarged .25}
+\ShowSampleB {fm} {path enlarged pair} {fullcircle} {fullcircle enlarged (1,.25)}
+\ShowSampleB {fm} {path llenlarged numeric} {fullcircle} {fullcircle llenlarged .25}
+\ShowSampleB {fm} {path lrenlarged numeric} {fullcircle} {fullcircle lrenlarged .25}
+\ShowSampleB {fm} {path urenlarged numeric} {fullcircle} {fullcircle urenlarged .25}
+\ShowSampleB {fm} {path ulenlarged numeric} {fullcircle} {fullcircle ulenlarged .25}
+\ShowSampleB {fm} {path llenlarged pair} {fullcircle} {fullcircle llenlarged (1,.25)}
+\ShowSampleB {fm} {path lrenlarged pair} {fullcircle} {fullcircle lrenlarged (1,.25)}
+\ShowSampleB {fm} {path urenlarged pair} {fullcircle} {fullcircle urenlarged (1,.25)}
+\ShowSampleB {fm} {path ulenlarged pair} {fullcircle} {fullcircle ulenlarged (1,.25)}
+\ShowSampleB {fm} {path llmoved numeric} {fullcircle} {fullcircle llmoved .25}
+\ShowSampleB {fm} {path lrmoved numeric} {fullcircle} {fullcircle lrmoved .25}
+\ShowSampleB {fm} {path urmoved numeric} {fullcircle} {fullcircle urmoved .25}
+\ShowSampleB {fm} {path ulmoved numeric} {fullcircle} {fullcircle ulmoved .25}
+\ShowSampleB {fm} {path llmoved pair} {fullcircle} {fullcircle llmoved (1,.25)}
+\ShowSampleB {fm} {path lrmoved pair} {fullcircle} {fullcircle lrmoved (1,.25)}
+\ShowSampleB {fm} {path urmoved pair} {fullcircle} {fullcircle urmoved (1,.25)}
+\ShowSampleB {fm} {path ulmoved pair} {fullcircle} {fullcircle ulmoved (1,.25)}
+\ShowSampleB {mp} {path slanted numeric} {fullcircle} {fullcircle slanted .5}
+\ShowSampleB {mp} {path rotated numeric} {fullsquare} {fullsquare rotated 45}
+
+\ShowSampleB {mm} {path rotatedaround(pair,numeric)} {fullsquare} {fullsquare rotatedaround((.25,.5),45)}
+\ShowSampleB {mm} {path reflectedabout(pair,pair)} {fullcircle} {fullcircle reflectedabout((.25,-1),(.25,+1))}
+\ShowSampleB {mp} {reverse path} {fullcircle} {reverse fullcircle shifted(.5,0)}
+\ShowSampleB {mm} {counterclockwise path} {fullcircle} {counterclockwise fullcircle shifted(.5,0)}
+\ShowSampleB {mm} {tensepath path} {fullcircle} {tensepath fullcircle}
+
+\ShowSampleB {mp} {subpath (numeric,numeric) of path} {fullcircle} {subpath (1,5) of fullcircle}
+\ShowSampleB {mm} {path cutbefore pair} {fullcircle} {fullcircle cutbefore point 3 of fullcircle}
+\ShowSampleB {mm} {path cutafter pair} {fullcircle} {fullcircle cutafter point 3 of fullcircle}
+\ShowSampleB {mm} {path cutends .1} {fullcircle} {fullcircle cutends .5}
+
+\ShowSampleC {mp} {llcorner path} {fullcircle} {llcorner fullcircle}
+\ShowSampleC {mp} {lrcorner path} {fullcircle} {lrcorner fullcircle}
+\ShowSampleC {mp} {urcorner path} {fullcircle} {urcorner fullcircle}
+\ShowSampleC {mp} {ulcorner path} {fullcircle} {ulcorner fullcircle}
+\ShowSampleC {mm} {center path} {fullcircle} {center fullcircle}
+
+\ShowSampleD {fm} {boundingbox path} {fullcircle} {boundingbox fullcircle}
+\ShowSampleD {fm} {boundingcircle path} {fullsquare} {boundingcircle fullsquare}
+\ShowSampleD {fm} {innerboundingbox path} {fullcircle} {innerboundingbox fullcircle}
+\ShowSampleD {fm} {outerboundingbox path} {fullcircle} {outerboundingbox fullcircle}
+
+\ShowSampleDD {fm} {bottomboundary path} {fullcircle} {bottomboundary fullcircle}
+\ShowSampleDD {fm} {leftboundary path} {fullcircle} {leftboundary fullcircle}
+\ShowSampleDD {fm} {topboundary path} {fullcircle} {topboundary fullcircle}
+\ShowSampleDD {fm} {rightboundary path} {fullcircle} {rightboundary fullcircle}
+
+\ShowSampleP {fm} {bbwidth path} {draw textext(decimal bbwidth (fullcircle xscaled 100 yscaled 200))}
+\ShowSampleP {fm} {bbwidth path} {draw textext(decimal bbheight (fullcircle xscaled 100 yscaled 200))}
+
+\ShowSampleE {fm} {path/picture xsized numeric} {xsized 3cm} {currentpicture xsized 5cm}
+\ShowSampleE {fm} {path/picture ysized numeric} {ysized 2cm} {currentpicture ysized 2cm}
+\ShowSampleE {fm} {path/picture xysized numeric} {xysized (3cm,2cm)} {currentpicture xysized (3cm,2cm)}
+
+\ShowSampleP {fm}
+ {area path}
+ {draw area ((0,10)--(20,20)--(30,5)--(40,10)--(50,5)--(60,5))}
+
+\ShowSampleT {mp}
+ {setbounds picture}
+ {draw fullcircle ; setbounds currentpicture to unitsquare}
+ {draw fullcircle scaled .5 InGray; setbounds currentpicture to unitsquare scaled .5}
+
+\ShowSampleT {mm}
+ {clip path}
+ {fill fullcircle ; clip currentpicture to fullsquare scaled 0.9}
+ {fill fullcircle scaled 1 InRed ; clip currentpicture to fullsquare scaled 0.9}
+
+\ShowSampleT {mm}
+ {path peepholed path}
+ {fill (fullcircle peepholed fullsquare)}
+ {fill (fullcircle peepholed fullsquare) InRed}
+
+\ShowSampleT {fm}
+ {anchored}
+ {draw anchored.urt(textext("ll"),origin)}
+ {draw anchored.urt(textext("ll") xsized (5mm/Scale),origin) InRed ;}
+
+% \ShowSampleT {fm}
+% {autoalign}
+% {draw textext.autoalign(260)("260")}
+% {draw textext.autoalign(260)("260")}
+
+% draw textext.autoalign(260)("\strut oeps 3") ;
+
+\ShowSampleX {fm}
+ {path crossingunder path}
+ {draw (fullsquare rotated 45) crossingunder fullsquare}
+
+\stopsection
+
+\startsection[title={Points}]
+
+\index{points}
+
+%ShowSampleF {mp} {center path} {fullcircle} {center fullcircle}
+\ShowSampleF {mm} {top pair} {fullcircle} {top center fullcircle}
+\ShowSampleF {mm} {bot pair} {fullcircle} {bot center fullcircle}
+\ShowSampleF {mm} {lft pair} {fullcircle} {lft center fullcircle}
+\ShowSampleF {mm} {rt pair} {fullcircle} {rt center fullcircle}
+\ShowSampleF {mp} {point numeric of path} {fullcircle} {point 2 of fullcircle}
+\ShowSampleF {fm} {point numeric on path} {fullcircle} {point .5 on fullcircle}
+\ShowSampleF {fm} {point numeric along path} {fullcircle} {point 1cm along fullcircle}
+\ShowSampleF {mp} {precontrol numeric of path} {fullcircle} {precontrol 2 of fullcircle}
+\ShowSampleF {mp} {postcontrol numeric of path} {fullcircle} {postcontrol 2 of fullcircle}
+\ShowSampleF {mp} {directionpoint pair of path} {fullcircle} {directionpoint (2,3) of fullcircle}
+
+\ShowSampleG {mc} {numeric[pair,pair]} {(1,1)} {.5[(0,0),(1,1)]}
+
+\ShowSampleH {mm} {path intersectionpoint path} {fullcircle} {fulldiamond}
+ {fullcircle intersectionpoint fulldiamond}
+
+\ShowSampleHH {mm} {interpath(numeric,path,path}
+ {interpath(.8,fullcircle,fullsquare)}
+
+\ShowSampleHH {fm} {interpolated(numeric,path,path}
+ {interpolated(.8,fullcircle,fullsquare)}
+
+\ShowSampleO {mm} {right} {draw left}
+\ShowSampleO {mm} {up} {draw up}
+\ShowSampleO {mm} {left} {draw left}
+\ShowSampleO {mm} {down} {draw down}
+
+\stopsection
+
+\startsection[title={Colors}]
+
+\index{colors}
+
+\ShowSampleI {mp} {withcolor rgbcolor} {withcolor (.625,0,0)}
+\ShowSampleI {mp} {withrgbcolor rgbcolor} {withrgbcolor (.625,0,0)}
+\ShowSampleI {mp} {withcmykcolor cmykcolor} {withcmykcolor (.375,0,0,0)}
+\ShowSampleI {mp} {withgray / withgrey numeric} {withgray .625}
+\ShowSampleI {mp} {withcolor namedcolor} {withcolor namedcolor("darkblue")}
+\ShowSampleI {mp} {withcolor spotcolor} {withcolor spotcolor("tempone",red/2)}
+\ShowSampleI {mp} {withcolor multitonecolor} {withcolor .2 * multitonecolor("temptwo",blue/2,yellow/3)}
+
+Remark: at the time of this writing only Acrobat shows spot- and multitonecolors
+properly. Possible indications of a viewing problem are factors not being applied
+(in the page stream) or colors that are way off.
+
+\ShowSampleU {mp} {red} {fill fullcircle scaled 2 withcolor red/2}
+\ShowSampleU {mp} {green} {fill fullcircle scaled 2 withcolor green/2}
+\ShowSampleU {mp} {blue} {fill fullcircle scaled 2 withcolor blue/2}
+\ShowSampleU {mp} {cyan} {fill fullcircle scaled 2 withcolor cyan/2}
+\ShowSampleU {mp} {magenta} {fill fullcircle scaled 2 withcolor magenta/2}
+\ShowSampleU {mp} {yellow} {fill fullcircle scaled 2 withcolor yellow/2}
+\ShowSampleU {mp} {black} {fill fullcircle scaled 2 withcolor black/2}
+\ShowSampleU {mp} {white} {fill fullcircle scaled 2 withcolor white/2}
+
+\ShowSampleU {mp} {blackcolor} {fill fullcircle withcolor blackcolor red}
+
+%ShowSampleI {fm} {withcolor cmyk(c,m,y,k)} {withcolor cmyk(0,.625,.625,0)}
+%ShowSampleI {fm} {withcolor transparent(n.m,color)} {withcolor transparent(1,.625,red)}
+
+\ShowSampleI {fm} {withtransparency(num,num)} {withcolor red withtransparency (1,.625)}
+
+% \ShowSampleZ {fm} {withshade numeric} {Shades need to be declared before they can be (re)used.}
+
+\startMPinclusions
+ defineshade cshade withshademethod "circular" ;
+ defineshade lshade withshademethod "linear" ;
+\stopMPinclusions
+
+\ShowSampleW {fm} {shaded someshade }
+ {fill fullsquare shaded lshade}
+ {fill fullsquare scaled 2cm shaded lshade}
+
+This assumes the definition:
+
+\starttyping
+defineshade lshade withshademethod "linear" ;
+\stoptyping
+
+\ShowSampleW {fm} {shaded someshade}
+ {fill fullcircle shaded cshade}
+ {fill fullcircle scaled 2cm shaded cshade}
+
+This assumes the definition:
+
+\starttyping
+defineshade cshade withshademethod "circular" ;
+\stoptyping
+
+% withshadefactor 1
+% withshadedomain (0,1)
+% withshadecolors (black,white)
+% withtransparency (1,.5)
+
+% \startMPcode
+% fill fullcircle scaled 3cm
+% shaded myshade
+% withshadefactor 0.7
+% ;
+% \stopMPcode
+
+% \startMPcode
+% fill fullcircle scaled 3cm
+% shaded myshade
+% withshadecolors (red,green)
+% withshadefactor 1
+% withtransparency (1,.75)
+% ;
+% \stopMPcode
+
+% \startMPcode
+% fill fullcircle scaled 3cm
+% shaded myshade ;
+% withshadefactor 1
+% withshadedomain (0,1)
+% withshadecolors (green,blue)
+% withtransparency (1,.5)
+% ;
+% \stopMPcode
+
+% \startMPcode
+% fill fullcircle scaled 3cm
+% shaded myshade ;
+% withshadefactor 1
+% withshadedomain (0,1)
+% withcolor blue shadedinto yellow
+% withtransparency (1,.5)
+% ;
+% \stopMPcode
+
+\ShowSampleV {mp}
+ {basiccolors}
+ {for i=0 upto 21 : fill ... withcolor basiccolors[i] ; endfor}
+ {for i=0 upto 21 : fill fullcircle shifted (i,0) withcolor basiccolors[i] ; endfor}
+
+\stopsection
+
+\startsection[title={Attributes}]
+
+\index{attributes}
+
+\ShowSampleII {mp} {dashed withdots} {dashed withdots}
+\ShowSampleII {mp} {dashed evenly} {dashed evenly}
+\ShowSampleII {mp} {dashed oddly} {dashed oddly}
+\ShowSampleII {mp} {dashpattern} {dashed dashpattern (on .1 off .2 on .3 off .4)}
+\ShowSampleII {mp} {undashed} {dashed evenly undashed}
+
+\ShowSampleJ {mm} {pencircle transform} {pencircle}
+\ShowSampleJ {mm} {pensquare transform} {pensquare}
+\ShowSampleJ {mm} {penrazor transform} {penrazor}
+\ShowSampleK {mm} {penspeck transform} {penspeck}
+
+\ShowSampleL {mm} {draw} {fullcircle}
+\ShowSampleL {mm} {fill} {fullcircle}
+\ShowSampleL {mm} {filldraw} {fullcircle}
+\ShowSampleL {mm} {drawfill} {fullcircle}
+\ShowSampleL {mm} {drawdot} {origin}
+\ShowSampleL {mm} {drawarrow} {fullcircle}
+\ShowSampleL {mm} {drawdblarrow} {fullcircle}
+
+\ShowSampleL {fm} {eofill} {fullcircle}
+
+\ShowSampleM {mm} {undraw} {fullcircle}
+\ShowSampleM {mm} {unfill} {fullcircle}
+\ShowSampleM {mm} {unfilldraw} {fullcircle}
+\ShowSampleM {mm} {undrawfill} {fullcircle}
+\ShowSampleM {mm} {undrawdot} {origin}
+
+\ShowSampleQ {mm} {cutdraw} {origin--(1,1)}
+
+\ShowSampleN {mv} {butt} {linecap := butt} {(0,.5)--(.5,0)--(1,1)}
+\ShowSampleN {mv} {rounded} {linecap := rounded} {(0,.5)--(.5,0)--(1,1)}
+\ShowSampleN {mv} {squared} {linecap := squared} {(0,.5)--(.5,0)--(1,1)}
+
+\ShowSampleN {mv} {mitered} {linejoin := mitered} {(0,.5)--(.5,0)--(1,1)}
+\ShowSampleN {mv} {rounded} {linejoin := rounded} {(0,.5)--(.5,0)--(1,1)}
+\ShowSampleN {mv} {beveled} {linejoin := beveled} {(0,.5)--(.5,0)--(1,1)}
+
+\ShowSampleR {fm} {inverted picture} {inverted currentpicture}
+\ShowSampleR {fm} {picture uncolored color} {currentpicture uncolored green}
+\ShowSampleR {fm} {picture softened numeric} {currentpicture softened .8}
+\ShowSampleR {fm} {picture softened color} {currentpicture softened (.7,.8,.9)}
+\ShowSampleR {fm} {grayed picture} {grayed currentpicture}
+
+\stopsection
+
+\startsection[title={Text}]
+
+\index{text}
+
+\ShowSampleO {mm} {label} {label("MetaFun",origin)}
+\ShowSampleO {mm} {label.top} {label.top("MetaFun",origin)}
+\ShowSampleO {mm} {label.bot} {label.bot("MetaFun",origin)}
+\ShowSampleO {mm} {label.lft} {label.lft("MetaFun",origin)}
+\ShowSampleO {mm} {label.rt} {label.rt("MetaFun",origin)}
+\ShowSampleO {mm} {label.llft} {label.llft("MetaFun",origin)}
+\ShowSampleO {mm} {label.lrt} {label.lrt("MetaFun",origin)}
+\ShowSampleO {mm} {label.urt} {label.urt("MetaFun",origin)}
+\ShowSampleO {mm} {label.ulft} {label.ulft("MetaFun",origin)}
+
+\ShowSampleW {mp} {dotlabel}
+ {dotlabel.bot("\tttf metafun",(2cm,1cm))}
+ {dotlabel.bot("\tttf metafun",(2cm,1cm))}
+
+\ShowSampleW {mp} {dotlabels + range .. thru ..}
+ {z1 = ... ; dotlabels.bot(range 1 thru 3)}
+ {z1=(0,0); z2=(10mm,10mm); z3=(20mm,15mm); ; z4=(30mm,5mm); dotlabels.bot(range 1 thru 4)}
+
+\ShowSampleW {mp} {labels + range .. thru ..}
+ {z1 = ... ; labels.bot(range 1 thru 3)}
+ {z1=(0,0); z2=(10mm,10mm); z3=(20mm,15mm); ; z4=(30mm,5mm); labels.bot(range 1 thru 4)}
+
+\ShowSampleQQ {fm}
+ {thelabel(string,pair)}
+ {draw thelabel("MetaFun",(2cm,0))}
+
+\ShowSampleQQ {fm}
+ {formatted(string)}
+ {draw textext(formatted("@0.5f",1.234))}
+
+\ShowSampleQQ {fm}
+ {format(string) : graph package}
+ {draw textext(format("@5E-2",1.234))}
+
+\ShowSampleP {mp}
+ {btex text etex}
+ {draw btex MetaTeX etex}
+
+\ShowSampleQQ {fm}
+ {textext(string)}
+ {draw textext("MetaFun")}
+
+\ShowSampleQQ {fm}
+ {thetextext(string,pair)}
+ {draw thetextext("MetaFun",(2cm,0))}
+
+% \ShowSampleQQ {fm}
+% {graphictext string ...}
+% {graphictext "MetaFun"}
+
+\ShowSampleQQQ {fm}
+ {outlinetext.d("string")(d)}
+ {draw outlinetext.d("MetaFun")(InRed)}
+
+\ShowSampleQQQ {fm}
+ {outlinetext.f("string")(f)}
+ {draw outlinetext.f("MetaFun")(InYellow)}
+
+\ShowSampleQQQ {fm}
+ {outlinetext.b("string")(f)(d)}
+ {draw outlinetext.b("MetaFun")(InYellow)(InRed)}
+
+\ShowSampleQQQ {fm}
+ {outlinetext.r("string")(d)(f)}
+ {draw outlinetext.r("MetaFun")(InRed)(InYellow)}
+
+\ShowSampleUU {fm}
+ {outlinetext.p("string")}
+ {draw outlinetext.p("MetaFun")}
+
+\stopsection
+
+\startsection[title={Control}]
+
+\index{loops}
+
+\ShowSampleU {mp} {for (positive step) until} {for i=0 step 2 until 8: drawdot (i,0) ; endfor}
+\ShowSampleU {mp} {for (negative step) until} {for i=6 step -2 until 0: drawdot (i,0) ; endfor}
+\ShowSampleU {mm} {for upto} {for i=0 upto 12: drawdot (i,0) ; endfor}
+\ShowSampleU {mm} {for downto} {for i=10 downto 0: drawdot (i,0) ; endfor}
+\ShowSampleU {mm} {forsuffixes} {forsuffixes i=1,4,6,12: drawdot (i,0) ; endfor}
+
+\stopsection
+
+\startsection[title={Graphics}]
+
+\index{graphics}
+
+\ShowSampleS {fm}
+ {loadfigure string number numeric ...}
+ {loadfigure "mycow.mp" number 1 scaled .25}
+
+\ShowSampleS {fm}
+ {externalfigure string ...}
+ {draw externalfigure "mycow.pdf" scaled 3cm}
+
+\ShowSampleT {fm} {addbackground text}
+ {addbackground withcolor .625 yellow}
+ {fill fullcircle xyscaled (2,1) InRed; addbackground InYellow}
+
+\ShowSampleQQ {mm} {image (text)}
+ {draw image(draw fullcircle) xscaled 4cm yscaled 1cm}
+
+\ShowSampleT {mm} {decorated (text) text}
+ {draw decorated (....) withcolor red}
+ {draw decorated (fill fullcircle) InRed}
+
+\ShowSampleT {mm} {undecorated (text) text}
+ {draw undecorated (.... withcolor yellow) withcolor red}
+ {draw undecorated (fill fullcircle InYellow) InRed}
+
+\ShowSampleT {mm} {redecorated (text) text}
+ {draw redecorated (.... withcolor yellow) withcolor red}
+ {draw redecorated (fill fullcircle InYellow) InRed}
+
+\ShowSampleS {mm}
+ {bitmapimage (w,h,data)}
+ {draw bitmapimage (2,2,"114477AA") rotated 15 scaled 4cm}
+
+\ShowSampleT {mm}
+ {withmask string}
+ {draw externalfigure "m-1.png" scaled 2cm withmask "m-2.png"}
+ {Scale := 1 ;
+ draw externalfigure "m-2.png" scaled 2cm shifted (-3cm,0) ;
+ draw externalfigure "m-1.png" scaled 2cm shifted (-6cm,0) ;
+ draw externalfigure "m-1.png" scaled 2cm withmask "m-2.png"}
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
+
+%% draw leftpath fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625red ;
+%% draw reverse leftpath (reverse fullcircle scaled 2cm) withpen pencircle scaled 1mm withcolor .625yellow ;
+%% draw rightpath fullcircle scaled 3cm withpen pencircle scaled 1mm withcolor .625white ;
+%%
+%% path p ; p := (0,0) .. (1,2) .. cycle ;
+%% draw leftpath p scaled 1cm withpen pencircle scaled 1mm withcolor .625red ;
+%% draw reverse leftpath (reverse p scaled 2cm) withpen pencircle scaled 1mm withcolor .625yellow ;
+%% draw rightpath p scaled 3cm withpen pencircle scaled 1mm withcolor .625white ;
diff --git a/doc/context/sources/general/manuals/metafun/metafun-sneaky.tex b/doc/context/sources/general/manuals/metafun/metafun-sneaky.tex
new file mode 100644
index 000000000..02c502cf0
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-sneaky.tex
@@ -0,0 +1,60 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-conventions
+
+\environment metafun-environment
+
+\startchapter[title={Conventions}]
+
+\startsection[title={Suffixes}]
+
+One characteristic of using \METAFUN\ in \CONTEXT\ is that it is basically one
+long run. The code snippets become figures that then get converted to \PDF\ and
+embedded. If text is involved, each figure is actually processed twice, once to
+identify what needs to be typeset, and once with the result(ing metrics).
+Normally that gets unnoticed. You can check for the state by consulting the
+boolean \type {mfun_trial_run}.
+
+A consequence of the one run cq.\ multiple runs is that you need to be careful with
+undefined or special variables. Consider the following:
+
+\starttyping
+vardef foo@#(text t) =
+ save s ; string s ; s := str @# ;
+ if length(s) > 0 :
+ textext(s)
+ else :
+ nullpicture
+ fi
+enddef ;
+\stoptyping
+
+The following works ok in the first run when bar is undefined:
+
+\starttyping
+draw foo.bar("a") ;
+\stoptyping
+
+But if afterwards we say:
+
+\starttyping
+vardef bar(expr x) =
+ 123
+enddef ;
+\stoptyping
+
+and expand \type {foo.bar} again we will get an error message because this time
+\type {bar} expands. Suffixes are always expanded!
+
+The lesson is: when you get unexpected results or errors, check your variable
+definitions. You can use the \type {begingroup} and \type {endgroup} primitives
+to protect your variables but then you also need to explicitly use \type {save}
+to store their meanings and allocate new ones after that inside the group.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-styles.tex b/doc/context/sources/general/manuals/metafun/metafun-styles.tex
new file mode 100644
index 000000000..f82359117
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-styles.tex
@@ -0,0 +1,445 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-styles
+
+\environment metafun-environment
+
+\startchapter[title={Defining styles}]
+
+\index {layout}
+\index {styles}
+
+\startintro
+
+Since the integration of \METAPOST\ into \CONTEXT, a complete new range of layout
+fetaures became available. In this document we have introduced several ways to
+include graphics in your document definition. In this chapter we go one step
+further and make dynamic graphics part of a document style.
+
+\stopintro
+
+\startsection[title={Adaptive buttons}]
+
+So far we have seen a lot of graphic ingredients that you can use to make your
+documents more attractive. In this chapter we will define a simple document
+style. This style was written for the \PDFTEX\ presentations at the TUG 2000
+conference in Oxford (UK).
+
+This style exploits a few tricks, like graphics calculated using positional
+information. It also demonstrates how you can make menu buttons that dynamically
+adapt their shapes to the rest of the page layout.
+
+\startbuffer[screens]
+\startlinecorrection[blank]
+\setupcombinations[distance=.0125\textwidth]
+\startcombination[5*1]
+ {\typesetfile[mfun-77\ScrNum.tex][page=1,width=.19\textwidth]} {page 1}
+ {\typesetfile[mfun-77\ScrNum.tex][page=2,width=.19\textwidth]} {page 2}
+ {\typesetfile[mfun-77\ScrNum.tex][page=3,width=.19\textwidth]} {page 3}
+ {\typesetfile[mfun-77\ScrNum.tex][page=4,width=.19\textwidth]} {page 4}
+ {\typesetfile[mfun-77\ScrNum.tex][page=5,width=.19\textwidth]} {page 5}
+\stopcombination
+\stoplinecorrection
+\stopbuffer
+
+\def\ScrNum{1} \getbuffer[screens]
+
+Later we will see an instance with some more randomness in the graphics. While
+writing this style, the random alternative made me think of those organic
+buildings with non equal windows |<|we have a few of those in The Netherlands|>|,
+so I decided to label this style as \type {pre-organic}. If you use \CONTEXT, you
+can load this style with:
+
+\starttyping
+\usemodule[pre-organic]
+\stoptyping
+
+At the end of this file, there is a small test file, so when you process the file
+\type {s-pre-19.tex} \footnote {This style is the 19\high{th} presentation style.
+Those numbered styles are internally mapped onto more meaningful names like in
+this case \type {pre-organic}.} with the options \type {--mode=demo} and \type
+{--pdf}, you will get a demo document.
+
+We use one of the standard screen \quote {paper} sizes, and map it onto the same
+size, so that we get a nicely cropped page. Other screen sizes are \type {S4} and
+\type {S5}.
+
+\starttyping
+\setuppapersize[S6][S6]
+\stoptyping
+
+Like in this \METAFUN\ manual, we use the Palatino as main bodyfont. This font is
+quite readable on even low resolution screens, although I admit that this style
+is developed using an $1400\times1050$ pixel \kap {lcd} screen, so the author may
+be a little biased.
+
+\starttyping
+\setupbodyfont[ppl]
+\stoptyping
+
+The layout specification sets up a text area and a right edge area where the
+menus will go (see \in {chapter} [sec:page] for a more in depth discussion on the
+layout areas). Watch how we use a rather large edge distance. By setting the
+header and footer dimensions to zero, we automatically get rid of page body
+ornaments, like the page number.
+
+\starttyping
+\setuplayout
+ [topspace=48pt,
+ backspace=48pt,
+ cutspace=12pt,
+ width=400pt,
+ margin=0cm,
+ rightedge=88pt,
+ rightedgedistance=48pt,
+ header=0cm,
+ footer=0cm,
+ height=middle]
+\stoptyping
+
+We use a moderate, about a line height, inter||paragraph white space.
+
+\starttyping
+\setupwhitespace[big]
+\stoptyping
+
+Of course we use colors, since on computer displays they come for free.
+
+\starttyping
+\setupcolors[state=start]
+
+\definecolor [red] [r=.75]
+\definecolor [yellow] [r=.75,g=.75]
+\definecolor [gray] [s=.50]
+\definecolor [white] [s=.85]
+\stoptyping
+
+Because it is an interactive document, we have to enable hyperlinks and alike.
+However, in this style, we disable the viewer's \quote {highlight a hyperlink
+when it's clicked on} feature. We will use a menu, so we enable menus. Later we
+will see the contrast color |<|hyperlinks gets that color when we are already on
+the location|>| in action.
+
+\starttyping
+\setupinteraction
+ [state=start,
+ click=off,
+ color=red,
+ contrastcolor=gray,
+ menu=on]
+\stoptyping
+
+The menu itself is set up as follows. Because we will calculate menu buttons
+based on their position on the page, we have to keep track of the positions.
+Therefore, we set the \type {position} variable to \type {yes}.
+
+\starttyping
+\setupinteractionmenu
+ [right]
+ [frame=off,
+ position=yes,
+ align=middle,
+ topoffset=-.75cm,
+ bottomoffset=-.75cm,
+ color=gray,
+ contrastcolor=gray,
+ style=bold,
+ before=,
+ after=]
+\stoptyping
+
+The menu content is rather sober: just a list of topics and a close button. Later
+we will define the command that generates topic entries. The alternative \type
+{right} lets the topic list inherit its characteristics from the menu.
+
+\starttyping
+\startinteractionmenu[right]
+ \placelist[Topic][alternative=right]
+ \vfill
+ \but [CloseDocument] close \\
+\stopinteractionmenu
+\stoptyping
+
+We have now arrived at the more interesting part of the style definition: the
+graphic that goes in the page background. Because this graphic will change, we
+define a useable \METAPOST\ graphic. Page backgrounds are recalculated each page,
+opposite to the other backgrounds that are calculated when a new background is
+defined, or when repetitive calculation is turned on.
+
+\starttyping
+\setupbackgrounds [page] [background=page]
+\defineoverlay [page] [\useMPgraphic{page}]
+\setupMPvariables [page] [alternative=3]
+\stoptyping
+
+We will implement three alternative backgrounds. First we demonstrate the
+relatively simple super ellipsed one. The main complication is that we want the
+button shapes to follow the right edge of the curve that surrounds the text. We
+don't know in advance how many lines of text there will be in a button, and we
+also don't know at what height it will end up. Therefore, we need to calculate
+each button shape independently and for that purpose we need to know its position
+(see \in {chapter} [sec:positioning]). In \in {figure} [fig:style] you can see
+what lines we need in order to be calculate the button shapes.
+
+\startpostponing
+
+\startmode[screen]
+ \placefigure
+ [here][fig:style]
+ {The lines used to calculate the button shapes.}
+ {\externalfigure[mfun-774.pdf][page=1,height=.85\textheight]}
+\stopmode
+
+\startnotmode[screen]
+ \placefigure
+ [here][fig:style]
+ {The auxiliary lines used to calculate the button shapes.}
+ {\rotate{\externalfigure[mfun-774.pdf][page=1,height=\textwidth]}}
+\stopnotmode
+
+\page
+
+\stoppostponing
+
+We separate the calculation of the button shape from the rest by embedding it in
+its own usable graphic container. The \type {StartPage}||\type {StopPage} pair
+takes care of proper placement of the whole graphic.
+
+\starttyping
+\startuseMPgraphic{page}
+
+ \includeMPgraphic{rightsuperbutton}
+
+ StartPage ;
+
+ path p, q ; pickup pencircle scaled 3pt ;
+
+ p := Field[Text][Text] enlarged 36pt superellipsed .90 ;
+
+ fill Page withcolor \MPcolor{yellow} ;
+ fill p withcolor \MPcolor{white} ;
+ draw p withcolor \MPcolor{red} ;
+
+ p := Field[Text][Text] enlarged 48pt superellipsed .90 ;
+
+ def right_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) =
+ if (pp>0) and (rr>0) :
+ q := rightsuperbutton(p,xx,yy,RightEdgeWidth,hh) ;
+ fill q withcolor \MPcolor{white} ;
+ draw q withcolor if rr=2 : \MPcolor{gray}
+ else : \MPcolor{red} fi ;
+ fi ;
+ enddef ;
+
+ \MPmenubuttons{right}
+
+ StopPage ;
+\stopuseMPgraphic
+\stoptyping
+
+The \TEX\ macro \type {\MPmenubuttons} expands into a list of (in this case four)
+calls to the \METAPOST\ macro \type {right_menu_button}. This list is generated
+by \CONTEXT\ when it generates the menu. Because the page background is applied
+last, this list is available at that moment.
+
+\starttyping
+... (expr nn, rr, pp, xx, yy, ww, hh, dd) ...
+\stoptyping
+
+This rather long list of arguments represents the following variables: number,
+referred page, current page, x coordinate, y coordinate, width, height and depth.
+The last six variables originate from the positioning mechanism. Because the
+variables are only available after a second \TEX\ pass, we only draw a button
+shape when the test for the page numbers succeeds.
+
+\starttyping
+\startuseMPgraphic{rightsuperbutton}
+ vardef rightsuperbutton (expr pat, xpos, ypos, wid, hei) =
+
+ save p, ptop, pbot, t, b, edge, shift, width, height ;
+ path p, ptop, pbot ; pair t, b ;
+ numeric edge, shift, width, height ;
+
+ edge := xpos + wid ; shift := ypos + hei ;
+
+ p := rightpath pat ;
+
+ ptop := ((-infinity,shift)--(edge,shift)) ;
+ pbot := ((-infinity,shift-hei)--(edge,shift-hei)) ;
+
+ t := p intersectionpoint ptop ;
+ b := p intersectionpoint pbot ;
+
+ p := subpath(0,xpart (p intersectiontimes ptop)) of p ;
+ p := subpath(xpart (p intersectiontimes pbot),length(p)) of p ;
+
+ (p -- t -- point 1 of ptop &
+ point 1 of ptop -- point 1 of pbot &
+ point 1 of pbot -- b
+ -- cycle)
+
+ enddef ;
+\stopuseMPgraphic
+\stoptyping
+
+The calculation of the button itself comes down to combining segments of the main
+shape and auxiliary lines. The \type {rightpath} macro returns the right half of
+the path provided. This half is shown as a non dashed line.
+
+Topics are identified with \type {\Topic}, which is an instance of chapter
+headings. The number is made invisible. Since it still is a numbered section
+header, \CONTEXT\ will write the header to the table of contents.
+
+\starttyping
+\definehead [Topic] [chapter]
+\setuphead [Topic] [number=no]
+\stoptyping
+
+We will use a bold font in the table of contents. We also force a complete list.
+
+\starttyping
+\setuplist
+ [Topic]
+ [criterium=all,
+ style=bold,
+ before=,
+ after=]
+\stoptyping
+
+The \type {\TitlePage} macro looks horrible, because we want to keep the
+interface simple: a list of small sentences, separated by \type {\\}.
+
+\starttyping
+\def\TitlePage#1%
+ {\startstandardmakeup
+ \switchtobodyfont[big]
+ \def\\{\vfill\bfb\let\\=\par}
+ \bfd\setupinterlinespace\gray
+ \vskip.5cm#1\\\vskip.5cm % \\ is really needed -)
+ \stopstandardmakeup}
+\stoptyping
+
+A presentation that uses this style, may look like the one below. You can choose
+among three alternatives.
+
+\starttyping
+\useenvironment[pre-organic] \setupoutput[pdftex]
+
+\setupMPvariables[page][alternative=1]
+
+\starttext
+
+\TitlePage
+ {A Few Nice Quotes\\
+ A Simple Style Demo\\
+ Hans Hagen, August 2000}
+
+\Topic {Douglas R. Hofstadter} \input douglas \page
+\Topic {Donald E. Knuth} \input knuth \page
+\Topic {Edward R. Tufte} \input tufte \page
+\Topic {Hermann Zapf} \input zapf \page
+
+\stoptext
+\stoptyping
+
+We will not implement the two other alternative shapes: squeezed and randomized.
+
+\def\ScrNum{2} \getbuffer[screens]
+\def\ScrNum{3} \getbuffer[screens]
+
+We combine all alternatives into one page graphic. The alternative is chosen by
+setting the \type {alternative} variable, as we demonstrated in the example.
+
+\starttyping
+\startuseMPgraphic{page}
+
+ \includeMPgraphic{rightsuperbutton}
+
+ StartPage ;
+
+ numeric alternative, seed, superness, squeezeness, randomness ;
+ path p, q ; transform t ;
+\stoptyping
+
+This is one of those cases where a transform variable is useful. We need to store
+the random seed value because we want the larger path that is used in the
+calculations to have the same shape.
+
+\starttyping
+ alternative := \MPvar{alternative} ;
+ seed := uniformdeviate 100 ;
+
+ if alternative > 10 :
+ superness := .85 + ((\realfolio-1)/max(\lastpage,1)) * .25 ;
+ squeezeness := 12pt - ((\realfolio-1)/max(\lastpage,1)) * 10pt ;
+ else :
+ superness := .90 ;
+ squeezeness := 12pt ;
+ fi ;
+
+ randomness := squeezeness ;
+
+ alternative := alternative mod 10 ;
+\stoptyping
+
+If you read closely, you will notice that when we add 10 to the alternative, we
+get a page dependant graphic. So, in fact we have five alternatives. We use
+\CONTEXT\ macros to fetch the (real) page number and the number of the last page.
+In further calculations we use the lower alternative numbers, which is why we
+apply a \type {mod}.
+
+The rest of the code is not so much different from the previous definition. The
+hard coded point sizes match the page dimensions (600pt by 450pt) quite well.
+
+\starttyping
+ t := identity if alternative=3: shifted (9pt,-9pt) fi ;
+
+ randomseed := seed ;
+
+ p := Field[Text][Text] enlarged if
+ alternative = 1 : 36pt superellipsed superness elseif
+ alternative = 2 : 36pt squeezed squeezeness elseif
+ alternative = 3 : 36pt randomized randomness else
+ : 36pt fi ;
+
+ pickup pencircle scaled 3pt ;
+
+ fill Page withcolor \MPcolor{yellow} ;
+ fill p withcolor \MPcolor{white} ;
+ draw p withcolor \MPcolor{red} ;
+
+ randomseed := seed ;
+
+ p := ( Field[Text][Text] enlarged if
+ alternative = 1 : 48pt superellipsed superness elseif
+ alternative = 2 : 48pt squeezed squeezeness elseif
+ alternative = 3 : 36pt randomized randomness else
+ : 48pt fi ) transformed t ;
+
+ def right_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) =
+ if (pp>0) and (rr>0) :
+ q := rightsuperbutton(p,xx,yy,RightEdgeWidth,hh) ;
+ fill q withcolor \MPcolor{white} ;
+ draw q withcolor if rr=2 : \MPcolor{gray}
+ else : \MPcolor{red} fi ;
+ fi ;
+ enddef ;
+
+ \MPmenubuttons{right}
+
+ StopPage ;
+\stopuseMPgraphic
+\stoptyping
+
+When we choose the alternatives~21 and~22 we get this result:
+
+\def\ScrNum{5} \getbuffer[screens]
+\def\ScrNum{6} \getbuffer[screens]
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-syntax.tex b/doc/context/sources/general/manuals/metafun/metafun-syntax.tex
new file mode 100644
index 000000000..9407b1dd0
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-syntax.tex
@@ -0,0 +1,1130 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+% eoclip: no postscript possible yet
+%
+% mpprocset mpxbreak
+
+% path expression -> path
+
+% listsize
+% copylist
+% sortlist
+% shapedlist
+% listtocurves
+% listtolines
+
+\startcomponent metafun-syntax
+
+\environment metafun-environment
+
+\startchapter[title={\METAPOST\ syntax}]
+
+\index{syntax}
+\index{language}
+
+\startintro
+
+In the \METAFONT\ book as well as the \METAPOST\ manual, you can find the exact
+specification of the language. Below you find the full \METAPOST\ syntax, to
+which we add the basic \METAFUN\ extensions. If this page looks too cryptic, you
+can safely skip to the next chapter. We don't distinguish between primitives and
+functionality defined in the \METAPOST\ format, simply because the core is kept
+small and a macro package is supposed to extend that core.
+
+\stopintro
+
+% \startsection[title={Syntax diagrams}]
+
+The following syntax diagrams are derived from the diagrams in the \METAPOST\
+manual. The \mathematics {\rightarrow} represents \quote {means} and the
+\mathematics {\vert} symbol stands for \quote {or}.
+
+The diagrams describe the hard coded \METAPOST\ syntax as well as most of the
+macros and variables defined in the plain \METAPOST\ format that belongs to the
+core of the system. They also include most of the fundamental \METAFUN\ commands.
+We have omitted the \METAPOST\ and \METAFONT\ commands that make no sense any
+more or are irrelevant for common usage. Specific \METAFUN\ modules are not
+included here, only general tools, text helpers and extensions to the built||in
+capabilities like transparency. If you feel that something is missing that should
+be specified here, just let me know.
+
+\start \switchtobodyfont[8pt] % small]
+
+\StartSyntax
+\S{atom}
+ \M \S{variable} \S{argument}
+ \O \S{number or fraction}
+ \O \S{internal variable}
+ \O \( \S{expression} \)
+ \O \L{begingroup} \S{statement list} \S{expression} \L{endgroup}
+ \O \S{nullary op}
+ \O \L{btex} \S{typesetting command} \L{etex}
+ % \O \L{verbatimtex} \S{typesetting command} \L{etex}
+ \O \S{pseudo function}
+\StopSyntax
+
+\StartSyntax
+\S{primary}
+ \M \S{atom}
+ \O \( \S{numeric expression} \L{,} \S{numeric expression} \)
+ \O \( \S{numeric expression} \L{,} \S{numeric expression} \L{,} \S{numeric expression} \)
+ \O \( \S{numeric expression} \L{,} \S{numeric expression} \L{,} \S{numeric expression} \L{,} \S{numeric expression} \)
+ \O \S{of operator} \S{expression} \L{of} \S{primary}
+ \O \S{numeric expression} \S{expression} \FL{along} \S{path expression}
+ \O \S{numeric expression} \S{expression} \FL{on} \S{path expression}
+ \O \S{unary op} \S{primary}
+ \O \L{str} \S{suffix}
+ \O \L{z} \S{suffix}
+ \O \S{numeric atom} \[ \S{expression} \L{,} \S{expression} \]
+ \O \S{scalar multiplication op} \S{primary}
+ \O \S{color expression} \FL{shadedinto} \S{color expression}
+ \O \S{picture expression} \FL{asgroup} \S{string expression}
+ \O \S{picture expression} \FL{onlayer} \S{string expression}
+\StopSyntax
+
+\StartSyntax
+\S{secondary}
+ \M \S{primary}
+ \O \S{secondary} \S{primary binop} \S{primary}
+ \O \S{secondary} \S{transformer}
+\StopSyntax
+
+\StartSyntax
+\S{tertiary}
+ \M \S{secondary}
+ \O \S{tertiary} \S{secondary binop} \S{secondary}
+\StopSyntax
+
+\StartSyntax
+\S{subexpression}
+ \M \S{tertiary}
+ \O \S{path expression} \S{path join} \S{path knot}
+\StopSyntax
+
+\StartSyntax
+\S{expression}
+ \M \S{subexpression}
+ \O \S{expression} \S{tertiary binop} \S{tertiary}
+ \O \S{path subexpression} \S{direction specifier}
+ \O \S{path subexpression} \S{path join} \L{cycle}
+\StopSyntax
+
+\StartSyntax
+\S{path knot}
+ \M \S{tertiary}
+\StopSyntax
+
+\StartSyntax
+\S{path join}
+ \M \L{--}
+ \O \S{direction specifier} \S{basic path join} \S{direction specifier}
+\StopSyntax
+
+\StartSyntax
+\S {direction specifier}
+ \M \S{empty}
+ \O \{ \L{curl} \S{numeric expression} \}
+ \O \{ \S{pair expression} \}
+ \O \{ \S{numeric expression} \L{,} \S{numeric expression} \}
+\StopSyntax
+
+\StartSyntax
+\S{basic path join}
+ \M \L{..}
+ \O \L{...}
+ \O \L{..} \S{tension} \L{..}
+ %O \L{..} \S{tension} \L{..} % check what got lost here
+ \O \L{..} \S{controls} \L{..}
+\StopSyntax
+
+\StartSyntax % atleast added
+\S{tension}
+ \M \L{tension} \S{numeric primary}
+ \O \L{tension} \L{atleast} \S{numeric primary}
+ \O \L{tension} \S{numeric primary} \L{and} \S{numeric primary}
+\StopSyntax
+
+\StartSyntax
+\S{controls}
+ \M controls \S{pair primary}
+ \O controls \S{pair primary} \L{and} \S{pair primary}
+\StopSyntax
+
+\StartSyntax
+\S{argument}
+ \M \S{symbolic token}
+\StopSyntax
+
+\StartSyntax
+\S{number or fraction}
+ \M \S{number} \L{/} \S{number}
+ \O \S{number} \Q{not followed by} \L{/} \S{number}
+\StopSyntax
+
+\StartSyntax
+\S{scalar multiplication op}
+ \M \L{+} \O \L{-}
+ \O \S{number or fraction} \Q{not followed by} \S{add op} \S{number}
+\StopSyntax
+
+\StartSyntax
+\S{transformer}
+ \M \L {rotated} \S {numeric primary}
+ \O \L {scaled} \S {numeric primary}
+ \O \L {shifted} \S {pair primary}
+ \O \L {slanted} \S {numeric primary}
+ \O \L {transformed} \S {transform primary}
+ \O \L {xscaled} \S {numeric primary} \O \L {yscaled} \S {numeric primary} \O \FL{xyscaled} \S {numeric or pair primary}
+ \O \L {zscaled} \S {pair primary}
+ \O \L {reflectedabout} \L \( \S{pair expression} \L{,} \S{pair expression} \)
+ \O \L {rotatedaround} \L \( \S{pair expression} \L{,} \S{numeric expression} \)
+ \O \FL{xsized} \S {numeric primary} \O \FL{ysized} \S {numeric primary} \O \FL{xysized} \S {numeric or pair primary}
+ \O \FL{blownup} \S {numeric or pair primary}
+ \O \FL{enlarged} \S {numeric or pair primary}
+ \O \FL{xstretched} \S {numeric primary} \O \FL{ystretched} \S{numeric primary} \O \FL{stretched} \S{numeric or pair primary}
+ \O \FL{shortened} \S {numeric or pair primary}
+ \O \FL{enlonged} \S {numeric or pair primary}
+ \O \FL{crossed} \S {numeric primary}
+ \O \FL{paralelled} \S {numeric primary}
+ \O \FL{curved} \S {numeric primary}
+ \O \FL{laddered}
+ \O \FL{leftenlarged} \S{numeric primary} \O \FL{llenlarged} \S{numeric primary} \O \FL{llmoved} \S{numeric primary}
+ \O \FL{rightenlarged} \S{numeric primary} \O \FL{lrenlarged} \S{numeric primary} \O \FL{lrmoved} \S{numeric primary}
+ \O \FL{topenlarged} \S{numeric primary} \O \FL{urenlarged} \S{numeric primary} \O \FL{urmoved} \S{numeric primary}
+ \O \FL{bottomenlarged} \S{numeric primary} \O \FL{ulenlarged} \S{numeric primary} \O \FL{ulmoved} \S{numeric primary}
+ \O \FL{randomized} \S{numeric or pair or color primary}
+ \O \FL{randomizedcontrols} \S{numeric or pair}
+ \O \FL{snapped} \S{numeric or pair primary}
+ \O \FL{cornered} \S{numeric or pair}
+ \O \FL{peepholed} \S{path expression}
+ \O \FL{smoothed} \S{numeric or pair}
+ \O \FL{squeezed} \S{numeric or pair primary}
+ \O \FL{superellipsed} \S{numeric primary}
+ \O \FL{randomshifted} \S{numeric or pair primary}
+ \O \FL{uncolored} \S{color primary}
+ \O \FL{softened} \S{numeric or color primary}
+ \O \FL{asgroup} \S{string primary}
+ \O \L {gobbled} \S{primary}
+ %
+ \O \FL {insideof} \S{path expression}
+ \O \FL {outsideof} \S{path expression}
+ \O \FL {crossinunder} \S{path expression}
+\StopSyntax
+
+\StartSyntax
+\S{numeric or pair primary}
+ \M \S{numeric primary}
+ \O \S{pair primary}
+\StopSyntax
+
+\StartSyntax
+\S{numeric or pair or color primary}
+ \M \S{numeric primary}
+ \O \S{pair primary}
+ \O \S{color primary}
+\StopSyntax
+
+\StartSyntax
+\S{numeric or color primary}
+ \M \S{numeric primary}
+ \O \S{color primary}
+\StopSyntax
+
+\StartSyntax
+\S{nullary op}
+ \M \L{false} \O \L{true}
+ \O \L{normaldeviate}
+ \O \L{nullpen} \O \L{nullpicture} \O \L{pencircle}%
+ \O \L{whatever}
+\StopSyntax
+
+\StartSyntax
+\S{unary op}
+ \M \S{type}
+ \O \L {ASCII}
+ \O \FL{asin} \O \FL{asinh} \O \FL{acos} \O \FL{acosh} \O \FL{atan} \O \L {cosd} \O \FL{cos} \O \FL{cosh} \O \FL{cot} \O \FL{cotd} \O \L {sind} \O \FL{sin} \O \FL{sinh} \O \FL{tand} \O \FL{tan}
+ \O \L {inverse} \O \FL{inv} \O \FL{invcos} \O \FL{invsin} \O \FL{invtan}
+ \O \FL{sqr} \O \L {sqrt} \O \L {pow} \O \FL{exp} \O \L {mexp} \O \L {mlog} \O \FL{ln} \O \FL{log} \O \L {uniformdeviate}
+ \O \L {abs} \O \L {round} \O \L {odd} \O \L {ceiling} \O \L {floor}
+ \O \L {dir} \O \L {angle} \O \L {length} \O \L {arclength}
+ \O \L {bbox} \O \FL{bbwidth} \O \FL{bbheight}
+ \O \L {bot} \O \L {lft} \O \L {rt} \O \L {top} \O \L {center}
+ \O \FL{colordecimals} \O \L {decimal} \O \FL{ddecimal} \O \FL{dddecimal} \O \FL{ddddecimal} \O \FL{condition} \O \FL{tostring}
+ \O \FL{boundingbox} \O \FL{outerboundingbox} \O \FL{innerboundingbox} \O \L {bbox}
+ \O \L {colorpart} \O {fontpart} \O \L {pathpart} \O \L {penpart} \O \L {textpart} \O \L {dashpart}
+ \O \L {redpart} \O \L {greenpart} \O \L {bluepart} \O \L {greypart} \O \L {graypart}
+ \O \L {cyanpart} \O \L {magentapart} \O \L {yellowpart} \O \L {blackpart}
+ \O \L {postscriptpart} \O \L {prescriptpart}
+ \O \L {clipped} \O \L {bounded} \O \L {stroked} \O \L {filled} \O \L {textual}
+ \O \FL{punked} \O \L{paralleled}
+ \O \FL{leftboundary} \O \FL{rightboundary} \O \FL{topboundary} \O \FL{bottomboundary}
+ \O \L {xpart} \O \L {xxpart} \O \L {xypart} \O \L {ypart} \O \L {yxpart} \O \L {yypart}
+ \O \L {oct} \O \L {hex}
+ \O \L {colortype}
+ \O \FL{grayed} \O \FL{greyed}
+ \O \L {llcorner} \O \L {lrcorner} \O \L {ulcorner} \O \L {urcorner}
+ \O \L {not} \O \L {known} \O \L {unknown}
+ \O \FL{blackcolor} \O \FL{whitecolor} \O \L {colormodel}
+ \O \L {char} \O \L {fontsize}
+ \O \L {cycle} \O \L {reverse} \O \L {counterclockwise}
+ \O \L {makepath} \O \L {makepen}
+ \O \L {unitvector}
+ \O \L {turningnumber}
+ \O \L {circularpath} \O \L {squarepath} \O \L {linearpath}
+ % maybe pseudo functions:
+ \O \FL{area} \O \FL{inverted} \O \FL{simplified} \O \FL{unspiked}
+\StopSyntax
+
+\StartSyntax
+\S{type}
+ \M \L{boolean} \O \L{numeric} \O \L{pair} \O \L{path}
+ \O \L{pen} \O \L{picture} \O \L{string} \O \L{transform}
+ \O \L{color} \O \L{cmykcolor} \O \FL {greycolor} \FL {graycolor}\O \L{rgbcolor}
+ \O \FL{property}\O \FL{transparency}
+ \O \L{outer} \O \L{inner}
+\StopSyntax
+
+\StartSyntax
+\S{primary binop}
+ \M \L{*} \O \L{/} \O \L{**} \O \L{and}
+ \O \L{dotprod} \O \L{div} \O \L{infont} \O \L{mod}
+\StopSyntax
+
+\StartSyntax
+\S{secondary binop}
+ \M \L{+} \O \L{-} \O \L{++} \O \L{+-+} \O \L{or}
+ \O \L{intersectionpoint} \O \L{intersectiontimes}
+\StopSyntax
+
+\StartSyntax
+\S{tertiary binop}
+ \M \L{&} \O \L{<} \O \L{<=} \O \L{<>} \O \L{=} \O \L{>} \O \L{>=}
+ \O \L{cutafter} \O \L{cutbefore} \O \FL{cutends}
+ \O \L{softjoin}
+\StopSyntax
+
+\StartSyntax
+\S{of operator}
+ \M \L{arctime} \O \L{direction} \O \L{directiontime} \O \L{directionpoint}%
+ \O \L{penoffset} \O \L{point}
+ \O \L{postcontrol} \O \L{precontrol} \O \L{subpath} \O \L{substring}
+ \O \L{takepower}
+\StopSyntax
+
+\StartSyntax
+\S{variable}
+ \M \S{predefined numeric variable}
+ \O \S{predefined path variable}
+ \O \S{predefined picture variable}
+ \O \S{predefined transform variable}
+ \O \S{predefined pair variable}
+ \O \S{predefined pen variable}
+ \O \S{predefined string variable}
+ \O \S{predefined dashpattern}
+ \O \S{predefined rgbcolor variable}
+ \O \S{predefined macro}
+ \O \S{tag} \S{suffix}
+\StopSyntax
+
+\StartSyntax
+\S{predefined numeric variable}
+ \M \FL{nothing yet}
+\StopSyntax
+
+\StartSyntax
+\S{predefined picture variable}
+ \M \FL{blankpicture}
+ \O \L{currentpicture}
+\StopSyntax
+
+\StartSyntax
+\S{predefined transform variable}
+ \M \L{identity} \O \L{currenttransform}
+\StopSyntax
+
+\StartSyntax
+\S{predefined path variable}
+ \M \FL{originpath}
+ \O \FL{fullcircle} \O \FL{fullsquare} \O \FL{fulldiamond} \O \FL{fulltriangle}
+ \O \FL{unitcircle} \O \FL{unitsquare} \O \FL{unitdiamond} \O \FL{unittriangle}
+ \O \FL{halfcircle} \O \FL{quartercircle}
+ \O \FL{llcircle} \O \FL{lrcircle} \O \FL{urcircle} \O \FL{ulcircle}
+ \O \FL{bcircle} \O \FL{tcircle} \O \FL{lcircle} \O \FL{rcircle}
+ \O \FL{triangle}
+ \O \FL{righttriangle} \O \FL{uptriangle} \O \FL{lefttriangle} \O \FL{downtriangle}
+ \O \FL{lltriangle} \O \FL{lrtriangle} \O \FL{urtriangle} \O \FL{ultriangle}
+ \O \L{cuttings}
+\StopSyntax
+
+\StartSyntax
+\S{predefined pair variable}
+ \M \L{right} \O \L{up} \O \L{left} \O \L{down}
+ \M \L{shadedright} \O \L{shadedup} \O \L{shadedleft} \O \L{shadeddown}
+\StopSyntax
+
+\StartSyntax
+\S{predefined pen variable}
+ \M \FL{pensquare} \O \FL{penrazor} \O \FL{penspec}
+ \O \L{currentpen}
+\StopSyntax
+
+\StartSyntax
+\S{predefined string variable}
+ \M \FL{EOF}
+ \O \FL{CRLF} \O \FL{crlf}
+ \O \FL{DQUOTE} \O \FL{dquote} \O \L{ditto}
+ \O \FL{SPACE} \O \FL{space}
+ \O \FL{PERCENT} \O \FL{percent}
+ \O \L{defaultfont}
+ \O \L{extra_beginfig} \O \L {extra_endfig}
+ \O \FL{pathconnectors}
+\StopSyntax
+
+\StartSyntax
+\S{predefined dashpattern}
+ \M \L{evenly} \O \FL{oddly} \O \L{withdots}
+\StopSyntax
+
+\StartSyntax
+\S{predefined rgbcolor variable}
+ \M \L{red} \O \L{green} \O \L{blue} \O \L{white}
+ \O \L{cyan} \O \L{magenta} \O \L{yellow} \O \L{black}
+ \O \L{background}
+ \O \FL{basiccolors}
+\StopSyntax
+
+\StartSyntax
+\S{predefined macro}
+ \M \FL{shipit} \O \FL{bye}
+ \O \FL{resetdrawoptions}
+ \O \FL{visualizepaths} \O \FL{naturalizepaths}
+\StopSyntax
+
+\StartSyntax
+\S{suffix}
+ \M \S{empty}
+ \O \S{suffix} \S{subscript}
+ \O \S{suffix} \S{tag}
+ \O \S{suffix parameter}
+\StopSyntax
+
+\StartSyntax
+\S{subscript}
+ \M \S{number}
+ \O \[ \S{numeric expression} \]
+\StopSyntax
+
+\StartSyntax
+\S{internal variable}
+ \M \L{ahangle} \O \L{ahlength}
+ \O \L{bboxmargin} \O \L{labeloffset}
+ \O \L{charcode}
+ \O \L{defaultcolormodel} \O \L{defaultpen} \O \L{defaultscale}
+ \O \L{linecap} \O \L{linejoin} \O \L{miterlimit}
+ \O \L{outputformat} \O \L{outputtemplate} \O \O \L{prologues}
+ \O \L{showstopping} \L{pausing}
+ \O \L{tracingoutput} \O \L{tracingcapsules} \O \L{tracingchoices} \O \L{tracingcommands} \O \L{tracingequations}
+ \O \L{tracinglostchars} \O \L{tracingmacros} \O \L{tracingonline} \O \L{tracingrestores} \O \L{tracingspecs}
+ \O \L{tracingstats} \O \L{tracingtitles}
+ \O \L{truecorners} \O \L{warningcheck}
+ \O \L{dotlabeldiam}
+ \O \L{day} \O \L{month} \O \L{year} \O \L{hour} \O \L{minute} \O \L{time}
+ \O \L{mm} \O \L{pt} \O \L{dd} \O \L{bp} \O \L{cm} \O \L{pc} \O \L{cc} \O \L{in}
+ \O \L{butt} \O \L{rounded} \O \L{squared} \O \L{mitered} \O \L{beveled}
+ \O \FL{pi} \O \FL{radian} \O \FL{eps} \O \FL{epsilon}
+ \O \FL{nocolormodel} \O \FL{greycolormodel} \O \FL{graycolormodel} \O \FL{rgbcolormodel} \O \FL{cmykcolormodel}
+ % \O \FL{shadefactor}
+ \O \FL{textextoffset}
+ \O \FL{maxdimensions}
+ \O \L{infinity}
+ \O \FL{charscale}
+ \O \FL{metapostversion}
+ \O \FL{normaltransparent} \O \FL{multiplytransparent} \O \FL{screentransparent} \O \FL{overlaytransparent}
+ \O \FL{softlighttransparent} \O \FL{hardlighttransparent} \O \FL{colordodgetransparent} \O \FL{colorburntransparent}
+ \O \FL{darkentransparent} \O \FL{lightentransparent} \O \FL{differencetransparent} \O \FL{exclusiontransparent}
+ \O \FL{huetransparent} \O \FL{saturationtransparent} \O \FL{colortransparent} \O \FL{luminositytransparent}
+ \O \S{symbolic token defined by \L{newinternal}}
+ \O \L{ahangle} \O \L{ahlength}
+ \O \L{bboxmargin}
+ \O \L{pen_bot} \O \L{pen_top} \O \L{pen_lft} \O \L{pen_rt}
+ \O \L{join_radius}
+ \O \L{crossingscale} \O \L{crossingoption}
+\StopSyntax
+
+\StartSyntax
+\S{pseudo function}
+ \M \L {min} \( \S{expression list} \)%
+ \O \L {max} \( \S{expression list} \)
+ \O \L {incr} \( \S{numeric variable} \)%
+ \O \L {decr} \( \S{numeric variable} \)
+ \O \L {dashpattern} \( \S{on/off list} \)
+ \O \L {interpath} \( \S{numeric expression} \L{,} \S{path expression} \L{,} \S{path expression} \)
+ \O \FL{interpolated} \( \S{numeric expression} \L{,} \S{path expression} \L{,} \S{path expression} \)
+ \O \L {buildcycle} \( \S{path expression list} \)
+ \O \L {thelabel} \S{label suffix} \( \S{expression} \L{,} \S{pair expression} \)
+ \O \FL{thefreelabel} \( \S{expression}\L{,} \S{pair expression} \L{,} \S{pair expression} \)
+ \O \FL{anglebetween} \( \S{path expression} \L{,} \S{path expression} \L{,} \S{expression} \)
+ \O \L {flex} \( \S{text} \)
+ \O \L {hide} \( \S{text} \)
+ \O \L {gobble} \S{primary}
+ \O \L {clearit}
+ \O \L {clearpen}
+ \O \L {clearxy}
+ \O \FL{pointarrow} \( \S{path expression} \L{,} \S{numeric or pair primary} \L{,} \S{numeric expression} \)
+ \O \FL{centerarrow} \( \S{path expression} \L{,} \S{numeric or pair primary} \L{,} \S{numeric expression} \)
+ \O \FL{leftarrow} \( \S{path expression} \L{,} \S{numeric or pair primary} \L{,} \S{numeric expression} \)
+ \O \FL{rightarrow} \( \S{path expression} \L{,} \S{numeric or pair primary} \L{,} \S{numeric expression} \)
+ \O \FL{paired} \( \S{numeric or pair} \)%
+ \O \FL{tripled} \( \S{numeric or color} \)
+ \O \FL{remappedcolor} \( \S{color expression} \)
+ \O \FL{superellipse} \( \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \L{,} \L{numeric primary} \L{,} \N \L{numeric primary} \)
+ \O \FL{roundedsquare} \( \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \)
+ \O \FL{tensecircle} \( \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \)
+ \O \FL{tensepath} \( \S{path primary} \)
+ \O \FL{(constructed)function}%
+ \( \S{string expression} \)%
+ \( \S{string primary} \L{,} \S{string primary} \L{,} \S{numeric primary} \L{,}
+ \N \S{numeric primary} \L{,} \S{numeric primary} \)
+ \O \FL{straightfunction} \( \S{string primary} \L{,} \S{string primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \L{,}
+ \N \S{numeric primary} \)
+ \O \FL{curvedfunction} \( \S{string primary} \L{,} \S{string primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \L{,}
+ \N \S{numeric primary} \)
+ %\O \FL{punkedfunction} \( \S{string primary} \L{,} \S{string primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \)
+ %\O \FL{tightfunction} \( \S{string primary} \L{,} \S{string primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \)
+ \O \FL{constructedpairs} \( \S{string expression} \) \( \S{pair array} \)
+ \O \FL{straightpairs} \( \S{pair array} \)
+ \O \FL{curvedpairs} \( \S{pair array} \)
+ %\O \FL{punkedpairs} \( \S{pair array} \)
+ %\O \FL{tightpairs} \( \S{pair array} \)
+ \O \FL{constructedpath} \( \S{string expression} \) \( \S{text} \)
+ \O \FL{straightpath} \( \S{text} \)
+ \O \FL{curvedpath} \( \S{text} \)
+ %\O \FL{punkedpath} \( \S{text} \)
+ %\O \FL{tightpath} \( \S{text} \)
+ \O \FL{epsed} \S{numeric primary}
+ \O \FL{arrowhead} \S{path primary}
+ \O \FL{arrowpath} \S{path primary}
+ \O \FL{infinite} \S{path primary}
+ %
+ \O \FL{tolist} \( \S{pair array} \) \( \S{text} \)
+ \O \FL{topath} \( \S{pair array} \) \( \S{text} \)
+ \O \FL{tocycle} \( \S{pair array} \) \( \S{text} \)
+ \O \FL{pencilled} \( \S{path expression} \) \( \S{pen expression} \)
+\StopSyntax
+
+\StartSyntax
+\S{color expression}
+ \M \S{basic color expression}
+ \O \S{string primary}
+ \O \FL{namedcolor} \( \S{string primary} \)
+ \O \FL{spotcolor} \( \S{string primary} \L{,} \S{basic color expression} \)
+ \O \FL{multitonecolor} \( \S{string primary} \L{,} \S{basic color expression list} \)
+\StopSyntax
+
+\StartSyntax
+\S{basic color expression}
+ \M \S{rgb color expression}
+ \O \S{cmyk color expression}
+ \O \S{gray color expression}
+\StopSyntax
+
+\StartSyntax
+\S{basic color expression list}
+ \M \S{basic color expression}
+ \O \S{basic color expression list} \L{,} \S{basic color expression}
+\StopSyntax
+
+\StartSyntax
+\S{rgb color expression}
+ \M \S\( \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \S\)
+\StopSyntax
+
+\StartSyntax
+\S{cmyk color expression}
+ \M \S\( \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{numeric primary} \S\)
+\StopSyntax
+
+\StartSyntax
+\S{gray color expression}
+ \M \S\( \S{numeric primary} \S\)
+ \O \S{numeric primary}
+\StopSyntax
+
+\StartSyntax
+\S{path expression list}
+ \M \S{path expression}
+ \O \S{path expression list} \L{,} \S{path expression}
+\StopSyntax
+
+\StartSyntax
+\S{on/off list}
+ \M \S{on/off list} \S{on/off clause}
+ \O \S{on/off clause}
+\StopSyntax
+
+\StartSyntax
+\S{on/off clause}
+ \M \L{on} \S{numeric tertiary}
+ \O \L{off} \S{numeric tertiary}
+\StopSyntax
+
+\StartSyntax
+\S{boolean expression} \M \S{expression}
+\S{cmyk expression} \M \S{expression}
+\S{color expression} \M \S{expression}
+\S{numeric atom} \M \S{atom}
+\S{numeric expression} \M \S{expression}
+\S{numeric primary} \M \S{primary}
+\S{numeric tertiary} \M \S{tertiary}
+\S{numeric variable} \M \S{variable} \O \S{internal variable}
+\S{pair expression} \M \S{expression}
+\S{pair primary} \M \S{primary}
+\S{path expression} \M \S{expression}
+\S{path subexpression} \M \S{subexpression}
+\S{pen expression} \M \S{expression}
+\S{picture expression} \M \S{expression}
+\S{picture variable} \M \S{variable}
+\S{rgb expression} \M \S{expression}
+\S{string expression} \M \S{expression}
+\S{suffix parameter} \M \S{parameter}
+\S{transform primary} \M \S{primary}
+\StopSyntax
+
+\StartSyntax
+\S{program}
+ \M \S{statement list} \L{end}
+\StopSyntax
+
+\StartSyntax
+\S{statement list}
+ \M \S{empty}
+ \O \S{statement list} \L{;} \S{statement}
+\StopSyntax
+
+\StartSyntax
+\S{statement}
+ \M \S{empty}
+ \O \S{equation}
+ \O \S{assignment}
+ \O \S{declaration}
+ \O \S{macro definition}
+ \O \S{compound}
+ \O \S{pseudo procedure}
+ \O \S{command}
+\StopSyntax
+
+\StartSyntax
+\S{compound}
+ \M \L{begingroup} \S{statement list} \L{endgroup}
+ \O \L{beginfig} \( \S{numeric expression} \) \L{;} \S{statement list} \S{;} \L{endfig}
+ \O \FL{beginglyph} \( \S{glyph property list} \) \L{;} \S{statement list} \S{;} \L{endglyph}
+ \O \L{image builder} \( \S{statement list} \)
+\StopSyntax
+
+\StartSyntax
+\S{image builder}
+ \M {image} \O \FL {decorated} \O \FL {redecorated} \O \FL {undecorated}
+\StopSyntax
+
+\StartSyntax
+\S{glyph property list}
+ \M \S{numeric expression} \L{,} \S{numeric expression} \L{,} \S{numeric expression} \L{,} \S{numeric expression}
+\StopSyntax
+
+\StartSyntax
+\S{equation}
+ \M \S{expression} \L{=} \S{right-hand side}
+\StopSyntax
+
+\StartSyntax
+\S{assignment}
+ \M \S{variable} \L{:=} \S{right-hand side}
+ \O \S{internal variable} \L{:=} \S{right-hand side}
+\StopSyntax
+
+\StartSyntax
+\S{right-and side}
+ \M \S{expression}
+ \O \S{equation}
+ \O \S{assignment}
+\StopSyntax
+
+\StartSyntax
+\S{declaration}
+ \M \S{type} \S{declaration list}
+\StopSyntax
+
+\StartSyntax
+\S{declaration list}
+ \M \S{generic variable}
+ \O \S{declaration list} \L{,} \S{generic variable}
+\StopSyntax
+
+\StartSyntax
+\S{generic variable}
+ \M \S{Symbolic token} \S{generic suffix}
+\StopSyntax
+
+\StartSyntax
+\S{generic suffix}
+ \M \S{empty}
+ \O \S{generic suffix} \S{tag}
+ \O \S{generic suffix} \L{[]}
+\StopSyntax
+
+\StartSyntax
+\S{macro definition}
+ \M \S{macro heading} \L{=} \S{replacement text} \L{enddef}
+\StopSyntax
+
+\StartSyntax
+\S{macro heading}
+ \M \L{def} \S{Symbolic token} \S{delimited part} \S{undelimited part}
+ \O \L{vardef} \S{generic variable} \S{delimited part} \S{undelimited part}
+ \O \L{vardef} \S{generic variable} \L{@#} \S{delimited part} \S{undelimited part}
+ \O \S{binary def} \S{parameter} \S {symbolic token} \S{parameter}
+\StopSyntax
+
+\StartSyntax
+\S{delimited part}
+ \M \S{empty}
+ \O \S{delimited part} \( \S{parameter type} \S{parameter tokens} \)
+\StopSyntax
+
+\StartSyntax
+\S{parameter type}
+ \M \L{expr}
+ \O \L{suffix}
+ \O \L{text}
+\StopSyntax
+
+\StartSyntax
+\S{parameter tokens}
+ \M \S{parameter}
+ \O \S{parameter tokens} \L{,} \S{parameter}
+\StopSyntax
+
+\StartSyntax
+\S{parameter}
+ \M \S{Symbolic token}
+\StopSyntax
+
+\StartSyntax
+\S{undelimited part}
+ \M \S{empty}
+ \O \S{parameter type} \S{parameter}
+ \O \S{precedence level} \S{parameter}
+ \O \L{expr} \S{parameter} \L{of} \S{parameter}
+\StopSyntax
+
+\StartSyntax
+\S{precedence level}
+ \M \L{primary}
+ \O \L{secondary}
+ \O \L{tertiary}
+\StopSyntax
+
+\StartSyntax
+\S{binary def}
+ \M \S{primarydef}
+ \O \S{secondarydef}
+ \O \S{tertiarydef}
+\StopSyntax
+
+\StartSyntax
+\S{pseudo procedure}
+ \M \L {drawoptions} \( \S{option list} \)
+ \O \L {label} \S{label suffix} \( \S{expression} \L{,} \S{pair expression} \)
+ \O \L {thelabel} \S{label suffix} \( \S{expression} \L{,} \S{pair expression} \)
+ \O \L {dotlabel} \S{label suffix} \( \S{expression} \L{,} \S{pair expression} \)
+ \O \L {makelabel} \S{makelabel}
+ \O \L {labels} \S{label suffix} \( \S{point number list} \)
+ \O \L {dotlabels} \S{label suffix} \( \S{point number list} \)
+ \O \FL{textext} \S{label suffix} \( \S{expression} \)
+ \O \FL{infotext} \S{label suffix} \( \S{expression}, \S{numeric expression} \)
+ \O \FL{thetextext} \S{label suffix} \( \S{expression}, \S{pair expression} \)
+ \O \FL{rawtextext} \( \S{expression} \)
+ \O \FL{verbatim} \S{string expression}
+ \O \FL{freelabel} \( \S{expression} \L{,} \S{pair expression} \L{,} \S{pair expression} \)
+ \O \FL{freedotlabel} \( \S{expression} \L{,} \S{pair expression} \L{,} \S{pair expression} \)
+ \O \FL{remapcolor} \( \S{color expression} \L{,} \S{color expression} \)
+ \O \FL{resetcolormap}
+ \O \FL{recolor} \S{picture expression}
+ \O \FL{bitmapimage} \( \S{numeric primary} \L{,} \S{numeric primary} \L{,} \S{string primary} \)
+ \O \FL{pushboundingbox} \O \FL{popboundingbox}
+ \O \FL{pushcurrentpicture} \O \FL{popcurrentpicture}
+ \O \FL{externalfigure} \S{string expression} \S{transformer}
+ \O \FL{loadfigure} \S{string expression} \L{number} \S{numeric expression} \S{transformer}
+ \O \FL{properties}
+ \O \L {anchored} \S{label suffix} \( \S{expression} \L{,} \S{pair expression} \)
+\StopSyntax
+
+\StartSyntax
+\S{point number list}
+ \M \S{suffix} \O \S{point number list} \L{,} \S{suffix}
+\StopSyntax
+
+\StartSyntax
+\S{label suffix}
+ \M \S{empty}
+ \O \L{lft} \O \L{rt}\O \L{top} \O \L{bot} \O \L{ulft} \O \L{urt}%
+ \O \L{llft} \O \L{lrt} \O \FL{raw} \O \FL{origin}
+\StopSyntax
+
+\StartSyntax
+\S{command}
+ \M \L{clip} \S{picture variable} \L{to} \S{path expression}
+ \O \L{interim} \S{internal variable} \L{:=} \S{right-hand side}
+ \O \L{let} \S{symbolic token} \L{=} \S{symbolic token}
+ \O \L{pickup} \S{expression}
+ \O \L{randomseed} \L{:=} \S{numeric expression}
+ \O \L{save} \S{symbolic token list}
+ \O \L{delimiters} \S{character} \S{character}
+ \O \L{setbounds} \S{picture variable} \L{to} \S{path expression}
+ \O \L{shipout} \S{picture expression}
+ \O \L{special} \S{string expression}
+ \O \L{endinput}
+ \O \L{expandafter}
+ \O \S{addto command}
+ \O \S{drawing command}
+ \O \S{font metric command}
+ \O \S{newinternal command}
+ \O \S{message command}
+ \O \S{mode command}
+ \O \S{show command}
+ \O \S{special command}
+ \O \S{tracing command}
+ \O \S{scantokens} \S{string expression}
+ \O \FL{defineshade} \S{symbolic token} \S{shading expression}
+ \O \L{write} \S{string expression} \L{to} \S{string expression}
+ \O \L{readfrom} \S{string expression}
+ \O \FL{readfile} \S{string expression}
+ \O \L{readstring}
+ \O \L{restoreclipcolor}
+ \O \L{savepen}
+ \O \L{runscript}
+ \O \L{relax}
+\StopSyntax
+
+\StartSyntax
+\S{show command}
+ \M \L{show} \S{expression list}
+ \O \L{showvariable} \S{symbolic token list}
+ \O \L{showtoken} \S{symbolic token list}
+ \O \L{showdependencies}
+\StopSyntax
+
+\StartSyntax
+\S{symbolic token list}
+ \M \S{symbolic token}
+ \O \S{symbolic token} \L{,} \S{symbolic token list}
+\StopSyntax
+
+\StartSyntax
+\S{expression list}
+ \M \S{expression}
+ \O \S{expression list} \L{,} \S{expression}
+\StopSyntax
+
+\StartSyntax
+\S{addto command}
+ \M \L{addto} \S{picture variable} \L{also} \S{picture expression} \S{option list}
+ \O \L{addto} \S{picture variable} \L{contour} \S{path expression} \S{option list}
+ \O \L{addto} \S{picture variable} \L{doublepath} \S{path expression} \S{option list}
+\StopSyntax
+
+\StartSyntax
+\S{option list}
+ \M \S{empty}
+ \O \S{drawing option} \S{option list}
+\StopSyntax
+
+\StartSyntax
+\S{drawing option}
+ \M \L {withcolor} \S{color expression}%
+ \O \FL {withgrey} \S{numeric expression}%
+ \O \FL {withgray} \S{numeric expression}
+ \O \L {withrgbcolor} \S{rgb expression}%
+ \O \L {withcmykcolor} \S{cmyk expression}%
+ \O \L {withgreyscale} \S{numeric expression}
+ \O \L {withoutcolor}
+ \O \L {withprescript} \S{string expression}%
+ \O \L {withpostscript} \S{string expression}
+ \O \L {withpen} \S{pen expression}
+ \O \L {dashed} \S{picture expression}
+ \O \FL{undashed}
+ \O \FL{withshade} \S{numeric expression} \O \FL{shaded} \S{shading expression}
+ \O \FL{withproperties} \S{property primary}
+ \O \FL{withtransparency} \S{pair primary}
+ \O \FL{withlinearshade} \(%
+ \S{path expression} \L{,}%
+ \S{path expression} \L{,}%
+ \S{color expression} \L{,}%
+ \S{color expression} \)
+ \O \FL{withcircularshade} \(%
+ \S{path ex} \L{,}%
+ \S{path ex} \L{,}%
+ \S{numeric ex} \L{,}%
+ \S{numeric ex} \L{,}%
+ \S{color ex} \L{,}%
+ \S{color ex} \)
+ \O \S{shading expression}
+ \O \FL{onlayer} \S{string expression}
+ \O \FL{withmask} \S{string expression}
+\StopSyntax
+
+\StartSyntax
+\S{property expression}
+ \M \( {drawing option} \)
+\StopSyntax
+
+\StartSyntax
+\S{shading expression}
+ \M \FL{withshademethod} \L{string expression}
+ \O \FL{withshadefactor} \L{numeric expression}
+ \O \FL{withshadedomain} \L{pair expression}
+ \O \FL{withshadevector} \L{pair expression}
+ \O \FL{withshaderadius} \L{pair expression}
+ \O \FL{withshadeorigin} \L{pair expression}
+ \O \FL{withshadecolors} \( \S{color expression} \L{,} \S{color expression} \)
+ \O \FL{withshadecenter} \L{pair expression}
+\StopSyntax
+
+\StartSyntax
+\S{drawing command}
+ \M \L{draw} \S{picture expression} \S{option list}
+ \O \S{fill type} \S{path expression} \S{option list}
+\StopSyntax
+
+\StartSyntax
+\S{fill type}
+ \M \L {fill} \O \L{unfill} \O \FL{refill}
+ \O \L {draw} \O \L{undraw} \O \FL{redraw}
+ \O \L {filldraw} \O \FL{drawfill} \O \L{undrawfill} \O \L{unfilldraw}
+ \O \FL{eofill} \O \FL{nofill} \O \FL{fillup}
+ \O \L {drawdot}
+ \O \L {drawarrow} \O \L{drawdblarrow}
+ \O \L {cutdraw}
+ \O \L {visualizer}
+ \O \FL{normaldraw} \O \FL{normalfill}
+\StopSyntax
+
+\StartSyntax
+\S{visualizer}
+ \M \FL{drawboundary} \O \FL{drawboundingbox} \O \FL{drawboundoptions}
+ \O \FL{drawcontrollines} \O \FL{drawcontroloptions} \O \FL{drawcontrolpoints}
+ \O \FL{drawlabeloptions} \O \FL{drawlineoptions} \O \FL{drawoptions}
+ \O \FL{draworigin} \O \FL{draworiginoptions}
+ \O \FL{drawpath} \O \FL{drawpathoptions}
+ \O \FL{drawpoint} \O \FL{drawpointlabels} \O \FL{drawpointoptions}
+ \O \FL{drawpoints} \O \FL{drawwholepath}
+ \O \FL{visualizeddraw} \O \FL{visualizedfill}
+\StopSyntax
+
+\StartSyntax
+\S{newinternal command}
+ \M \L{newinternal} \S{internal type} \S{symbolic token list}
+ \O \S{newinternal} \S{symbolic token list}
+\StopSyntax
+
+\StartSyntax
+\S{message command}
+ \M \L{errhelp} \S{string expression}
+ \O \L{errmessage} \S{string expression}
+ \O \L{filenametemplate} \S{string expression}
+ \O \L{message} \S{string expression}
+\StopSyntax
+
+\StartSyntax
+\S{mode command}
+ \M \L{batchmode}
+ \O \L{nonstopmode}
+ \O \L{scrollmode}
+ \O \L{errorstopmode}
+ \O \L{interact}
+\StopSyntax
+
+\StartSyntax
+\S{special command}
+ \M \L{fontmapfile} \S{string expression}
+ \O \L{fontmapline} \S{string expression}
+ \O \L{special} \S{string expression}
+ \O \L{input} \S{string expression}
+ \O \L{prologies} \S{numeric expression}
+ \O \L{outputtemplate} \S{string expression}
+ \O \L{outputformat} \S{string expression}
+\StopSyntax
+
+\StartSyntax
+\S{tracing command}
+ \M \L{tracingall}
+ \O \L{loggingall}
+ \O \L{tracingnone}
+\StopSyntax
+
+\StartSyntax
+\S{if test}
+ \M \L{if} \S{boolean expression} \L{:} \S{balanced tokens} \S{alternatives} \L{fi}
+\StopSyntax
+
+\StartSyntax
+\S{alternatives}
+ \M \S{empty}
+ \O \L{else} \L{:} \S{balanced tokens}
+ \O \L{elseif} \S{boolean expression} \S{:} \S{balanced tokens} \S{alternatives}
+ \O \L{exit} \O \L{exitif} \S{boolean expression} \O \L{exitunless} \S{boolean expression}
+ \O \L{break}
+\StopSyntax
+
+\StartSyntax
+\S{loop}
+ \M \S{loop header} \L{:} \S{loop text} \L{endfor}
+\StopSyntax
+
+\StartSyntax
+\S{loop header}
+ \M \L{for} \S{symbolic token} \L{=} \S{progression}
+ \O \L{for} \S{symbolic token} \L{=} \S{for list}
+ \O \L{for} \S{symbolic token} \L{within} \S{picture expression}
+ \O \L{forsuffixes} \S{symbolic token} \L{=} \S{suffix list}
+ \O \L{forever}
+\StopSyntax
+
+\StartSyntax
+\S{progression}
+ \M \S{numeric expression} \L{upto} \S{numeric expression}
+ \O \S{numeric expression} \L{downto} \S{numeric expression}
+ \O \S{numeric expression} \L{step} \S{numeric expression} \L{until} \S{numeric expression}
+ \O \L{range} \S{numeric expression} \L{thru} \S{numeric expression}
+\StopSyntax
+
+\StartSyntax
+\S{for list}
+ \M \S{expression}
+ \O \S{for list} \L{,} \S{expression}
+\StopSyntax
+
+\StartSyntax
+\S{suffix list}
+ \M \S{suffix}
+ \O \S{suffix list} \L{,} \S{suffix}
+\StopSyntax
+
+\stop
+
+% \stopsection
+
+\stopchapter
+
+\stopcomponent
+
+% \startsection[title={Left overs}]
+
+% There are a few more concepts and commands available in \METAFUN, like color
+% remapping, shading and graphic inclusion. Because they have their own small
+% syntax world, we present them here.
+%
+% You may consider shades to be internally represented by a hidden datastructure.
+% The end user has access to a shade by means of a pointer, expressed in a numeric.
+%
+% \start \switchtobodyfont[small]
+%
+% \StartSyntax
+% \S{pseudo procedure}
+% \M \FL{linear_shade}%
+% \( \S{path expression} \L{,} \S{numeric expression}%
+% \L{,} \S{color expression} \L{,} \S{color expression} \)
+% \O \FL{circular_shade}%
+% \( \S{path expression} \L{,} \S{numeric expression}%
+% \L{,} \S{color expression} \L{,} \S{color expression} \)
+% \StopSyntax
+%
+% \StartSyntax
+% \S{pseudo function}
+% \M \FL{define_linear_shade}%
+% \( \S{pair expr} \L{,} \S{pair expr}%
+% \L{,} \S{color expr} \L{,} \S{color expr} \)
+% \O \FL{define_circular_shade}%
+% \( \S{pair expr} \L{,} \S{pair expr}%
+% \L{,} \S{path expr} \L{,} \S{path expr}%
+% \L{,} \S{color expr} \L{,} \S{color expr} \)
+% \O \FL{predefined_linear_shade}%
+% \( \S{path expr} \L{,} \S{numeric expr}%
+% \L{,} \S{color expr} \L{,} \S{color expr} \)
+% \O \FL{predefined_circular_shade}%
+% \( \S{path expr} \L{,} \S{numeric expr}%
+% \L{,} \S{color expr} \L{,} \S{color expr} \)
+% \StopSyntax
+%
+% \stop
+
+% External figures are just files, so the string passed as first argument needs to
+% be a valid filename. Additionally, they need to be given dimensions.
+
+% \start \switchtobodyfont[small]
+%
+% \StartSyntax
+% \S{pseudo procedure}
+% \M \FL{externalfigure} \S{string expression} \S{transformer}
+% \StopSyntax
+%
+% \stop
+
+% An external \METAPOST\ graphic can be loaded by filename and figure number. The
+% normal transformations can be applied.
+%
+% \start \switchtobodyfont[small]
+%
+% \StartSyntax
+% \S{pseudo procedure}
+% \M \FL{loadfigure} \S{string expression} \L{number} \S{numeric expression} \S{transformer}
+% \StopSyntax
+%
+% \stop
+
+% A graphic text is (normally) an outline representation of a snippet of text
+% typeset by \TEX. This procedure has a couple of dedicated options.
+
+% \start \switchtobodyfont[small]
+
+% \StartSyntax
+% \S{pseudo procedure}
+% \M \FL{graphictext} \S{string expression} \S{transformer} \S{text option list}
+% \O \FL{regraphictext} \S{transformer} \S{text option list}
+% \StopSyntax
+
+% \StartSyntax
+% \S{text option list}
+% \M \S{empty}
+% \O \S{text drawing option} \S{text option list}
+% \StopSyntax
+
+% \StartSyntax
+% \S{text drawing option}
+% \M \S{drawing option}
+% \O \FL{reversefill}
+% \O \FL{outlinefill}
+% \O \FL{withdrawcolor} \S{color expression}
+% \O \FL{withfillcolor} \S{color expression}
+% \StopSyntax
+
+% \StartSyntax
+% \S{pseudo procedure}
+% \M \FL{resetgraphictextdirective}
+% \O \FL{graphictextdirective} \S {string expression}
+% \StopSyntax
+
+% \StartSyntax
+% \S{internal variable}
+% \M \FL{graphictextformat}
+% \StopSyntax
+
+% \stop
+
+% \stopsection
+
+% \stopchapter
+
+% \stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-text.tex b/doc/context/sources/general/manuals/metafun/metafun-text.tex
new file mode 100644
index 000000000..f70f53ac3
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-text.tex
@@ -0,0 +1,1784 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-text
+
+\environment metafun-environment
+
+\startchapter[reference=sec:typesetting,title={Typesetting in \METAPOST}]
+
+\startintro
+
+It is said that a picture tells more than a thousand words. So you might expect
+that text in graphics becomes superfluous. Out of experience we can tell you that
+this is not the case. In this chapter we explore the ways to add text to
+\METAPOST\ graphics, and let you choose whether or not to have it typeset by
+\TEX.
+
+\stopintro
+
+\startsection[title={The process}]
+
+\index{text}
+
+You can let \METAPOST\ process text that is typeset by \TEX. Such text is first
+embedded in the \METAPOST\ file in the following way:
+
+\starttyping
+btex Some text to be typeset by \TEX etex
+\stoptyping
+
+This returns a picture, but only after \METAPOST\ has made sure that \TEX\ has
+converted it into something useful. This process of conversion is slightly system
+dependent and even a bit obscure. Traditional \METAPOST\ calls a program that
+filters the \type {btex}|\unknown|\type {etex} commands, next it calls \TEX\ by
+passing the output routine, in order to make sure that each piece of text ends up
+on its own page, and afterwards it again calls a program that converts the \DVI\
+pages into \METAPOST\ pictures. In \LUATEX's \MPLIB\ a different route is
+followed.
+
+In \CONTEXT\ \MKII, when using \WEBC, you can generate the graphics at run||time.
+This takes more time than processing the graphics afterwards, but has the
+advantage that \TEX\ knows immediately what graphic it is dealing with. When
+enabled, \CONTEXT\ will call either \METAPOST, or, when the graphic contains
+\type {btex}||\type {etex} commands, call \TEXEXEC, which in turn makes sure that
+the right auxiliary programs are executed.
+
+In \CONTEXT\ \MKIV\ you won't notice this at all because everything is tightly
+integrated with \LUATEX's \MPLIB. This has an enormous speed gain: when this
+manual had about 425 pages, on my laptop with mobile 3840QM processor, one run of
+this document takes 18 seconds (14.5 with \LUAJITTEX) and that includes loadint a
+bunch of (outline) fonts and processing some 2200 \METAPOST\ images. While
+writing the first version of this manual runtime was upto 50 times slower for
+half the number of pages so compared to \MKII\ we have gained a lot.
+
+\startFLOWchart[metatex]
+ \startFLOWcell
+ \name {script 1}
+ \location {1,1}
+ \shape {action}
+ \text {\type{context}}
+ \connection [rl] {context 1}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {context 1}
+ \location {2,1}
+ \shape {action}
+ \text {\CONTEXT}
+ \connection [bt] {metapost 1}
+ \connection [rl] {script 2}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {metapost 1}
+ \location {2,2}
+ \shape {action}
+ \text {\METAPOST}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {script 2}
+ \location {3,1}
+ \shape {action}
+ \text {\type{context}}
+ \connection [rl] {context 2}
+ \connection [bt] {metapost 2}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {context 2}
+ \location {4,1}
+ \shape {action}
+ \text {\CONTEXT}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {metapost 2}
+ \location {3,2}
+ \shape {action}
+ \text {\METAPOST}
+ \stopFLOWcell
+\stopFLOWchart
+
+\startplacefigure[title={How \TEX\ and \METAPOST\ work together.}]
+ \FLOWchart[metatex]
+\stopplacefigure
+
+\stopsection
+
+\startsection[title={Environments}]
+
+\index{environments}
+
+In case you want to pass code that is shared by all \type {btex}||\type {etex}
+pictures, \METAPOST\ provides:
+
+\starttyping
+verbatimtex \DefineSomeCommands etex ;
+\stoptyping
+
+However, in \CONTEXT\ one has a better mechanism available. In \CONTEXT\ \MKII\
+the advised method is passing environments. The best way to pass them is the
+following. As an example we switch to the 15 basic \POSTSCRIPT\ fonts.
+
+\startbuffer[pos]
+\startMPenvironment
+ \usetypescript[palatino][texnansi] % mkii has encodings
+ \setupbodyfont[palatino]
+\stopMPenvironment
+\stopbuffer
+
+\typebuffer[pos]
+
+This means that in code like the following, a Palatino font will be used.
+
+\starttyping
+\startMPcode
+draw btex Meta is a female lion! etex
+ xysized (\the\textwidth,\the\textheight) ;
+\stopMPcode
+\stoptyping
+
+However, in \CONTEXT\ \MKIV\ this method is no longer recomended as all
+processing happens in the same run anyway.
+
+% beware: extensive scaling can make acrobat crash and okular drop the !
+
+\startbuffer[lioncode]
+\startMPcode
+numeric w, h ; w := \the\textwidth ; h := w/2 ;
+
+picture p ; p := btex \colored[r=.375,g=.375]{Meta is a female lion!} etex
+ xysized (w,h) ;
+picture q ; q := btex \colored[r=.625] {Meta is a female lion!} etex
+ xysized (w,h) ;
+
+path b ; b := boundingbox p ; draw p ;
+
+for i=(.28w,.90h),(.85w,.90h),(w,.05h) :
+ picture r ; r := q ;
+ path s ; s := (fullsquare xscaled .05w yscaled .4h) shifted i ;
+ clip r to s ; draw r ; % draw s ;
+endfor ;
+
+setbounds currentpicture to b ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[lioncode]
+
+\in {Figure} [lionclip] shows the previous sentence in a slightly different look.
+You may consider coloring the dots to be an exercise in clipping.
+
+\getbuffer[pos]
+
+\placefigure
+ [here][lionclip]
+ {An example of clipping.}
+ {\getbuffer[lioncode]}
+
+\resetMPenvironment
+
+An environment can be reset with \typ {\resetMPenvironment} or by passing \type
+{reset} to \typ {\startMPenvironment}.
+
+\starttyping
+\startMPenvironment[reset]
+ \usetypescript[postscript][texnansi] % mkii
+ \setupbodyfont[postscript]
+\stopMPenvironment
+\stoptyping
+
+So, to summarize: if you're using \CONTEXT\ \MKIV\ you might as well forgot what
+you just read.
+
+\stopsection
+
+\startsection[title={Labels}]
+
+\index{labels}
+
+In \METAPOST\ you can use the \type {label} macro to position text at certain
+points.
+
+\starttyping
+label("x", origin) ;
+\stoptyping
+
+The font and scale are determined by two variables, \type {defaultfont} and \type
+{defaultscale}, the former expecting the name of a font in the form of a string,
+the latter expecting a numeric to be used in the scaling of the font. Should you
+choose not to set these yourself, they default to \type {"Mono"} and \type
+{1.0}, respectively. However, you can change the defaults as follows:
+
+\starttyping
+defaultfont := "texgyrepagella-regular*default" ;
+defaultscale := 1.2 ;
+\stoptyping
+
+These settings selects Pagella at about 12pt. You can also set these variables
+to \CONTEXT\ related values. For \CONTEXT\ graphics they are set to:
+
+\starttyping
+defaultfont := "\truefontname{Regular}*default" ;
+defaultscale := \the\bodyfontsize/10 ;
+\stoptyping
+
+This means that they will adapt themselves to the current body font (in this
+document we get \truefontname{Regular}) and the current size of the bodyfont
+(here \the\bodyfontsize/10).
+
+\stopsection
+
+\startsection[title={\TeX\ text}]
+
+\index{text}
+
+In the next example we will use a special mechanism for building graphics step by
+step. The advantage of this method is that we can do intermediate calculations in
+\TEX. Our objective is to write a macro that draws text along a circular path.
+While doing so we want to achieve the following:
+
+\startitemize[packed]
+\item the text should be properly kerned, i.e.\ the
+ spacing between characters should be optimal,
+\item the position on the circle should vary, and
+\item the radius of the circle should vary.
+\stopitemize
+
+This implementation is not the most straightforward one, but by doing it step by
+step, at least we see what is involved. Later, we will see a better method. If
+you run these examples yourself, you must make sure that the \TEX\ environment of
+your document matches the one used by \METAPOST.
+
+We let the bodyfont match the font used in this document, and define \type
+{RotFont} to be the regular typeface, the one you are reading right now, but
+bold.
+
+\startbuffer
+\definefont[RotFont][RegularBold*default]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Since \METAPOST\ is unaware of kerning, we have to use \TEX\ to keep track of the
+positions. We will split the text into tokens (often characters) and store the
+result in an array of pictures (\type {pic}). We will also store the accumulated
+width in an array (\type {len}). The number of characters is stored in~\type {n}.
+In a few paragraphs we will see why the other arrays are needed.
+
+While defining the graphic, we need \TEX\ to do some calculations. Therefore, we
+will use \type {\startMPdrawing} to stepwise construct the definition. The basic
+pattern we will follow is:
+
+\starttyping
+\resetMPdrawing
+\startMPdrawing
+ metapost code
+\stopMPdrawing
+tex code
+\startMPdrawing
+ metapost code
+\stopMPdrawing
+\MPdrawingdonetrue
+\getMPdrawing
+\stoptyping
+
+In the process, we will use a few variables. We will store the individual
+characters of the text in the variable \type {pic}, its width in \type {wid} and
+the length of the string so far in \type {len}. Later we will use the \type {pos}
+array to store the position where a character ends up. The variable \type {n}
+holds the number of tokens.
+
+\startbuffer[init]
+\resetMPdrawing
+\startMPdrawing
+ picture pic[] ;
+ numeric wid[], len[], pos[], n ;
+ wid[0] := len[0] := pos[0] := n := 0 ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[init]
+
+We also started fresh by resetting the drawing. From now on, each start command
+will add some more to this graphic. The next macro is responsible for collecting
+the data. Each element is passed on to \TEX, using the \type {btex} construct.
+So, \METAPOST\ itself will call \TEX !
+
+\startbuffer[toks]
+\def\whatever#1%
+ {\appendtoks#1\to\MPtoks
+ \setbox\MPbox=\hbox{\bfd\the\MPtoks}%
+ \startMPdrawing
+ n := n + 1 ; len[n] := \the\wd\MPbox ;
+ \stopMPdrawing
+ \startMPdrawing[-]
+ pic[n] := textext("\bfd\setstrut\strut#1") ;
+ pic[n] := pic[n] shifted - llcorner pic[n] ;
+ \stopMPdrawing}
+
+\handletokens MetaPost is Fun!\with\whatever
+\stopbuffer
+
+\typebuffer[toks]
+
+We use the low level \CONTEXT\ macro \type {\appendtoks} to extend the token list
+\type {\MPtoks}. The \type {\handletokens} macro passes each token (character) of
+\typ {MetaPost is Fun!} to the macro \type {\whatever}. The tokens are appended
+to the token register \type {\MPtoks} (already defined). Then we typeset the
+content of \type {\MPtoks} in \type {\MPbox} (also already defined). The width of
+the box is passed to \METAPOST\ and stored in \type {len}.
+
+By default the content of the drawing is expanded, which means that the macro is
+replaced by its current meaning, so the current width ends up in the \METAPOST\
+file. The next part of the drawing, starting with \type {btex}, puts the token in
+a picture. This time we don't expand the drawing, since we want to pass font
+information. Here, the \type {[-]} suppresses expansion of \typ {btex \bfd #1
+etex}. The process is iterated by \type {\handletokens} for each character of the
+text \typ {MetaPost is Fun!}.
+
+Before we typeset the text, now available in pieces in \type {pic}, in a circle,
+we will first demonstrate what they look like. You may like to take a look at the
+file \type {mpgraph.mp} to see what is passed to \METAPOST.
+
+\startbuffer[test]
+\startMPdrawing
+ pair len ; len := origin ;
+ for i=1 upto n :
+ draw pic[i] shifted len ;
+ draw boundingbox pic[i] shifted len
+ withpen pencircle scaled .25pt withcolor red ;
+ len := len+(xpart urcorner pic[i]-xpart llcorner pic[i],0) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[test]
+
+\startbuffer[show]
+\MPdrawingdonetrue\getMPdrawing
+\stopbuffer
+
+We can call up this drawing with \type {\getMPdrawing}, but first we inform the
+compiler that our \METAPOST\ drawing is completed.
+
+\typebuffer[show]
+
+This results in:
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,test,show]
+\stoplinecorrection
+
+Compare this text with the text as typeset by \TEX:
+
+\blank \start \bfd MetaPost is Fun!\par \stop \blank
+
+and you will see that the text produced by \METAPOST\ is not properly kerned.
+When putting characters after each other, \TEX\ uses the information available in
+the font, to optimize the spacing between characters, while \METAPOST\ looks at
+characters as separate entities. But, since we have stored the optimal spacing in
+\type {len}, we can let \METAPOST\ do a better job. Let's first calculate the
+correction needed.
+
+\startbuffer[kern]
+\startMPdrawing
+ for i=1 upto n :
+ wid[i] := abs(xpart urcorner pic[i] - xpart llcorner pic[i]) ;
+ pos[i] := len[i]-wid[i] ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[kern]
+
+This compares well to the text as typeset by \TEX:
+
+\blank \start \bfd MetaPost is Fun!\par \stop \blank
+
+We can now use the values in \type {pos} to position the pictures according to
+what \TEX\ considered to be the best (relative) position.
+
+\startbuffer[test]
+\startMPdrawing
+ for i=1 upto n :
+ draw pic[i] shifted (pos[i],0) ;
+ draw boundingbox pic[i] shifted (pos[i],0)
+ withpen pencircle scaled .25pt withcolor red ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[test]
+
+That this correction is adequate, is demonstrated in the next graphic. If you
+look closely, you will see that for instance the \quote {o} is moved to the left,
+under the capital \quote {P}.
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,test,show]
+\stoplinecorrection
+
+When we want to position the pictures along a circle, we need to apply some
+rotations, especially because we want to go clockwise. Since we don't want to use
+\quote {complicated} math or more advanced \METAPOST\ code yet, we will do it in
+steps.
+
+\startbuffer[swap]
+\startMPdrawing
+ for i=1 upto n:
+ pic[i] := pic[i] rotatedaround(origin,-270) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[swap]
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,swap,test,show]
+\stoplinecorrection
+
+\startbuffer[cent]
+\startMPdrawing
+ for i=1 upto n :
+ pic[i] := pic[i]
+ shifted (0,ypart -.5[ulcorner pic[i],llcorner pic[i]]) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+We will now center the pictures around the baseline. Centering comes down to
+shifting over half the height of the picture. This can be expressed by:
+
+\starttyping
+ypart -.5[ulcorner pic[i],llcorner pic[i]]
+\stoptyping
+
+but different ways of calculating the distance are possible
+too.
+
+\typebuffer[cent]
+
+So, now we have:
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,swap,cent,test,show]
+\stoplinecorrection
+
+When we typeset on a (half) circle, we should map the actual length onto a
+partial circle. We denote the radius with an~\type {r} and shift the pictures to
+the left.
+
+\startbuffer[shif]
+\startMPdrawing
+ numeric r ; r := len[n]/pi ;
+ for i=1 upto n :
+ pic[i] := pic[i] shifted (-r,0) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[shif]
+
+You can now use the following code to test the current state of the pictures. Of
+course this code should not end up in the final definitions.
+
+\startbuffer[test]
+\startMPdrawing
+ draw origin
+ withpen pencircle scaled 5pt withcolor red ;
+ for i=1 upto n :
+ draw pic[i] ;
+ draw boundingbox pic[i]
+ withpen pencircle scaled .25pt withcolor red ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[test]
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,swap,cent,shif,test,show]
+\stoplinecorrection
+
+Later we will write a compact, efficient macro to take care of rotation. However,
+for the moment, so as not to overwhelm you with complicated code, we will rotate
+each individual picture with the following code fragment.
+
+\startbuffer[rots]
+\startMPdrawing
+ numeric delta, extra, radius, rot[] ;
+
+ delta := extra := radius := 0 ;
+
+ for i=1 upto n :
+ rot[i] := extra+delta-((pos[i]+.5wid[i])/len[n])*(180+2delta) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[rots]
+
+Here we introduce a few variables that we can use later to tune the result a bit.
+With \type {delta}, the space between the characters can be increased, while
+\type {extra} rotates the whole string around the origin. The \type {radius}
+variable can be used to increase the distance to the origin. Without these
+variables, the assignment would have been:
+
+\starttyping
+rot[i] := ((pos[i]+.5wid[i])/len[n])*180 ;
+\stoptyping
+
+Placing the pictures is now rather easy:
+
+\startbuffer[done]
+\startMPdrawing
+ for i=1 upto n :
+ draw pic[i] shifted (-radius,0) rotatedaround(origin,rot[i]) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[done]
+
+The pictures are now positioned on half a circle, properly kerned.
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,swap,cent,shif,rots,done,show]
+\stoplinecorrection
+
+A bit more insight is given in the next picture:
+
+\startbuffer[test]
+\startMPdrawing
+ def moved(expr i) =
+ shifted (-radius,0) rotatedaround(origin,rot[i])
+ enddef ;
+ pickup pencircle scaled .5pt ;
+ for i=1 upto n :
+ draw pic[i] moved(i) ;
+ draw boundingbox pic[i] moved(i) withcolor red ;
+ draw origin -- center pic[i] moved(i) withcolor green ;
+ endfor ;
+ draw tcircle scaled 2r withcolor blue ;
+\stopMPdrawing
+\stopbuffer
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,swap,cent,shif,rots,test,show]
+\stoplinecorrection
+
+This was defined as follows. The path variable \type {tcycle} is predefined to
+the top half of a fullcircle.
+
+\typebuffer[test]
+
+We will now package all of this into a nice, efficient macro, using, of course,
+the predefined scratch registers \type {\MPtoks} and \type {\MPbox}. First we
+define the token processor. Note again the expansion inhibition switch \type
+{[-]}.
+
+\startbuffer
+\def\processrotationtoken#1%
+ {\appendtoks#1\to\MPtoks
+ \setbox\MPbox=\hbox{\RotFont\the\MPtoks}%
+ \startMPdrawing
+ n := n + 1 ; len[n] := \the\wd\MPbox ;
+ \stopMPdrawing
+ \startMPdrawing[-]
+ pic[n] := textext("\RotFont\setstrut\strut#1") ;
+ pic[n] := pic[n] shifted - llcorner pic[n] ;
+ \stopMPdrawing}
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+The main macro is a bit more complicated but by using a few scratch numerics, we
+can keep it readable.
+
+\startbuffer
+\def\rotatetokens#1#2#3#4% delta extra radius tokens
+ {\vbox\bgroup
+ \MPtoks\emptytoks
+ \resetMPdrawing
+ \startMPdrawing
+ picture pic[] ;
+ numeric wid, len[], rot ;
+ numeric delta, extra, radius, n, r ;
+ len[0] := n := 0 ;
+ delta := #1 ; extra := #2 ; radius := #3 ;
+ \stopMPdrawing
+ \handletokens#4\with\processrotationtoken
+ \startMPdrawing
+ r := len[n]/pi ;
+ for i=1 upto n :
+ wid := abs(xpart lrcorner pic[i] -
+ xpart llcorner pic[i]) ;
+ rot := extra + delta -
+ ((len[i]-.5wid)/len[n]) * (180+2delta) ;
+ draw pic[i]
+ rotatedaround (origin,-270) shifted (-r-radius,
+ ypart -.5[ulcorner pic[i], llcorner pic[i]])
+ rotatedaround (origin,rot) ;
+ endfor ;
+ \stopMPdrawing
+ \MPdrawingdonetrue
+ \getMPdrawing
+ \resetMPdrawing
+ \egroup}
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+\startbuffer
+\startcombination[3*1]
+ {\rotatetokens {0} {0}{0}{Does it work ok?}} {A}
+ {\rotatetokens{20} {0}{0}{Does it work ok?}} {B}
+ {\rotatetokens{20}{30}{0}{Does it work ok?}} {C}
+\stopcombination
+\stopbuffer
+
+We can use this macro as follows:
+
+\typebuffer
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+The previous macro is not really an example of generalization, but we used it for
+demonstrating how to build graphics in a stepwise way. If you put the steps in
+buffers, you can even combine steps and replace them at will. This is how we made
+the previous step by step examples: We put each sub||graphic in a buffer and then
+called the ones we wanted.
+
+We now present a more general approach to typesetting along a given path. This
+method is not only more robust and general, it is also a more compact definition,
+especially if we omit the tracing and testing code. We use a familiar auxiliary
+definition. The \type {\setstrut} and \type {\strut} commands ensure that the
+lines have the proper depth and height.
+
+\startbuffer
+\def\processfollowingtoken#1%
+ {\appendtoks#1\to\MPtoks
+ \setbox\MPbox=\hbox{\RotFont\setstrut\strut\the\MPtoks}%
+ \startMPdrawing
+ n := n + 1 ; len[n] := \the\wd\MPbox ;
+ \stopMPdrawing
+ \startMPdrawing[-]
+ pic[n] := btex \RotFont\setstrut\strut#1 etex ;
+ pic[n] := pic[n] shifted -llcorner pic[n] ;
+ \stopMPdrawing}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+In \MKII\ the previous code is collected in the macro \type {\followtokens} but
+in \MKIV\ we use a different approach. There we use a mix of \TEX, \METAPOST, and
+\LUA\ to define that macro. The principles remain the same but the code is more
+robust.
+
+\input meta-imp-txt.mkiv % we need to force a reload \useMPlibrary[txt]
+
+So, how does this compare to earlier results? The original, full text as typeset
+by \TEX, looks like:
+
+\blank \start \RotFont We now follow some arbitrary path ... \stop \blank
+
+In the examples, the text is typeset along the path with:
+
+\startbuffer[toks]
+\followtokens{We now follow some arbitrary path ...}
+\stopbuffer
+
+\typebuffer[toks]
+
+\startlinecorrection[blank]
+\getbuffer[toks]
+\stoplinecorrection
+
+Since we did not set a path, a dummy path is used. We can provide a path by
+(re)defining the graphic \type {followtokens}.
+
+\startbuffer[trac]
+\startMPinclusions
+ boolean TraceRot ; TraceRot := true ;
+\stopMPinclusions
+\stopbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := fullcircle ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer
+\typebuffer[draw]
+\startlinecorrection[blank]
+\hbox
+ {\getbuffer[draw,toks]\hskip1cm
+ \getbuffer[trac,draw,toks]}
+\stoplinecorrection
+\stopbuffer
+
+\getbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := reverse fullcircle ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := (-3cm,-1cm)--(0,1cm)--(3cm,-1cm) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := (-3cm,0)--(3cm,1cm) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := (-3cm,0)..(-1cm,1cm)..(3cm,0) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := (-3cm,0)..(-1cm,1cm)..(0cm,-2cm)..(3cm,0) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer
+
+When turned on, tracing will produce bounding boxes as well as draw the path.
+Tracing can be turned on by saying:
+
+\typebuffer[trac]
+
+% let's turn it off now
+
+\startMPinclusions
+ boolean TraceRot ; TraceRot := false ;
+\stopMPinclusions
+
+The next example is dedicated to Giuseppe Bilotta who wants to handle multiple
+strings and uses a patched version of \type {\followtokens}. To avoid a
+complicated explanation, we will present an alternative here that uses overlays.
+This method also avoids complicated path definitions.
+
+\startbuffer
+\startoverlay
+ {\startuseMPgraphic{followtokens}
+ draw fullcircle scaled 5cm .
+ withpen pencircle scaled 1pt withcolor .625yellow ;
+ draw fullsquare scaled 5.25cm
+ withpen pencircle scaled 1pt withcolor .625red ;
+ drawoptions (withcolor .625red) ;
+ path RotPath ; RotPath := halfcircle scaled 5cm ;
+ setbounds currentpicture to boundingbox fullcircle scaled 5.25cm ;
+ \stopuseMPgraphic
+ \followtokens { Met{\`a} superiore }}
+ {\startuseMPgraphic{followtokens}
+ drawoptions (withcolor .625red) ;
+ path RotPath ; RotPath := halfcircle rotated 90 scaled 5cm ;
+ setbounds currentpicture to boundingbox fullcircle scaled 5.25cm ;
+ \stopuseMPgraphic
+ \followtokens { {$\star$} }}
+ {\startuseMPgraphic{followtokens}
+ drawoptions (withcolor .625red) ;
+ path RotPath ; RotPath := halfcircle rotated 180 scaled 5cm ;
+ setbounds currentpicture to boundingbox fullcircle scaled 5.25cm ;
+ \stopuseMPgraphic
+ \followtokens { Met{\`a} inferiore }}
+ {\startuseMPgraphic{followtokens}
+ drawoptions (withcolor .625red) ;
+ path RotPath ; RotPath := halfcircle rotated 270 scaled 5cm ;
+ setbounds currentpicture to boundingbox fullcircle scaled 5.25cm ;
+ \stopuseMPgraphic
+ \followtokens { {$\star$} }}
+\stopoverlay
+\stopbuffer
+
+\typebuffer
+
+In order to fool the overlay macro that each graphic has the same size, we force
+a bounding box.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Talking to \TEX}]
+
+Sometimes, others may say oftentimes, we are in need for some fancy typesetting.
+If we want to typeset a paragraph of text in a non standard shape, like a circle,
+we have to fall back on \type {\parshape}. Unfortunately, \TEX\ is not that
+strong in providing the specifications of more complicated shapes, unless you are
+willing to do some complicated arithmetic \TEX. Given that \METAPOST\ knows how
+to deal with shapes, the question is: \quotation {Can \METAPOST\ be of help?}
+
+In the process of finding out how to deal with this, we first define a simple
+path. Because we are going to replace pieces of code, we will compose the graphic
+from components. First, we create the path.
+
+\startbuffer
+\startuseMPgraphic{text path}
+ path p ; p := ((0,1)..(-1,0)..(1,0)--cycle) scaled 65pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This shape is not that beautiful, but it has a few characteristics that will help
+us to identify bordercases.
+
+\startbuffer
+\startuseMPgraphic{text draw}
+ drawarrow p withpen pencircle scaled 1pt withcolor red ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Now we use \CONTEXT's \type {\includeMPgraphic} command to build our graphic from
+the previously defined components.
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text path}
+ \includeMPgraphic{text draw}
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+When called with \type {\useMPgraphic{text}}, we get:
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+For the moment we start the path at $(x=0,y>0)$, but later using more complicated
+macros, we will see that we can use arbitrary paths.
+
+We are going to split the path in two, and will use the points that make up the
+bounding box as calcutated by \METAPOST. The next graphic shows one of these
+points, the lower left corner, available as point \typ {llcorner p}.
+
+\startbuffer
+\startuseMPgraphic{text draw}
+ draw p withpen pencircle scaled 3pt withcolor red ;
+ draw boundingbox p withpen pencircle scaled 1pt ;
+ draw llcorner p withpen pencircle scaled 5pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+The five points that \METAPOST\ can report for each path or picture are:
+
+\starttabulate[|Tl|l|]
+\NC llcorner \NC lower left corner \NC \NR
+\NC lrcorner \NC lower right corner \NC \NR
+\NC urcorner \NC upper right corner \NC \NR
+\NC ulcorner \NC upper left corner \NC \NR
+\NC center \NC intersection of the diagonals \NC \NR
+\stoptabulate
+
+If we want to typeset text inside this circle, we need to know where a line
+starts and ends. Given that lines are horizontal and straight, we therefore need
+to calculate the intersection points of the lines and the path. As a first step,
+we calculate the top and bottom of the path and after that we split off the left
+and right path.
+
+\startbuffer
+\startuseMPgraphic{text split}
+ pair t, b ; path l, r ;
+
+ t := (ulcorner p -- urcorner p) intersectionpoint p ;
+ b := (llcorner p -- lrcorner p) intersectionpoint p ;
+
+ l := p cutbefore t ; l := l cutafter b ;
+ r := p cutbefore b ; r := r cutafter t ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The \type {intersectionpoint} macro returns the point where two paths cross. If
+the paths don't cross, an error is reported, when the paths cross more times,
+just one point is returned. The \type {cutafter} and \type {cutbefore} commands
+do as their names say and return a path.
+
+In the \type {text split} code fragment, \type {t} and \type {b} are the top
+points of the main path, while \type {l} and \type {r} become the left and right
+half of path \type {p}.
+
+We now draw the original path using a thick pen and both halves with a thinner
+pen on top of the original. The arrows show the direction.
+
+\startbuffer
+\startuseMPgraphic{text draw}
+ draw p withpen pencircle scaled 3pt withcolor red ;
+ drawarrow l withpen pencircle scaled 1pt withcolor green ;
+ drawarrow r withpen pencircle scaled 1pt withcolor blue ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We use \type {\includeMPgraphic} to assemble the components:
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text path}
+ \includeMPgraphic{text split}
+ \includeMPgraphic{text draw}
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This graphic is typeset with \type {\useMPgraphic{text}}:
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+Before we are going to use them, we define some variables that specify the text.
+We use a baseline distance of 8~points. The part of the line above the baseline
+is 7.2~points, while the (maximum) depth is 2.8~points. These ratios are the ones
+we use in \CONTEXT. Because we don't want the text to touch the circle so we
+define an offset too.
+
+\startbuffer
+\startuseMPgraphic{text vars}
+ baselineskip := 8pt ;
+ strutheight := (7.2/10) * baselineskip ;
+ strutdepth := (2.8/10) * baselineskip ;
+ offset := baselineskip/2 ;
+ topskip := strutheight ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We more or less achieve the offset by scaling the path. In doing so, we use the
+width and height, which we call \type {hsize} and \type {vsize}, thereby
+conforming to the \TEX\ naming scheme.
+
+First we calculate both dimensions from the bounding box of the path. Next we
+down scale the path to compensate for the offset. When done, we recalculate the
+dimensions.
+
+\startbuffer
+\startuseMPgraphic{text move}
+ pair t, b ; path q, l, r ;
+
+ hsize := xpart lrcorner p - xpart llcorner p ;
+ vsize := ypart urcorner p - ypart lrcorner p ;
+
+ q := p xscaled ((hsize-2offset)/hsize)
+ yscaled ((vsize-2offset)/vsize) ;
+
+ hsize := xpart lrcorner q - xpart llcorner q ;
+ vsize := ypart urcorner q - ypart lrcorner q ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startuseMPgraphic{text split}
+ t := (ulcorner q -- urcorner q) intersectionpoint q ;
+ b := (llcorner q -- lrcorner q) intersectionpoint q ;
+
+ l := q cutbefore t ; l := l cutafter b ;
+ r := q cutbefore b ; r := r cutafter t ;
+\stopuseMPgraphic
+\stopbuffer
+
+We adapt the \type {text split} code to use the reduced path
+instead of the original.
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startuseMPgraphic{text draw}
+ drawarrow p withpen pencircle scaled 1pt withcolor red ;
+ draw t withpen pencircle scaled 2pt ;
+ draw b withpen pencircle scaled 2pt ;
+ drawarrow l withpen pencircle scaled 1pt withcolor green ;
+ drawarrow r withpen pencircle scaled 1pt withcolor blue ;
+\stopuseMPgraphic
+\stopbuffer
+
+In order to test what we have reached so far, we draw the original path, the left
+and right part of the reduced path, and both the top and bottom point.
+
+\typebuffer \getbuffer
+
+Again we use \type {\includeMPgraphic} to combine the
+components into a graphic.
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text path} \includeMPgraphic{text vars}
+ \includeMPgraphic{text move} \includeMPgraphic{text split}
+ \includeMPgraphic{text draw}
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Then we use \type {\useMPgraphic{text}} to call up the picture.
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+The offset is not optimal. Note the funny gap at the top. We could try to fix
+this, but there is a better way to optimize both paths.
+
+We lower the top edge of \type {q}'s bounding box by \type {topskip}, then cut
+any part of the left and right pieces of \type {q} that lie above it. Similarly,
+we raise the bottom edge and cut off the pieces that fall below this line.
+
+\startbuffer
+\startuseMPgraphic{text cutoff}
+ path tt, bb ;
+
+ tt := (ulcorner q -- urcorner q) shifted (0,-topskip) ;
+ bb := (llcorner q -- lrcorner q) shifted (0,strutdepth) ;
+
+ l := l cutbefore (l intersectionpoint tt) ;
+ l := l cutafter (l intersectionpoint bb) ;
+ r := r cutbefore (r intersectionpoint bb) ;
+ r := r cutafter (r intersectionpoint tt) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Because we use \type {\includeMPgraphic} to construct the graphic, we can
+redefine \type {text draw} to show the result of this effort.
+
+\startbuffer
+\startuseMPgraphic{text draw}
+ drawarrow p withpen pencircle scaled 1pt withcolor red ;
+ drawarrow l withpen pencircle scaled 1pt withcolor green ;
+ drawarrow r withpen pencircle scaled 1pt withcolor blue ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The \type {text} graphic now becomes:
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text path} \includeMPgraphic{text vars}
+ \includeMPgraphic{text move} \includeMPgraphic{text split}
+ \includeMPgraphic{text cutoff} \includeMPgraphic{text draw}
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Or, as graphic:
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+We are now ready for an attempt to calculate the shape of the text. For each
+line, we have to calculate the left and right intersection points, and since a
+line has a height and depth, we have to determine which part touches first.
+
+\startbuffer
+\startuseMPgraphic{text calc}
+ vardef found_point (expr lin, pat, sig) =
+ pair a, b ;
+ a := pat intersection_point (lin shifted (0,strutheight)) ;
+ if intersection_found :
+ a := a shifted (0,-strutheight) ;
+ else :
+ a := pat intersection_point lin ;
+ fi ;
+ b := pat intersection_point (lin shifted (0,-strutdepth)) ;
+ if intersection_found :
+ if sig :
+ if xpart b > xpart a : a := b shifted (0,strutdepth) fi ;
+ else :
+ if xpart b < xpart a : a := b shifted (0,strutdepth) fi ;
+ fi ;
+ fi ;
+ a
+ enddef ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Instead of using \METAPOST's \type {intersectionpoint} macro, we use one that
+comes with \CONTEXT. That way we don't get an error message when no point is
+found, and can use a boolean flag to take further action. Since we use a \type
+{vardef}, all calculations are hidden and the~\type {a} at the end is returned,
+so that we can use this macro in an assignment. The \type {sig} variable is used
+to distinguish between the beginning and end of a line (the left and right
+subpath).
+
+\startbuffer
+\startuseMPgraphic{text step}
+ path line; pair lll, rrr ;
+
+ for i=topskip step baselineskip until vsize :
+
+ line := (ulcorner q -- urcorner q) shifted (0,-i) ;
+
+ lll := found_point(line,l,true ) ;
+ rrr := found_point(line,r,false) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Here we divide the available space in lines. The first line starts at \type
+{strutheight} from the top.
+
+We can now finish our graphic by visualizing the lines. Both the height and depth
+of the lines are shown.
+
+\startbuffer
+\startuseMPgraphic{text line}
+ fill (lll--rrr--rrr shifted (0,strutheight)--lll
+ shifted (0,strutheight)--cycle) withcolor .5white ;
+ fill (lll--rrr--rrr shifted (0,-strutdepth)--lll
+ shifted (0,-strutdepth)--cycle) withcolor .7white ;
+ draw lll withpen pencircle scaled 2pt ;
+ draw rrr withpen pencircle scaled 2pt ;
+ draw (lll--rrr) withpen pencircle scaled .5pt ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{text done}
+ endfor ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The result is still a bit disappointing.
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text path} \includeMPgraphic{text vars}
+ \includeMPgraphic{text move} \includeMPgraphic{text split}
+ \includeMPgraphic{text cutoff} \includeMPgraphic{text draw}
+ \includeMPgraphic{text calc} \includeMPgraphic{text step}
+ \includeMPgraphic{text line} \includeMPgraphic{text done}
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+In order to catch the overflow at the bottom, we need to change the \type
+{for}||loop a bit, so that the number of lines does not exceed the available
+space. The test that surrounds the assignment of \type {vvsize} makes sure that
+we get better results when we (on purpose) take a smaller height.
+
+\startbuffer
+\startuseMPgraphic{text step}
+ path line; pair lll, rrr ; numeric vvsize ;
+
+ if (strutheight+strutdepth<baselineskip) :
+ vvsize := vsize ;
+ else :
+ vvsize := (vsize div baselineskip) * baselineskip ;
+ fi ;
+
+ for i=topskip step baselineskip until vvsize :
+
+ line := (ulcorner q -- urcorner q) shifted (0,-i) ;
+
+ lll := found_point(line,l,true ) ;
+ rrr := found_point(line,r,false) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+We can manipulate the heigth and depth of the lines to give different (and maybe
+better) results.
+
+\startbuffer
+\startuseMPgraphic{text vars}
+baselineskip := 8pt ;
+strutheight := 4pt ;
+strutdepth := 2pt ;
+offset := 4pt ;
+topskip := 3pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+This kind of graphic trickery in itself is not enough to get \TEX\ into
+typesetting within the bounds of a closed curve. Since \METAPOST\ can write
+information to a file, and \TEX\ can read such a file, a natural way to handle
+this is to let \METAPOST\ write a \type {\parshape} specification.
+
+\startbuffer
+\startuseMPgraphic{text macro}
+ def provide_parshape (expr p, offset, baselineskip,
+ strutheight, strutdepth, topskip) =
+
+ \includeMPgraphic{text move}
+ \includeMPgraphic{text split}
+ \includeMPgraphic{text cutoff}
+ \includeMPgraphic{text draw}
+ \includeMPgraphic{text calc}
+ \includeMPgraphic{text loop}
+ \includeMPgraphic{text save}
+
+ enddef ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We have to adapt the for||loop to register the information about the lines. After
+the loop we write those values to a file using another loop.
+
+\startbuffer
+\startuseMPgraphic{text loop}
+ path line; pair lll, rrr ; numeric vvsize, n ; n := 0 ;
+
+ if (strutheight+strutdepth<baselineskip) :
+ vvsize := vsize ;
+ else :
+ vvsize := (vsize div baselineskip) * baselineskip ;
+ fi ;
+
+ for i=topskip step baselineskip until vvsize :
+
+ line := (ulcorner q -- urcorner q) shifted (0,-i) ;
+
+ lll := found_point(line,l,true ) ;
+ rrr := found_point(line,r,false) ;
+
+ n := n + 1 ;
+
+ indent[n] := abs(xpart lll - xpart llcorner q) ;
+ width[n] := abs(xpart rrr - xpart lll) ;
+
+ endfor ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{text save}
+ write "\parshape " & decimal n to "mfun-mp-data.txt" ;
+ for i=1 upto n:
+ write decimal indent[i]&"bp " &
+ decimal width[i]&"bp " to "mfun-mp-data.txt" ;
+ endfor ;
+ write EOF to "mfun-mp-data.txt" ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We can call this macro using the part we used in the previous examples.
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text macro}
+
+ path p ; p := ((0,1)..(-1,0)..(1,0)--cycle) scaled 65pt ;
+
+ provide_parshape
+ (p, % shape path
+ .5*\baselinedistance, % offset
+ \baselinedistance, % distance between lines
+ \strutheight, % height of a line
+ \strutdepth, % depth of a line
+ \strutheight) ; % height of first line
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+After we called \type {\useMPgraphic{text}}, the resulting file looks as follows.
+You can call up this file by its anonymous name \type {\MPdatafile}, since this
+macro gets the value of the graphic at hand.
+
+\startnointerference
+ \useMPgraphic{text}
+\stopnointerference
+
+\typefile{mfun-mp-data.txt}
+
+% \blank{\em todo: mp data file}\blank
+% \writestatus{!!!!}{todo: mp data file}
+
+So, reading in this file at the start of a paragraph will setup \TEX\ to follow
+this shape.
+
+The final implementation is a bit more complicated since it takes care of paths
+that are not centered around the origin and don't start at the top point. We
+achieve this by moving the path to the center:
+
+\starttyping
+cp := center p ; q := p shifted - cp ;
+\stoptyping
+
+The arbitrary starting point is taken care of by a slightly more complicated path
+cutter. First we make sure that the path runs counterclockwise.
+
+\starttyping
+if xpart directionpoint t of q < 0 : q := reverse q fi ;
+\stoptyping
+
+Knowing this, we can split the path in two, using a slightly different splitter:
+
+\starttyping
+l := q cutbefore t ;
+l := l if xpart point 0 of q < 0 : & q fi cutafter b ;
+r := q cutbefore b ;
+r := r if xpart point 0 of q > 0 : & q fi cutafter t ;
+\stoptyping
+
+As always, when implementing a feature like this, some effort goes into a proper
+user interface. In doing so, we need some \TEX\ trickery that goes beyond this
+text, like collecting text and splitting of the part needed. Also, we want to be
+able to handle multiple shapes at once, like the next example demonstrates.
+
+\stopsection
+
+\startsection[title={Libraries}]
+
+\index{graphics+libraries}
+
+The macro discussed in the previous section is included in one of the \METAPOST\
+libraries, so we first have to say:
+
+\startbuffer
+\useMPlibrary[txt]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+We define four shapes. They are not really beautiful, but they demonstrate what
+happens in border cases. For instance, too small first lines are ignored. First
+we define a circle. Watch how the dimensions are set in the graphic. The
+arguments passed to \type {build_parshape} are: path, an offset, an additional
+horizontal and vertical displacement, the baseline distance, the height and depth
+of the line, and the height of the first line (topskip in \TEX\ terminology). The
+height and depth of a line are often called strut height and depth, with a strut
+being an invisible character with maximum dimensions.
+
+\startbuffer
+\startuseMPgraphic{test 1}
+ path p ; p := fullcircle scaled 6cm ;
+
+ build_parshape(p,6pt,0,0,\baselinedistance,
+ \strutheight,\strutdepth,\strutheight) ;
+
+ draw p withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The second shape is a diamond. This is a rather useless shape, unless the text
+suits the small lines at the top and bottom.
+
+\startbuffer
+\startuseMPgraphic{test 2}
+ path p ; p := fullsquare rotated 45 scaled 5cm ;
+
+ build_parshape(p,6pt,0,0,\baselinedistance,
+ \strutheight,\strutdepth,\strutheight) ;
+
+ draw p withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The third and fourth shape demonstrate that providing a suitable offset is not
+always trivial.
+
+\startbuffer
+\startuseMPgraphic{test 3}
+ numeric w, h ; w := h := 6cm ;
+ path p ; p := (.5w,h) -- (0,h) -- (0,0) -- (w,0) &
+ (w,0) .. (.75w,.5h) .. (w,h) & (w,h) -- cycle ;
+
+ build_parshape(p,6pt,0,0,\baselinedistance,
+ \strutheight,\strutdepth,\strutheight) ;
+
+ draw p withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Contrary to the first three shapes, here we use a different path for the
+calculations and the drawing. Watch carefully! If, instead of an offset, we pass
+a path, \METAPOST\ is able to calculate the right dimensions and offsets. This is
+needed, since we need these later on.
+
+\startbuffer
+\startuseMPgraphic{test 4}
+ numeric w, h, o ;
+
+ def shape = (o,o) -- (w-o,o) & (w-o,o) .. (.75w-o,.5h) ..
+ (w-2o,h-o) & (w-2o,h-o) -- (o,h-o) -- cycle
+ enddef ;
+
+ w := h := 6cm ; o := 6pt ; path p ; p := shape ;
+ w := h := 6cm ; o := 0pt ; path q ; q := shape ;
+
+ build_parshape(p,q,6pt,6pt,\baselinedistance,
+ \strutheight,\strutdepth,\strutheight) ;
+
+ draw q withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Since we also want these graphics as backgrounds, we define them as overlays. If
+you don't want to show the graphic, you may omit this step.
+
+\startbuffer
+\defineoverlay[test 1][\useMPgraphic{test 1}]
+\defineoverlay[test 2][\useMPgraphic{test 2}]
+\defineoverlay[test 3][\useMPgraphic{test 3}]
+\defineoverlay[test 4][\useMPgraphic{test 4}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+As text, we use a quote from Douglas R.~Hofstadter's book \quotation {Metamagical
+Themas, Questing for the Essence of Mind and Pattern}. Watch how we pass a list
+of shapes.
+
+\startbuffer[text]
+\startshapetext[test 1,test 2,test 3,test 4]
+ \forgetall % as it says
+ \setupalign[verytolerant,stretch,normal]%
+ \input douglas % Douglas R. Hofstadter
+\stopshapetext
+\stopbuffer
+
+\typebuffer[text]
+
+Finally we combine text and shapes. Since we also want a background, we use \type
+{\framed}. The macros \type {\parwidth} and \type {\parheight} are automatically
+set to the current shape dimensions. The normal result is shown in \in {figure}
+[fig:shapes].
+
+\startbuffer[shapes]
+\startbuffer
+\setupframed
+ [offset=overlay,align=normal,frame=off,
+ width=\parwidth,height=\parheight]
+\startcombination[2*2]
+ {\framed[background=test 1]{\getshapetext}} {test 1}
+ {\framed[background=test 2]{\getshapetext}} {test 2}
+ {\framed[background=test 3]{\getshapetext}} {test 3}
+ {\framed[background=test 4]{\getshapetext}} {test 4}
+\stopcombination
+\stopbuffer
+\stopbuffer
+
+\typebuffer[shapes]
+
+\getbuffer[shapes]
+
+By using a buffer we keep \type {\placefigure} readable.
+
+\startbuffer[a]
+\placefigure
+ [here][fig:shapes]
+ {A continuous text, typeset in a non||standard shape,
+ spread over four areas, and right aligned.}
+ {\getbuffer}
+\stopbuffer
+
+\startbuffer[b]
+\placefigure
+ [here][fig:shapes]
+ {A continuous text, typeset in a non||standard shape,
+ spread over four areas.}
+ {\scale[factor=max,height=.9\textheight]{\getbuffer}}
+\stopbuffer
+
+\typebuffer[a]
+
+\doifmodeelse{screen}{\getbuffer[text,b]}{\getbuffer[text,a]}
+
+The traced alternative is shown in \in {figure} [fig:traced shapes]. This one is
+defined as:
+
+\startbuffer[a]
+\placefigure
+ [here][fig:traced shapes]
+ {A continuous text, typeset in a non||standard shape,
+ spread over four areas (tracing on).}
+ {\startMPinclusions
+ boolean trace_parshape ; trace_parshape := true ;
+ \stopMPinclusions
+ \getbuffer}
+\stopbuffer
+
+\startbuffer[b]
+\placefigure
+ [here][fig:traced shapes]
+ {A continuous text, typeset in a non||standard shape,
+ spread over four areas (tracing on).}
+ {\startMPinclusions
+ boolean trace_parshape ; trace_parshape := true ;
+ \stopMPinclusions
+ \scale[factor=max,height=.9\textheight]{\getbuffer}}
+\stopbuffer
+
+\typebuffer[a]
+
+\doifmodeelse{screen}{\getbuffer[text,b]}{\getbuffer[text,a]}
+
+% {\em This mechanism is still somewhat experimental and will be optimized and
+% extended with name spaces and more.}
+
+\blank
+
+We can combine all those tricks, although the input is somewhat fuzzy. First we
+define a quote typeset in a circular paragraph shape.
+
+\startbuffer[shape]
+\startuseMPgraphic{center}
+ build_parshape(fullcircle scaled 8cm,0,0,0,\baselinedistance,
+ \strutheight,\strutdepth,\strutheight) ;
+\stopuseMPgraphic
+
+\startshapetext[center]
+ \input douglas
+\stopshapetext
+
+\defineoverlay[center][\useMPgraphic{center}]
+\stopbuffer
+
+\typebuffer[shape]
+
+We will surround this text with a circular line, that we define as follows. By
+using a buffer we keep things organized.
+
+\startbuffer
+\startbuffer[circle]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := reverse fullcircle
+ rotatedaround(origin,90)
+ xscaled \overlaywidth yscaled \overlayheight ;
+ drawoptions (withcolor .625red) ;
+\stopuseMPgraphic
+
+\followtokens
+ {This is just a dummy text, kerned by \TeX\ and typeset
+ in a circle using \MetaPost.\quad}
+\stopbuffer
+
+\defineoverlay[edge][{\getbuffer[circle]}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The text and graphics come together in a framed text:
+
+\startbuffer
+\startbuffer[quote]
+\framed
+ [offset=24pt,
+ background=edge,
+ frame=off,
+ backgroundoffset=-18pt]
+ {\getshapetext}
+\stopbuffer
+
+\placefigure
+ {One more time Hofstadter's quotation (normal).}
+ {\getbuffer[shape,quote]}
+
+\placefigure
+ {One more time Hofstadter's quotation (traced).}
+ {\startMPinclusions
+ boolean TraceRot ; TraceRot := true ;
+ \stopMPinclusions
+ \getbuffer[shape,quote]}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+% {\em Here also, I will rewrite things a bit so that we can avoid \type
+% {\startMPdrawing} outside the macro, and thereby avoid problems. I can also add
+% the maps cdrom cover as example.}
+
+\stopsection
+
+% \startsection[title={Visualizing \TEX}]
+%
+% The next example is a bit out of place in this manual, but nevertheless
+% demonstrates how one can use \METAPOST\ to get insight in what \TEX\ is doing
+% inside.
+%
+% The author of \PDFTEX, \THANH, has extended the paragraph builder with a
+% provision for protruding characters and glyphs substitution, also known as {\it
+% hz} (which stands for Hermann Zapf). The {\it hz} optimization involves an
+% additional pass over the lines and|/|or paragraph, in order to determine how
+% inconsistency in gaps can be reduced by substituting an \quote {\scale [sx=1.01]
+% {a}} by an \quote {\scale [sx=5] {a}} or \quote {\scale [sx=.5] {a}}. In \in
+% {figure} [fig:hz] you can find the visualization in action. By means of colors we
+% indicate in what way glyphs are substituted by slightly larger or smaller values.
+% More details on how the {\it hz} optimization works can be found in \THANH's
+% thesis.
+%
+% \placefigure
+% [page][fig:hz]
+% {When we feed \TEX\ code into \METAPOST\ and back, we
+% can visualize {\it hz}||optimization in a colorful way.}
+% {\doifmodeelse{screen}
+% {\externalfigure[mfun-hzs.pdf][height=.8\textheight]}
+% {\externalfigure[mfun-hzp.pdf][height=.8\textheight]}}
+%
+% In order to avoid a complicated discussion about how to set up \PDFTEX\ to use
+% {\it hz} |<|this can best be left over to the macro package that you use|>| we
+% will illustrate the method behind this kind of visualizations in a more simple
+% case.
+%
+% When you include a \METAPOST\ graphic in \PDFTEX, the output produced by
+% \METAPOST\ is interpreted by a bunch of macros and converted into raw \PDF\ code.
+% In the process special extensions, like shading, transparency, graphic inclusion,
+% are taken care of. When the converter encounters a font inclusion directive,
+% i.e.\ the \POSTSCRIPT\ \type {fshow} operator, it uses the \TEX\ font handler to
+% take care of the font. A benefit of this approach is that \TEX\ and \METAPOST\
+% share the same font resources and therefore the inclusion is done in the way
+% expected.
+%
+% The low level macro that takes care of the font inclusion provides a couple of so
+% called hooks, that permit us to do additional manipulations with the character
+% sequences that are encountered.
+%
+% \startbuffer[demo]
+% draw
+% btex \definedfont[cmr10]%
+% Combine the power of \TeX\ and \MetaPost !
+% etex scaled 2 ;
+% \stopbuffer
+%
+% \typebuffer[demo]
+%
+% When processed, this gives the graphic:
+%
+% \startlinecorrection[blank]
+% \processMPbuffer[demo]
+% \stoplinecorrection
+%
+% The result is not spectacular, and there is no indication that \METAPOST\ has
+% been in action. The following line of code sets the hook \type {\MPfshowcommand}
+% |<|this commands takes one argument|>| to produce a ruled horizontal box.
+%
+% \startbuffer
+% \let\MPfshowcommand\ruledhbox
+% \stopbuffer
+%
+% \typebuffer
+%
+% \startlinecorrection[blank]
+% \getbuffer \processMPbuffer[demo]
+% \stoplinecorrection
+%
+% If you watch closely, you will see that the ruled boxes contain one or more
+% characters (or more precise glyphs). This is a result from \TEX\ explicitely
+% kerning characters.
+%
+% A second hook is provided in the macro that takes care of the font switch. This
+% command is defined as follows:
+%
+% \starttyping
+% \def\setMPfshowfont#1#2%
+% {\font\temp=#1\space at #2\relax\temp}
+% \stoptyping
+%
+% The first argument is the raw font name, and the second argument specifies the
+% desired size. If we want to see what fonts are involved, we can redefine the
+% hooks as follows.
+%
+% \starttyping
+% \def\setMPfshowfont#1#2%
+% {\message{[using #1 at #2 in mp graphic]}%
+% \font\temp=#1\space at #2\relax\temp}
+% \stoptyping
+%
+% It happens that two fonts are used: \type {cmr10} and \type {logo10}. Once we
+% know this, we can apply some magic: we set the color to the fontname and define a
+% couple of colors that match the name.
+%
+% \startbuffer
+% \definecolor [cmr10] [darkred]
+% \definecolor [logo10] [darkyellow]
+%
+% \def\setMPfshowfont#1#2%
+% {\color[#1]\font\temp=#1\space at #2\relax\temp}
+% \stopbuffer
+%
+% \typebuffer
+%
+% In the case of the \type {\it hz} examples we had to define a couple of more
+% colors, but the principle remains.
+%
+% \startlinecorrection[blank]
+% \getbuffer \processMPbuffer[demo]
+% \stoplinecorrection
+%
+% We don't expect the user to use tricks like this on a daily basis, but it
+% demonstrates that with a bit of knowlegde of the internals of \CONTEXT, you can
+% produce nice examples of typographic programming.
+%
+% \stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-titlepage-paper.tex b/doc/context/sources/general/manuals/metafun/metafun-titlepage-paper.tex
new file mode 100644
index 000000000..558e3b798
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-titlepage-paper.tex
@@ -0,0 +1,23 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\doifmode{book}{\endinput}
+
+\startcomponent mfun-titlepage-paper
+
+\environment metafun-environment
+
+\setupbackgrounds
+ [rightpage]
+ [background=title page]
+
+\startstandardmakeup
+ % title page
+\stopstandardmakeup
+
+\setupbackgrounds
+ [rightpage]
+ [background=]
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-titlepage-screen.tex b/doc/context/sources/general/manuals/metafun/metafun-titlepage-screen.tex
new file mode 100644
index 000000000..6350bdbda
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-titlepage-screen.tex
@@ -0,0 +1,30 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-titlepage-screen
+
+\environment metafun-environment
+
+\startstandardmakeup[topstate=empty]
+
+ \definefont[Big] [RegularBold*default at 60pt]
+ \definefont[Medium][RegularBold*default at 48pt]
+ \definefont[Small] [RegularBold*default at 32pt]
+ \definefont[Tiny] [RegularBold*default at 24pt]
+
+% \showstruts
+
+ \startcolor[darkyellow]
+
+ \Big METAFUN \par
+ \Tiny \setstrut \strut context mkiv \par
+ \vfill
+ \Tiny \setstrut \hfill \strut \currentdate \par
+ \Small \setstrut \hfill \strut Hans Hagen \par
+
+ \stopcolor
+
+\stopstandardmakeup
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-welcome.tex b/doc/context/sources/general/manuals/metafun/metafun-welcome.tex
new file mode 100644
index 000000000..425d15796
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-welcome.tex
@@ -0,0 +1,3502 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-welcome
+
+\environment metafun-environment
+
+\startchapter[reference=sec:welcome,title={Welcome to MetaPost}]
+
+\startintro
+
+In this chapter, we will introduce the most important \METAPOST\ concepts as well
+as demonstrate some drawing primitives and operators. This chapter does not
+replace the \METAFONT\ book or \METAPOST\ manual, both of which provide a lot of
+explanations, examples, and (dirty) tricks.
+
+As its title says, the \METAFONT\ book by Donald.\ E.\ Knuth is about fonts.
+Nevertheless, buying a copy is worth the money, because as a \METAPOST\ user you
+can benefit from the excellent chapters about curves, algebraic expressions, and
+(linear) equations. The following sections are incomplete in many aspects. More
+details on how to define your own macros can be found in both the \METAFONT\ book
+and \METAPOST\ manual, but you will probably only appreciate the nasty details if
+you have written a few simple figures yourself. This chapter will give you a
+start.
+
+A whole section is dedicated to the basic extensions to \METAPOST\ as provided by
+\METAFUN. Most of them are meant to make defining graphics like those shown in
+this document more convenient.
+
+Many of the concepts introduced here will be discussed in more detail in later
+chapters. So, you may consider this chapter to be an appetizer for the following
+chapters. If you want to get started quickly, you can safely skip this chapter
+now.
+
+\stopintro
+
+\startsection[title={Paths}]
+
+\index{paths}
+
+Paths are the building blocks of \METAPOST\ graphics. In its simplest form, a
+path is a single point.
+
+\startuseMPgraphic{axis}
+ tickstep := 1cm ; ticklength := 2mm ;
+ drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ;
+ tickstep := tickstep/2 ; ticklength := ticklength/2 ;
+ drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ;
+\stopuseMPgraphic
+
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ drawpoint "1cm,1.5cm" ;
+\stopMPcode
+\stoplinecorrection
+
+Such a point is identified by two numbers, which represent the horizontal and
+vertical position, often referred to as $x$ and $y$, or $(x,y)$. Because there
+are two numbers involved, in \METAPOST\ this point is called a pair. Its related
+datatype is therefore \type {pair}. The following statements assigns the point we
+showed previously to a pair variable.
+
+\starttyping
+pair somepoint ; somepoint := (1cm,1.5cm) ;
+\stoptyping
+
+A pair can be used to identify a point in the two dimensional coordinate space,
+but it can also be used to denote a vector (being a direction or displacement).
+For instance, \type {(0,1)} means \quote {go up}. Looking through math glasses,
+you may consider them vectors, and if you know how to deal with them, \METAPOST\
+may be your friend, since it knows how to manipulate them.
+
+You can connect points and the result is called a path. A path is a straight or
+bent line, and is not necessarily a smooth curve. An example of a simple
+rectangular path is: \footnote {In the next examples we use the debugging
+features discussed in \in {chapter} [sec:debugging] to visualize the points,
+paths and bounding boxes.}
+
+\startuseMPgraphic{path}
+ path p ;
+ p := unitsquare xyscaled (2cm,1cm) shifted (.5cm,.5cm) ;
+\stopuseMPgraphic
+
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ drawpath p ;
+\stopMPcode
+\stoplinecorrection
+
+This path is constructed out of four points:
+
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ swappointlabels := true ; drawpath p ; drawpoints p ;
+\stopMPcode
+\stoplinecorrection
+
+Such a path has both a beginning and end and runs in a certain direction:
+
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ autoarrows := true ;
+ swappointlabels := true ; drawarrowpath p ; drawpoints p ;
+\stopMPcode
+\stoplinecorrection
+
+A path can be open or closed. The previous path is an example of a closed path.
+An open path looks like this:
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,1.5cm)..(2cm,0cm) ;
+\stopuseMPgraphic
+
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ swappointlabels := true ; drawpath p ; drawpoints p ;
+\stopMPcode
+\stoplinecorrection
+
+When we close this path |<|and in a moment we will see how to do this|>| the path
+looks like:
+
+\startbuffer
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ p := p .. cycle ;
+ swappointlabels := true ; drawpath p ; drawpoints p ;
+\stopMPcode
+\stoplinecorrection
+\stopbuffer
+
+\getbuffer
+
+The open path is defined as:
+
+\starttyping
+(1cm,1cm)..(1.5cm,1.5cm)..(2cm,0cm)
+\stoptyping
+
+The \quote {double period} connector \type {..} tells \METAPOST\ that we want to
+connect the lines by a smooth curve. If you want to connect points with straight
+line segments, you should use \type {--}.
+
+Closing the path is done by connecting the first and last point, using the \type
+{cycle} command.
+
+\starttyping
+(1cm,1cm)..(1.5cm,1.5cm)..(2cm,0cm)..cycle
+\stoptyping
+
+Feel free to use \type {..} or \type {--} at any point in your path.
+
+\starttyping
+(1cm,1cm)--(1.5cm,1.5cm)..(2cm,0cm)..cycle
+\stoptyping
+
+\startuseMPgraphic{path}
+path p ; p := (1cm,1cm)--(1.5cm,1.5cm)..(2cm,0cm)..cycle ;
+\stopuseMPgraphic
+
+This path, when drawn, looks like this:
+
+\getbuffer
+
+As you can see in some of the previous examples, \METAPOST\ is capable of drawing
+a smooth curve through the three points that make up the path. We will now
+examine how this is done.
+
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ p := p .. cycle ; swappointlabels := true ;
+ drawpath p ; drawcontrollines p ; drawpoints p ; drawcontrolpoints p ;
+\stopMPcode
+\stoplinecorrection
+
+The six small points are the so called control points. These points pull their
+parent point in a certain direction. The further away such a point is, the
+stronger the pull.
+
+Each point has at most two control points. As you can see in the following
+graphic, the endpoints of a non closed curve have only one control point.
+
+\startuseMPgraphic{path}
+path p ; p := (1.5cm,1.5cm)..(2cm,0cm)..(1cm,1cm) ;
+\stopuseMPgraphic
+
+\startbuffer[path]
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ swappointlabels := true ;
+ drawpath p ; drawcontrollines p ; drawpoints p ; drawcontrolpoints p ;
+\stopMPcode
+\stoplinecorrection
+\stopbuffer
+
+\getbuffer[path]
+
+This time we used the path:
+
+\starttyping
+(1.5cm,1.5cm)..(2cm,0cm)..(1cm,1cm)
+\stoptyping
+
+When you connect points by a smooth curve, \METAPOST\ will calculate the control
+points itself, unless you specify one or more of them.
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,1.5cm)..controls (3cm,2cm)..(2cm,0cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+This path is specified as:
+
+\starttyping
+(1cm,1cm)..(1.5cm,1.5cm)..controls (3cm,2cm)..(2cm,0cm)
+\stoptyping
+
+In this path, the second and third point share a control point. Watch how the
+curve is pulled in that direction. It is possible to pull a bit less by choosing
+a different control point:
+
+\starttyping
+(1cm,1cm)..(1.5cm,1.5cm)..controls (2.75cm,1.25cm)..(2cm,0cm)
+\stoptyping
+
+Now we get:
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,1.5cm)..controls (2.75cm,1.25cm)..(2cm,0cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+We can also specify a different control point for each connecting segment.
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..controls (.5cm,2cm) and (2.5cm,2cm)..(2cm,.5cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+This path is defined as:
+
+\starttyping
+(1cm,1cm)..controls (.5cm,2cm) and (2.5cm,2cm)..(2cm,.5cm)
+\stoptyping
+
+\stopsection
+
+\startsection[title={Transformations}]
+
+\index{transformations}
+
+We can store a path in a path variable. Before we can use such a variable, we
+have to allocate its memory slot with \type {path}.
+
+\starttyping
+path p ; p := (1cm,1cm)..(1.5cm,2cm)..(2cm,0cm) ;
+\stoptyping
+
+Although we can manipulate any path in the same way, using a variable saves us
+the effort to key in a path more than once.
+
+\startuseMPgraphic{axis}
+ tickstep := 1cm ; ticklength := 2mm ;
+ drawticks unitsquare xscaled 8cm yscaled 4cm ;
+ tickstep := tickstep/2 ; ticklength := ticklength/2 ;
+ drawticks unitsquare xscaled 8cm yscaled 4cm ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,2cm)..(2cm,0cm)..cycle ;
+ path q ; q := p shifted (4cm,2cm) ;
+\stopuseMPgraphic
+
+\startbuffer[path]
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ swappointlabels := true ;
+ drawpath p ; drawcontrollines p ; drawpoints p ; drawcontrolpoints p ;
+ drawpath q ; drawcontrollines q ; drawpoints q ; drawcontrolpoints q ;
+\stopMPcode
+\stoplinecorrection
+\stopbuffer
+
+\getbuffer[path]
+
+In this graphic, the path stored in \type {p} is drawn twice, once in its
+displaced form. The displacement is defined as:
+
+\starttyping
+p shifted (4cm,2cm)
+\stoptyping
+
+In a similar fashion you can rotate a path. You can even combine shifts and
+rotations. First we rotate the path 15 degrees counter||clockwise around the
+origin.
+
+\starttyping
+p rotated 15
+\stoptyping
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,2cm)..(2cm,0cm)..cycle ;
+ path q ; q := p rotated 15 ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+This rotation becomes more visible when we also shift the path to the right by
+saying:
+
+\starttyping
+rotated 15 shifted (4cm,0cm)
+\stoptyping
+
+Now we get:
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,2cm)..(2cm,0cm)..cycle ;
+ path q ; q := p rotated 15 shifted (4cm,0cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+Note that \type {rotated 15} is equivalent to \typ {p rotatedaround (origin,
+15)}.
+
+It may make more sense to rotate the shape around its center. This can easily be
+achieved with the \type {rotatedaround} command. Again, we move the path to the
+right afterwards.
+
+\starttyping
+p rotatedaround(center p, 15) shifted (4cm,0cm)
+\stoptyping
+
+\startuseMPgraphic{axis}
+ tickstep := 1cm ; ticklength := 2mm ;
+ drawticks unitsquare xscaled 10cm yscaled 3cm ;
+ tickstep := tickstep/2 ; ticklength := ticklength/2 ;
+ drawticks unitsquare xscaled 10cm yscaled 3cm ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,2cm)..(2cm,0cm)..cycle ;
+ path q ; q := p rotatedaround(center p, 15) shifted (4cm,0cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+Yet another transformation is slanting. Just like characters can be upright or
+slanted, a graphic can be:
+
+\starttyping
+p slanted 1.5 shifted (4cm,0cm)
+\stoptyping
+
+\startuseMPgraphic{path}
+ path p ; p := (1cm,1cm)..(1.5cm,2cm)..(2cm,0cm)..cycle ;
+ path q ; q := p slanted 1.5 shifted (4cm,0cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+The slant operation's main application is in tilting fonts. The $x$||coodinates
+are increased by a percentage of their $y$||coordinate, so here every $x$ becomes
+$x+1.5y$. The $y$||coordinate is left untouched. The following table summarizes
+the most important primitive transformations that \METAPOST\ supports.
+
+\starttabulate[|lT|l|]
+\HL
+\NC \METAPOST\ code \NC mathematical equivalent \NC \NR
+\HL
+\NC (x,y) shifted (a,b) \NC $(x+a,y+b)$ \NC \NR
+\NC (x,y) scaled s \NC $(sx,sy)$ \NC \NR
+\NC (x,y) xscaled s \NC $(sx,y)$ \NC \NR
+\NC (x,y) yscaled s \NC $(x,sy)$ \NC \NR
+\NC (x,y) zscaled (u,v) \NC $(xu-yv,xv+yu)$ \NC \NR
+\NC (x,y) slanted s \NC $(x+sy,y)$ \NC \NR
+\NC (x,y) rotated r \NC $(x\cos(r)-y\sin(r),x\sin(r)+y\cos(r))$ \NC \NR
+\HL
+\stoptabulate
+
+The previously mentioned \type {rotatedaround} is not a primitive but a macro,
+defined in terms of shifts and rotations. Another transformation macro is
+mirroring, or in \METAPOST\ terminology, \type {reflectedabout}.
+
+\startbuffer[path]
+\startlinecorrection[blank]
+\startMPcode
+ \includeMPgraphic{axis}
+ \includeMPgraphic{path}
+ swappointlabels := true ;
+ drawpath p ; drawpoints p ;
+ drawpath q ; drawpoints q ;
+\stopMPcode
+\stoplinecorrection
+\stopbuffer
+
+\startuseMPgraphic{path}
+ path p ; p := unitsquare scaled 2cm shifted (2cm,.5cm) ;
+ path q ; q := unitsquare scaled 2cm shifted (2cm,.5cm) reflectedabout((2.4cm,-.5),(2.4cm,3cm)) ;
+ draw (2.4cm,-.5cm)--(2.4cm,3cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+The reflection axis is specified by a pair of points. For example, in the graphic
+above, we used the following command to reflect the square about a line through
+the given points.
+
+\starttyping
+p reflectedabout((2.4cm,-.5),(2.4cm,3cm))
+\stoptyping
+
+The line about which the path is mirrored. Mirroring does not have to be parallel
+to an axis.
+
+\starttyping
+p reflectedabout((2.4cm,-.5),(2.6cm,3cm))
+\stoptyping
+
+The rectangle now becomes:
+
+\startuseMPgraphic{path}
+ path p ; p := unitsquare scaled 2cm shifted (2cm,.5cm) ;
+ path q ; q := unitsquare scaled 2cm shifted (2cm,.5cm) reflectedabout((2.4cm,-.5),(2.6cm,3cm)) ;
+ draw (2.4cm,-.5cm)--(2.6cm,3cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+\pagereference [zscaled]The table also mentions \type {zscaled}.
+
+\startuseMPgraphic{path}
+path p ; p := unitsquare scaled (1cm) shifted (1cm,.5cm) ;
+path q ; q := unitsquare scaled (1cm) zscaled (2,.5) shifted (1cm,.5cm) ;
+\stopuseMPgraphic
+
+\getbuffer[path]
+
+A \type {zscaled} specification takes a vector as argument:
+
+\starttyping
+p zscaled (2,.5)
+\stoptyping
+
+The result looks like a combination of scaling and rotation, and conforms to the
+formula in the previous table.
+
+Transformations can be defined in terms of a transform matrix. Such a matrix is
+stored in a transform variable. For example:
+
+\starttyping
+transform t ; t := identity scaled 2cm shifted (4cm,1cm) ;
+\stoptyping
+
+We use the associated keyword \type {transformed} to apply this matrix to a path
+or picture.
+
+\starttyping
+p transformed t
+\stoptyping
+
+In this example we've taken the \type {identity} matrix as starting point but you
+can use any predefined transformation. The identity matrix is defined in such a
+way that it scales by a factor of one in both directions and shifts over the
+zero||vector.
+
+Transform variables can save quite some typing and may help you to force
+consistency when many similar transformations are to be done. Instead of changing
+the scaling, shifting and other transformations you can then stick to just
+changing the one transform variable.
+
+\stopsection
+
+\startsection[title={Constructing paths}]
+
+\index{paths}
+
+In most cases, a path will have more points than the few shown here. Take for
+instance a so called {\em super ellipse}.
+
+\startlinecorrection[blank]
+\startMPcode
+path p ; p := fullsquare xyscaled (5cm,3cm) superellipsed .85 ;
+drawpath p ; drawpoints p ;
+visualizepaths ; draw p shifted (6cm,0cm) withcolor .625yellow ;
+\stopMPcode
+\stoplinecorrection
+
+These graphics provide a lot of information. In this picture the crosshair in the
+center is the {\em origin} and the dashed rectangle is the {\em bounding box} of
+the super ellipse. The bounding box specifies the position of the graphic in
+relation to the origin as well as its width and height.
+
+In the graphic on the right, you can see the points that make up the closed path
+as well as the control points. Each point has a number with the first point
+numbered zero. Because the path is closed, the first and last point coincide.
+
+\startuseMPgraphic{axis}
+ tickstep := 1cm ; ticklength := 2mm ;
+ drawticks unitsquare xscaled 8cm yscaled 3cm ;
+ tickstep := tickstep/2 ; ticklength := ticklength/2 ;
+ drawticks unitsquare xscaled 8cm yscaled 3cm ;
+\stopuseMPgraphic
+
+\startbuffer
+\startlinecorrection[blank]
+\startMPcode
+ string tmp ; defaultfont := "\truefontname{Mono}" ;
+ \includeMPgraphic{axis}
+ \includeMPgraphic{points}
+ \includeMPgraphic{path}
+ label.lft(verbatim(tmp),(14.5cm,2.5cm)) ;
+ drawwholepath scantokens(tmp) ;
+\stopMPcode
+\stoplinecorrection
+\stopbuffer
+
+We've used the commands \type {..} and \type {--} as path connecting directives.
+In the next series of examples, we will demonstrate a few more. However, before
+doing that, we define a few points, using the predefined \type {z} variables.
+
+\startuseMPgraphic{points}
+ z0 = (0.5cm,1.5cm) ; z1 = (2.5cm,2.5cm) ;
+ z2 = (6.5cm,0.5cm) ; z3 = (3.0cm,1.5cm) ;
+\stopuseMPgraphic
+
+\starttyping
+z0 = (0.5cm,1.5cm) ; z1 = (2.5cm,2.5cm) ;
+z2 = (6.5cm,0.5cm) ; z3 = (3.0cm,1.5cm) ;
+\stoptyping
+
+Here \type {z1} is a short way of saying \type {(x1,y1)}. When a \type {z}
+variable is called, the corresponding \type {x} and \type {y} variables are
+available too. Later we will discuss \METAPOST\ capability to deal with
+expressions, which are expressed using an \type {=} instead of \type {:=}. In
+this case the expression related to \type {z0} is expanded into:
+
+\starttyping
+z0 = (x0,y0) = (0.5cm,1.5cm) ;
+\stoptyping
+
+But for this moment let's forget about their expressive nature and simply see
+them as points which we will now connect by straight line segments.
+
+\startuseMPgraphic{path}
+ tmp := "z0--z1--z2--z3--cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+The smooth curved connection, using \type {..} looks like:
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2..z3..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+If we replace the \type {..} by \type {...}, we get a tighter path.
+
+\startuseMPgraphic{path}
+ tmp := "z0...z1...z2...z3...cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Since there are \type {..}, \type {--}, and \type {...}, it will be no surprise
+that there is also \type {---}.
+
+\startuseMPgraphic{path}
+ tmp := "z0---z1---z2---z3---cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+If you compare this graphic with the one using \type {--} the result is the same,
+but there is a clear difference in control points. As a result, combining \type
+{..} with \type {--} or \type {---} makes a big difference. Here we get a
+non||smooth connection between the curves and the straight line.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2--z3..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+As you can see in the next graphic, when we use \type {---}, we get a smooth
+connection between the straight line and the rest of the curve.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2---z3..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+So far, we have joined the four points as one path. Alternatively, we can
+constrict subpaths and connect them using the ampersand symbol, \type {&}.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2 & z2..z3..z0 & cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+So far we have created a closed path. Closing is done by \type {cycle}. The
+following path may look closed but is in fact open.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2..z3..z0" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Only a closed path can be filled. The closed alternative looks as follows. We
+will see many examples of filled closed paths later on.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2..z3..z0..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Here the final \type {..} will try to make a smooth connection, but because we
+already are at the starting point, this is not possible. However, the \type
+{cycle} command can automatically connect to the first point. Watch the
+difference between the previous and the next path.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2..z3..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+It is also possible to combine two paths into one that don't have common head and
+tails. First we define an open path:
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+The following path is a closed one, and crosses the previously shown path.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z3..z1..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+With \type {buildcycle} we can combine two paths into one.
+
+\startuseMPgraphic{path}
+ tmp := "buildcycle(z0..z1..z2 , z0..z3..z1..cycle)" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+We would refer readers to the \METAFONT\ book and the \METAPOST\ manual for an
+explanation of the intricacies of the \type {buildcycle} command. It is an
+extremely complicated command, and there is just not enough room here to do it
+justice. We suffice with saying that the paths should cross at least once before
+the \type {buildcycle} command can craft a combined path from two given paths. We
+encourage readers to experiment with this command.
+
+In order to demonstrate another technique of joining paths, we first draw a few
+strange paths. The last of these three graphics demonstrates the use of \type
+{softjoin}.
+
+\startuseMPgraphic{path}
+ tmp := "z0--z1..z2--z3" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2--z3" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Watch how \type {softjoin} removes a point in the process of smoothing a
+connection. The smoothness is accomplished by adapting the control points of the
+neighbouring points in the appropriate way.
+
+\startuseMPgraphic{path}
+ tmp := "z0--z1 softjoin z2--z3" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Once a path is known, you can cut off a slice of it. We will demonstrate a few
+alternative ways of doing so, but first we show one more time the path that we
+take as starting point.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..z2..z3..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+This path is made up out of five points, where the cycle duplicates the first
+point and connects the loose ends. The first point has number zero.
+
+We can use these points in the \type {subpath} command, which takes two
+arguments, specifying the range of points to cut of the path specified after the
+keyword \type {of}.
+
+\startuseMPgraphic{path}
+ tmp := "subpath(2,4) of (z0..z1..z2..z3..cycle)" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+The new (sub|)|path is a new path with its own points that start numbering at
+zero. The next graphic shows both the original and the subpath from point 1
+upto~3.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..z2..z3..cycle)" ;
+ sub := "subpath(1,3)" ;
+\stopuseMPgraphic
+
+\startbuffer[sub]
+\startlinecorrection[blank]
+\startMPcode
+ string tmp, sub ; defaultfont := "\truefontname{Mono}" ;
+ \includeMPgraphic{axis}
+ \includeMPgraphic{points}
+ \includeMPgraphic{path}
+ label.lft(verbatim(tmp),(14.5cm,2.5cm)) ;
+ label.lft(verbatim(sub),(14.5cm,2.0cm)) ;
+ sub := sub & " of " & tmp ;
+ path p ; p := scantokens(tmp) ;
+ path q ; q := scantokens(sub) ;
+ drawwholepath p ; swappointlabels := true ;
+ drawpath q withcolor .625yellow ;
+ drawpoints q withcolor .625red ;
+ drawpointlabels q ;
+\stopMPcode
+\stoplinecorrection
+\stopbuffer
+
+\getbuffer[sub]
+
+In spite of what you may think, a point is not fixed. This is why in \METAPOST\ a
+point along a path is officially called a time. The next example demonstrates
+that we can specify any time on the path.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..z2..z3..cycle)" ;
+ sub := "subpath(2.45,3.85)" ;
+\stopuseMPgraphic
+
+\getbuffer[sub]
+
+Often we want to take a slice starting at a specific point. This is provided by
+\type {cutafter} and its companion \type {cutbefore}. Watch out, this time we use
+a non||cyclic path.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..z2..z3)" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+When you use \type {cutafter} and \type {cutbefore} it really helps if you know
+in what direction the path runs.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..z2..z3) cutafter z2" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..z2..z3) cutbefore z1" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Here is a somewhat silly way of accomplishing the same thing, but it is a nice
+introduction to \METAPOST's \type {point} operation. In order to use this command
+effectively, you need to know how many points make up the path.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..z2..z3) cutbefore point 2 of (z0..z1..z2..z3)" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+As with \type {subpath}, you can use fractions to specify the time on the path,
+although the resulting point is not necessarily positioned linearly along the
+curve.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..z2..z3) cutbefore point 2.5 of (z0..z1..z2..z3)" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+If you really want to know the details of where fraction points are positioned,
+you should read the \METAFONT\ book and study the source of \METAFONT\ and
+\METAPOST, where you will find the complicated formulas that are used to
+calculate smooth curves.
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Like any closed path, this path has points where the tangent is horizontal or
+vertical. Early in this chapter we mentioned that a pair (or point) can specify a
+direction or vector. Although any angle is possible, we often use one of four
+predefined directions:
+
+\starttabulate[|Tl|Tl|]
+\HL
+\NC right \NC ( 1, 0) \NC \NR
+\NC up \NC ( 0, 1) \NC \NR
+\NC left \NC (-1, 0) \NC \NR
+\NC down \NC ( 0,-1) \NC \NR
+\HL
+\stoptabulate
+
+We can use these predefined directions in combination with \type {directionpoint}
+and \type {cutafter}. The following command locates the first point on the path
+that has a tangent that points vertically upward, and then feeds this point to
+the \type {cutafter} command.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..cycle) cutafter directionpoint up of (z0..z1..cycle)" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+You are not limited to predefined direction vectors. You can provide a pair to
+indicate a direction. In the next example we use the following cyclic path:
+
+\startuseMPgraphic{path}
+ tmp := "z0..z1..cycle" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+Using \type {( )} is not mandatory but makes the expression look less
+complicated.
+
+\startuseMPgraphic{path}
+ tmp := "(z0..z1..cycle) cutafter directionpoint (1,1) of (z0..z1..cycle)" ;
+\stopuseMPgraphic
+
+\getbuffer
+
+We will apply these commands in the next chapters, but first we will finish our
+introduction in \METAPOST. We have seen how a path is constructed and what can be
+done with it. Now it is time to demonstrate how such a path is turned into a
+graphic.
+
+\stopsection
+
+\startsection[title={Angles}]
+
+\index{angles}
+\index{rotation}
+
+You can go from angles to vectors and vice versa using the \type {angle} and
+\type {dir} functions. The next example show both in action.
+
+\startbuffer
+pickup pencircle scaled 2mm ;
+draw (origin -- dir(45) -- dir(0) -- cycle)
+ scaled 3cm withcolor .625red ;
+draw (origin -- dir(angle(1,1)) -- dir(angle(1,0)) -- cycle)
+ scaled 3cm shifted (3.5cm,0) withcolor .625yellow ;
+draw (origin -- (1,1) -- (1,0) -- cycle)
+ scaled 3cm shifted (7cm,0) withcolor .625white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The \type {dir} command returns an unit vector, which is why the first two shapes
+look different and are smaller than the third one. We can compensate for that by
+an additional scaling:
+
+\startbuffer
+pickup pencircle scaled 2mm ;
+draw (origin -- dir(45) -- dir(0) -- cycle)
+ scaled sqrt(2) scaled 3cm withcolor .625red ;
+draw (origin -- dir(angle(1,1)) -- dir(angle(1,0)) -- cycle)
+ scaled sqrt(2) scaled 3cm shifted (4.5cm,0) withcolor .625yellow ;
+draw (origin -- (1,1) -- (1,0) -- cycle)
+ scaled 3cm shifted (9cm,0) withcolor .625white ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Drawing pictures}]
+
+\index{drawing}
+
+Once a path is defined, either directly or as a variable, you can turn it into a
+picture. You can draw a path, like we did in the previous examples, or you can
+fill it, but only if it is closed.
+
+\startlinecorrection[blank]
+\startMPcode
+visualizepaths ;
+path p ; p := (0cm,1cm)..(2cm,2cm)..(4cm,0cm)..cycle ;
+draw p withcolor .625red ;
+fill p shifted (7cm,0) withcolor .625white ;
+\stopMPcode
+\stoplinecorrection
+
+Drawing is done by applying the \type {draw} command to a path, as in:
+
+\starttyping
+draw (0cm,1cm)..(2cm,2cm)..(4cm,0cm)..cycle ;
+\stoptyping
+
+The rightmost graphic was made with \type {fill}:
+
+\starttyping
+fill (0cm,1cm)..(2cm,2cm)..(4cm,0cm)..cycle ;
+\stoptyping
+
+If you try to duplicate this drawing, you will notice that you will get black
+lines instead of red and a black fill instead of a gray one. When drawing or
+filling a path, you can give it a color, use all kinds of pens, and achieve
+special effects like dashes or arrows.
+
+\startlinecorrection[blank]
+\startMPcode
+visualizepaths ;
+path p ; p := (0cm,1cm)..(2cm,2cm)..(4cm,0cm)..(2.5cm,1cm)..cycle ;
+drawarrow p withcolor .625red ;
+draw p shifted (7cm,0) dashed withdots withcolor .625yellow ;
+\stopMPcode
+\stoplinecorrection
+
+These two graphics were defined and drawn using the following commands. Later we
+will explain how you can set the line width (or penshape in terms of \METAPOST).
+
+\starttyping
+path p ; p := (0cm,1cm)..(2cm,2cm)..(4cm,0cm)..(2.5cm,1cm)..cycle ;
+drawarrow p withcolor .625red ;
+draw p shifted (7cm,0) dashed withdots withcolor .625yellow ;
+\stoptyping
+
+Once we have drawn one or more paths, we can store them in a picture variable.
+The straightforward way to store a picture is to copy it from the current
+picture:
+
+\starttyping
+picture pic ; pic := currentpicture ;
+\stoptyping
+
+The following command effectively clears the picture memory and allows us to
+start anew.
+
+\starttyping
+currentpicture := nullpicture ;
+\stoptyping
+
+We can shift, rotate and slant the picture stored in \type {pic} as we did with
+paths. We can say:
+
+\starttyping
+draw pic rotated 45 withcolor red ;
+\stoptyping
+
+A picture can hold multiple paths. You may compare a picture to grouping as
+provided by drawing applications.
+
+\starttyping
+draw (0cm,0cm)--(1cm,1cm) ; draw (1cm,0cm)--(0cm,1cm) ;
+picture pic ; pic := currentpicture ;
+draw pic shifted (3cm,0cm) ; draw pic shifted (6cm,0cm) ;
+pic := currentpicture ; draw pic shifted (0cm,2cm) ;
+\stoptyping
+
+We first draw two paths and store the resulting \quote {cross} in a picture
+variable. Then we draw this picture two times, so that we now have three copies
+of the cross. We store the accumulated drawing again, so that after duplication,
+we finally get six crosses.
+
+\startlinecorrection[blank]
+\startMPcode
+path p ; p := (0cm,0cm)--(1cm,1cm) ;
+path q ; q := (1cm,0cm)--(0cm,1cm) ;
+for i=p,q :
+ drawpath i ; drawcontrollines i ; drawpoints i ; drawcontrolpoints i ;
+endfor ;
+picture pic ; pic := currentpicture ;
+draw pic shifted (3cm,0cm) ;
+draw pic shifted (6cm,0cm) ;
+pic := currentpicture ;
+draw pic shifted (0cm,2cm) ;
+\stopMPcode
+\stoplinecorrection
+
+You can often follow several routes to reach the same solution. Consider for
+instance the following graphic.
+
+\startbuffer[points]
+w := 4cm ; h := 2cm ; ww := 1cm ; hh := 1.5cm ;
+\stopbuffer
+
+\startbuffer[common]
+drawoptions(withcolor .625white) ;
+\stopbuffer
+
+\startbuffer[background]
+fill (unitsquare xscaled w yscaled h) enlarged 2mm withcolor .625yellow ;
+\stopbuffer
+
+\startbuffer[shape]
+fill (0,0)--(ww,0)--(ww,hh)--(w,hh)--(w,h)--(0,h)--cycle ;
+fill (ww,0)--(w,0)--(w,hh)--cycle ;
+\stopbuffer
+
+\typebuffer[shape]
+
+\startlinecorrection[blank]
+\processMPbuffer[common,points,shape]
+\stoplinecorrection
+
+The points that are used to construct the paths are defined using the constants
+\type {w}, \type {h}, \type {ww} and \type {hh}. These are defined as follows:
+
+\typebuffer[points]
+
+In this case we draw two shapes that leave part of the rectangle uncovered. If
+you have a background, this technique allows the background to \quote {show
+through} the graphic.
+
+\startlinecorrection[blank]
+\processMPbuffer[common,points,background,shape]
+\stoplinecorrection
+
+A not uncommon practice when making complicated graphics is to use unfill
+operations. Since \METAPOST\ provides one, let us see what happens if we apply
+this command.
+
+\startbuffer[shape]
+fill (0,0)--(w,0)--(w,h)--(0,h)--cycle ;
+unfill (ww,0)--(w,hh)--(ww,hh)--cycle ;
+\stopbuffer
+
+\typebuffer[shape]
+
+\startlinecorrection[blank]
+\processMPbuffer[common,points,background,shape]
+\stoplinecorrection
+
+This does not always give the desired effect, because \METAPOST's \type {unfill}
+is not really an unfill, but a \type {fill} with color \type {background}. Since
+this color is white by default, we get what we just showed. So, if we set \type
+{background} to \type {black}, using \typ {background := black}, we get:
+
+\startbuffer[back]
+background := black ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[back,common,points,background,shape]
+\stoplinecorrection
+
+Of course, you can set the variable \type {background} to a different color, but
+this does not hide the fact that \METAPOST\ lacks a real unfill operation.
+
+\startbuffer[shape]
+fill (0,0)--(0,h)--(w,h)--(w,0)--(ww,0)--(w,hh)--(ww,hh)--
+ (ww,0)--cycle ;
+\stopbuffer
+
+\startbuffer[path]
+autoarrows := true ;
+path p ; p := (0,0)--(0,h)--(w,h)--(w,0)--(ww,0)--(w,hh)--(ww,hh)--
+ (ww,0)--cycle ;
+draw p withpen pencircle scaled 1mm withcolor .625red;
+numeric l ; l := length(p)-1 ;
+for i=0 upto l :
+ drawarrow subpath(i,i+1) of p
+ withpen pencircle scaled 1mm
+ withcolor (.5+.5(i/l))*red ;
+endfor ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[common,points,background,shape]
+\stoplinecorrection
+
+Since we don't consider this \type {unfill} a suitable operator, you may wonder
+how we achieved the above result.
+
+\typebuffer[shape]
+
+\startlinecorrection[blank]
+\processMPbuffer[common,points,background,shape,path]
+\stoplinecorrection
+
+This feature depends on the \POSTSCRIPT\ way of filling closed paths, which comes
+down to filling either the left or the right hand side of a curve. The following
+alternative works too.
+
+\startbuffer[shape]
+fill (0,0)--(0,h)--(w,h)--(w,hh)--(ww,hh)--(ww,0)--(w,hh)--
+ (w,0)--cycle ;
+\stopbuffer
+
+\typebuffer[shape]
+
+\startlinecorrection[blank]
+\processMPbuffer[common,points,background,shape]
+\stoplinecorrection
+
+The next alternative will fail. This has to do with the change in direction at
+point \type {(0,0)} halfway through the path. Sometimes changing direction can
+give curious but desirable effects, but here it brings no good.
+
+\startbuffer[shape]
+fill (0,0)--(0,h)--(w,h)--(w,0)--(0,0)--(ww,0)--(ww,hh)--
+ (w,hh)--(ww,0)--cycle ;
+\stopbuffer
+
+\typebuffer[shape]
+
+This path fails because of the way \POSTSCRIPT\ implements its fill operator.
+More details on how \POSTSCRIPT\ defines fills can be found in the reference
+manuals.
+
+\startlinecorrection[blank]
+\processMPbuffer[common,points,background,shape]
+\stoplinecorrection
+
+Some of the operations we have seen are hard coded into \METAPOST\ and are called
+primitives. Others are defined as macros, that is, a sequence of \METAPOST\
+commands. Since they are used often, you may expect \type {draw} and \type {fill}
+to be primitives, but they are not. They are macros defined in terms of
+primitives.
+
+Given a path \type {pat}, you can consider a \type {draw} to be defined in terms
+of:
+
+\starttyping
+addto currentpicture doublepath pat
+\stoptyping
+
+The \type {fill} command on the other hand is defined as:
+
+\starttyping
+addto currentpicture contour pat
+\stoptyping
+
+Both macros are actually a bit more complicated but this is mainly due to the
+fact that they also have to deal with attributes like the pen and color they draw
+with.
+
+You can use \type {doublepath} and \type {contour} directly, but we will use
+\type {draw} and \type {fill} whenever possible.
+
+Given a picture \type {pic}, the following code is valid:
+
+\starttyping
+addto currentpicture also pic
+\stoptyping
+
+You can add pictures to existing picture variables, where \type {currentpicture}
+is the picture that is flushed to the output file. Watch the subtle difference
+between adding a \type {doublepath}, \type {contour} or \type {picture}.
+
+\stopsection
+
+\startsection[title={Variables}]
+
+\index{variables}
+
+At this point you may have noted that \METAPOST\ is a programming language.
+Contrary to some of today's languages, \METAPOST\ is a simple and clean language.
+Actually, it is a macro language. Although \METAPOST\ and \TEX\ are a couple, the
+languages differ in many aspects. If you are using both, you will sometimes wish
+that features present in one would be available in the other. When using both
+languages, in the end you will understand why the conceptual differences make
+sense.
+
+Being written in \PASCAL, it will be no surprise that \METAPOST\ has some
+\PASCAL||like features, although some may also recognize features from \ALGOL68\
+in it.
+
+First there is the concept of variables and assignments. There are several data
+types, some of which we already have seen.
+
+\starttabulate
+\HL
+\NC numeric \NC real number in the range $-4096 \ldots +4096$ \NC \NR
+\NC boolean \NC a variable that takes one of two states: true or false \NC \NR
+\NC pair \NC point or vector in 2||dimensional space \NC \NR
+\NC path \NC a piecewise collection of curves and line segments \NC \NR
+\NC picture \NC collection of stroked or filled paths \NC \NR
+\NC string \NC sequence of characters, like \type {"metapost"} \NC \NR
+\NC color \NC vector of three (rgb) or four (cmyk) numbers \NC \NR
+\HL
+\stoptabulate
+
+There are two additional types, \type {transform} and \type {pen}, but we will
+not discuss these in depth.
+
+\starttabulate
+\HL
+\NC transform \NC transformation vector with six elements \NC \NR
+\NC pen \NC pen specification \NC \NR
+\HL
+\stoptabulate
+
+You can achieve interesting effects by using pens with certain shapes. For the
+moment you may consider a pen to be a path itself that is applied to the path
+that is drawn.
+
+The \type {numeric} data type is used so often that it is the default type of any
+non declared variable. This means that
+
+\starttyping
+n := 10 ;
+\stoptyping
+
+is the same as
+
+\starttyping
+numeric n ; n := 10 ;
+\stoptyping
+
+When writing collections of macros, it makes sense to use the second method,
+because you can never be sure if \type {n} isn't already declared as a picture
+variable, and assigning a numeric to a picture variable is not permitted.
+
+Because we often deal with collections of objects, such as a series of points,
+all variables can be organized in arrays. For instance:
+
+\starttyping
+numeric n[] ; n[3] := 10 ; n[5] := 13 ;
+\stoptyping
+
+An array is a collection of variables of the same type that are assigned and
+accessed by indexing the variable name, as in \type {n[3] := 5}.
+Multi||dimensional arrays are also supported. Since you need a bit of imagination
+to find an application for 5||dimensional arrays, we restrict ourselves to a
+two||dimensional example.
+
+\starttyping
+numeric n[][] ; n[2][3] := 10 ;
+\stoptyping
+
+A nice feature is that the bounds of such an array needs not to be set
+beforehand. This also means that each cell that you access is reported as {\em
+unknown} unless you have assigned it a value.
+
+Behind the screens there are not really arrays. It's just a matter of creating
+hash entries. It might not be obvious, but the following assignments are all
+equivalent:
+
+\startbuffer
+i_111_222 := 1cm ;
+i_[111]_[222] := 1cm ;
+i_[111][222] := 1cm ;
+draw
+ image (
+ draw (0cm,i_111_222) ;
+ draw (1cm,i_[111]_[222]) ;
+ draw (2cm,i_[111][222]) ;
+ )
+ withpen pencircle scaled 5mm
+ withcolor .625 red ;
+\stopbuffer
+
+\typebuffer
+
+Sometimes \METAPOST\ ways are mysterious:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Conditions}]
+
+\index{conditions}
+
+The existence of boolean variables indicates the presence of conditionals.
+Indeed, the general form of \METAPOST's conditional follows:
+
+\starttyping
+if n=10 : draw p ; else : draw q ; fi ;
+\stoptyping
+
+Watch the colons after the if and else clause. They may not be omitted. The
+semi||colons on the other hand, are optional and depend on the context. You may
+say things like:
+
+\starttyping
+draw if n=10 : p ; else : q ; fi ;
+\stoptyping
+
+Here we can omit a few semi||colons:
+
+\starttyping
+draw if n=10 : p else : q fi withcolor red ;
+\stoptyping
+
+Adding semi||colons after \type {p} and \type {q} will definitely result in an
+error message, since the semi||colon ends the draw operation and \typ {withcolor
+red} becomes an isolated piece of nonsense.
+
+There is no case statement available, but for most purposes, the following
+extension is adequate:
+
+\starttyping
+draw p withcolor if n<10 : red elseif n=10 : green else : blue fi ;
+\stoptyping
+
+There is a wide repertoire of boolean tests available.
+
+\starttyping
+if picture p :
+if known n :
+if odd i :
+if cycle q :
+\stoptyping
+
+Of course, you can use \type {and}, \type {or}, \type {not}, and \type {( )} to
+construct very advanced boolean expressions. If you have a bit of programming
+experience, you will appreciate the extensive support of conditionals in
+\METAPOST.
+
+\stopsection
+
+\startsection[title={Loops}]
+
+\index{loops}
+
+Yet another programming concept present in \METAPOST\ is the loop statement, the
+familiar \quote {for loop} of all programming languages.
+
+\starttyping
+for i=0 step 2 until 20 :
+ draw (0,i) ;
+endfor ;
+\stoptyping
+
+As explained convincingly in Niklaus Wirth's book on algorithms and
+datastructures, the for loop is the natural companion to an array. Given an array
+of length $n$, you can construct a path out of the points that make up the array.
+
+\starttyping
+draw for i=0 step 1 until n-1 : p[i] .. endfor p[n] ;
+\stoptyping
+
+If the step increment is not explicitly stated, it has an assumed value of 1. We
+can shorten the previous loop construct as follows:
+
+\starttyping
+draw for i=0 upto n-1 : p[i] .. endfor p[n] ;
+\stoptyping
+
+After seeing \type {if} in action, the following \type {for} loop will be no
+surprise:
+
+\startbuffer
+draw origin for i=0 step 10 until 100 : ..{down}(i,0) endfor ;
+\stopbuffer
+
+\typebuffer
+
+This gives the zig||zag curve:
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+You can use a loop to iterate over a list of objects. A simple 3||step iteration
+is:
+
+\starttyping
+for i=p,q,r :
+ fill i withcolor .8white ;
+ draw i withcolor red ;
+endfor ;
+\stoptyping
+Using \type {for} in this manner can sometimes save a bit of typing. The list can
+contain any expression, and may be of different types.
+
+In the previous example the \type {i} is an independent variable, local to the
+for loop. If you want to change the loop variable itself, you need to use \type
+{forsuffixes}. In the next loop the paths \type {p}, \type {q} and~\type {r} are
+all shifted.
+
+\starttyping
+forsuffixes i = p, q, r :
+ i := i shifted (3cm,2cm) ;
+endfor ;
+\stoptyping
+
+Sometimes you may want to loop forever until a specific condition occurs. For
+this, \METAPOST\ provides a special looping mechanism:
+
+\startbuffer[demo]
+numeric done[][], i, j, n ; n := 0 ;
+forever :
+ i := round(uniformdeviate(10)) ; j := round(uniformdeviate(2)) ;
+ if unknown done[i][j] :
+ drawdot (i*cm,j*cm) ; n := n + 1 ; done[i][j] := n ;
+ fi ;
+ exitif n = 10 ;
+endfor ;
+\stopbuffer
+
+\typebuffer[demo]
+
+Here we remain in the loop until we have 10 points placed. We use an array to
+keep track of placed points. The \METAPOST\ macro \type {uniformdeviate(n)}
+returns a random number between 0 and~n and the \type {round} command is used to
+move the result toward the nearest integer. The \type {unknown} primitive allows
+us to test if the array element already exists, otherwise we exit the
+conditional. This saves a bit of computational time as each point is drawn and
+indexed only once.
+
+\startbuffer[pen]
+pickup pencircle scaled 2mm ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[pen,demo]
+\stoplinecorrection
+
+The loop terminator \type {exitif} and its companion \type {exitunless} can be
+used in \type {for}, \type {forsuffixes} and \type {forever}.
+
+\stopsection
+
+\startsection[title={Macros}]
+
+\index{macros}
+\index{definitions}
+
+In the previous section we introduced \type {upto}. Actually this is not part of
+the built in syntax, but a sort of shortcut, defined by:
+
+\starttyping
+def upto = step 1 until enddef ;
+\stoptyping
+
+You just saw a macro definition where \type {upto} is the name of the macro. The
+counterpart of \type {upto} is \type {downto}. Whenever you use \type {upto}, it
+is replaced by \typ {step 1 until}. This replacement is called expansion.
+
+There are several types of macros. A primary macro is used to define your own
+operators. For example:
+
+\starttyping
+primarydef p doublescaled s =
+ p xscaled (s/2) yscaled (s*2)
+enddef ;
+\stoptyping
+
+Once defined, the \type {doublescaled} macro is implemented as in the following
+example:
+
+\starttyping
+draw somepath doublescaled 2cm withcolor red ;
+\stoptyping
+
+When this command is executed, the macro is expanded. Thus, the actual content of
+this command becomes:
+
+\starttyping
+draw somepath xscaled 1cm yscaled 4cm withcolor red ;
+\stoptyping
+
+If in the definition of \type {doublescaled} we had added a semi||colon after
+\type {(s*2)}, we could not have set the color, because the semicolon ends the
+statement. The \type {draw} expects a path, so the macro can best return one.
+
+A macro can take one or more arguments, as in:
+
+\starttyping
+def drawrandomscaledpath (expr p, s) =
+ draw p xscaled (s/2) yscaled (s*2) ;
+enddef ;
+\stoptyping
+
+When using this macro, it is expected that you will pass it two parameters, the
+first being a path, the second a numeric scale factor.
+
+\starttyping
+drawrandomscaledpath(fullsquare, 3cm) ;
+\stoptyping
+
+Sometimes we want to return a value from a macro. In that case we must make sure
+that any calculations don't interfere with the expectations. Consider:
+
+\starttyping
+vardef randomscaledpath(expr p, s) =
+ numeric r ; r := round(1 + uniformdeviate(4)) ;
+ p xscaled (s/r) yscaled (s*r)
+enddef ;
+\stoptyping
+
+Because we want to use the same value of \type {r} twice, we have to use an
+intermediate variable. By using a \type {vardef} we hide everything but the last
+statement. It is important to distinguish \type {def} macros from those defined
+with \type {vardef}. In the latter case, \type {vardef} macros are not a simple
+expansion and replacement. Rather, \type {vardef} macros return the value of
+their last statement. In the case of the \type {randomscaledpath} macro, a path
+is returned. This macro is used in the following manner:
+
+\starttyping
+path mypath ; mypath := randomscaledpath(unitsquare,4cm) ;
+\stoptyping
+
+Note that we send \type {randomscaledpath} a path (\type {unitsquare}) and a
+scaling factor (\type {4cm}). The macro returns a scaled path which is then
+stored in the path variable \type {mypath}.
+
+The following argument types are accepted:
+
+\starttabulate
+\HL
+\NC expr \NC something that can be assigned to a variable \NC \NR
+\NC text \NC arbitrary \METAPOST\ code ending with a \type {;} \NC \NR
+\NC suffix \NC a variable bound to another variable \NC \NR
+\HL
+\stoptabulate
+An expression is passed by value. This means that in the body of the macro, a
+copy is used and the original is left untouched. On the other hand, any change to
+a variable passed as suffix is also applied to the original.
+
+Local variables must be handled in a special manner, since they may conflict with
+variables used elsewhere. This is because all variables are global by default.
+The way out of this problem is using grouping in combination with saving
+variables. The use of grouping is not restricted to macros and may be used
+anywhere in your code. Variables saved and declared in a group are local to that
+group. Once the group is exited the variables cease to exist.
+
+\starttyping
+vardef randomscaledpath(expr p, s) =
+ begingroup ; save r ; numeric r ;
+ r := round(1 + uniformdeviate(4)) ;
+ p xscaled (s/r) yscaled (s*r)
+ endgroup
+enddef ;
+\stoptyping
+
+In this particular case, we could have omitted the grouping, since \type {vardef}
+macros are always grouped automatically. Therefore, we could have defined the
+macro as:
+
+\starttyping
+vardef randomscaledpath(expr p, s) =
+ save r ; numeric r ; r := round(1 + uniformdeviate(4)) ;
+ p xscaled (s/r) yscaled (s*r)
+enddef ;
+\stoptyping
+
+The command \type {save r} declares that the variable \type {r} is local to the
+macro. Thus, any changes to the (new) numeric variable \type {r} are local and
+will not interfere with a variable \type {r} defined outside the macro. This is
+important to understand, as variables outside the macro are global and accessible
+to the code within the body of the macro.
+
+Macro definitions may be nested, but since most \METAPOST\ code is relatively
+simple, it is seldom needed. Nesting is discouraged as it makes your code less
+readable.
+
+Besides \type {def} and \type {vardef}, \METAPOST\ also provides the classifiers
+\type {primarydef}, \type {secondarydef} and \type {tertiarydef}. You can use
+these classifiers to define macros like those provided by \METAPOST\ itself:
+
+\starttyping
+primarydef x mod y = ... enddef ;
+secondarydef p intersectionpoint q = ... enddef ;
+tertiarydef p softjoin q = ... enddef ;
+\stoptyping
+A primary macro acts like the binary operators \type {*} or \type {scaled} and
+\type {shifted}. Secondary macros are like \type {+}, \type {-} and logical \type
+{or}, and take less precedence. The tertiary operators like \type {<} or the path
+and string concatenation operator \type {&} have tertiary macros as companions.
+More details can be found in the \METAFONT\ book. When it comes to taking
+precedence, \METAPOST\ tries to be as natural as possible, in the sense that you
+need to provide as few \type {( )}'s as possible. When in doubt, or when
+surprised by unexpected results, use parentheses.
+
+\stopsection
+
+\startsection[title={Arguments}]
+
+\index{arguments}
+\index{macros+arguments}
+
+The \METAPOST\ macro language is rather flexible in how you feed arguments to
+macros. If you have only one argument, the following definitions and calls are
+valid.
+
+\starttyping
+def test expr a = enddef ; test (a) ; test a ;
+def test (expr a) = enddef ; test (a) ; test a ;
+\stoptyping
+
+A more complex definition is the following. As you can see, you can call the
+\type {test} macro in your favorite way.
+
+\starttyping
+def test (expr a,b) (expr c,d) = enddef ;
+
+test (a) (b) (c) (d) ;
+test (a,b) (c,d) ;
+test (a,b,c) (d) ;
+test (a,b,c,d) ;
+\stoptyping
+
+The type of the arguments is one of \type {expr}, \type {primary} or \type
+{suffix}. When fetching arguments, \METAPOST\ uses the type to determine how and
+what to grab. A fourth type is \type {text}. When no parenthesis are used, a
+\type {text} argument grabs everything upto the next semicolon.
+
+\starttyping
+def test (expr a) text b = enddef ;
+
+test (a) ; test (a) b ;
+\stoptyping
+
+You can use a \type {text} to grab arguments like \typ {withpen pencircle scaled
+10 withcolor red}. Because \type {text} is so hungry, you may occasionally need a
+two stage definition:
+
+\starttyping
+def test expr a = dotext(a) enddef ;
+def dotest (expr a) text b = ... enddef ;
+
+test a ; test a b ;
+\stoptyping
+
+This definition permits arguments without parenthesis, which is something you
+want with commands like \type {draw}.
+
+The \type {vardef} alternative behaves in a similar way. It always provides
+grouping. You need to generate a return value and as a result may not end with a
+semicolon.
+
+You may consider the whole \type {vardef} to be encapsulated into parenthesis and
+thereby to be a (self contained) variable. Adding additional parenthesis often
+does more harm than good:
+
+\starttyping
+vardef test (expr a) =
+ ( do tricky things with a ; manipulated_a )
+enddef ;
+\stoptyping
+
+Here the tricky things become part of the return value, which quite certainly is
+something that you don't want.
+
+The three operator look||alike macro definitions are less flexible and have the
+definition scheme:
+
+\starttyping
+primarydef x test y = enddef ;
+secondarydef x test y = enddef ;
+tertiarydef x test y = enddef ;
+\stoptyping
+
+When defining macros using this threesome you need to be aware of the associated
+priorities. When using these definitions, you also have to provide your own
+grouping.
+
+In the plain \METAPOST\ macro collection (\type {plain.mp}) you can find many
+examples of clever definitions. The following (simplified) version of \type {min}
+demonstrates how we use the argument handler to isolate the first argument from
+the provided list, simply by using two arguments.
+
+\starttyping
+vardef min (expr u) (text t) =
+ save min_u ; min_u := u ;
+ for uu = t : if uu<u : min_u := uu ; fi endfor
+ min_u
+enddef ;
+\stoptyping
+
+The special sequence \type {@#} is used to pick up a so called delimited argument:
+
+\starttyping
+vardef TryMe@#(expr x) =
+ % we can now use @#, which is just text
+enddef ;
+\stoptyping
+
+This feature is used in the definition of \type {z} as used in \type {z1} or
+\type {z234}:
+
+\starttyping
+vardef z@# = (x@#,y@#) enddef ;
+\stoptyping
+
+Other applications can be found in the label drawing macros where the anchor
+point is assigned to the obscure variable \type {@#}.
+
+\stopsection
+
+\startsection[title={Pens}]
+
+\index{pens}
+
+When drawing, three attributes can be applied to it: a dashpattern, a pen
+and|/|or a color. You may consider an arrowhead an attribute, but actually it is
+just an additional drawing, appended to the path.
+
+The (predefined) \type {pencircle} attribute looks like:
+
+\starttyping
+withpen pencircle
+\stoptyping
+
+where \type {pencircle} is a special kind of path, stored in a pen variable. Like
+any path, you can transform it. You can scale it equally in all directions:
+
+\starttyping
+withpen pencircle scaled 1mm
+\stoptyping
+
+You can also provide unequal scales, creating an elliptically shaped and rotated
+pen.
+
+\starttyping
+withpen pencircle xscaled 2mm yscaled 4mm rotated 30
+\stoptyping
+
+In the following graphic, the circle in the center is drawn without any option,
+which means that the default pen is used, being a pencircle with a radius of half
+a base point. The other three circles are drawn with different pen
+specifications.
+
+\startlinecorrection[blank]
+\startMPcode
+path p ; p := fullcircle scaled 1cm ;
+drawoptions (withcolor .625yellow) ;
+draw p ;
+drawoptions (withcolor .625red) ;
+draw p scaled 2 withpen pencircle ;
+drawoptions (withcolor .625yellow) ;
+draw p scaled 3 withpen pencircle scaled 1mm ;
+drawoptions (withcolor .625red) ;
+draw p scaled 4 withpen pencircle xscaled 2mm yscaled 4mm rotated 30 ;
+\stopMPcode
+\stoplinecorrection
+
+If you forget about the colors, the \METAPOST\ code to achieve this is as
+follows.
+
+\starttyping
+path p ; p := fullcircle scaled 1cm ;
+draw p ;
+draw p scaled 2 withpen pencircle ;
+draw p scaled 3 withpen pencircle scaled 1mm ;
+draw p scaled 4 withpen pencircle xscaled 2mm yscaled 4mm rotated 30 ;
+\stoptyping
+
+If this were the only way of specifying a pen, we would be faced with a
+considerable amount of typing, particularly in situations where we use pens
+similar to the fourth specification above. For that reason, \METAPOST\ supports
+the concept of a current pen. The best way to set this pen is to use the \type
+{pickup} macro.
+
+\starttyping
+pickup pencircle xscaled 2mm yscaled 4mm rotated 30 ;
+\stoptyping
+
+This macro also stores some characteristics of the pen in variables, so that they
+can be used in (the more complicated) calculations that are involved in
+situations like drawing font||like graphics.
+
+If we substitute \type {pencircle} by \type {pensquare}, we get a different kind
+of shapes. In the non rotated pens, the top, bottom, left and right parts of the
+curve are thinner.
+
+\startlinecorrection[blank]
+\startMPcode
+path p ; p := fullcircle scaled 1cm ;
+drawoptions (withcolor .625yellow) ;
+draw p ;
+drawoptions (withcolor .625red) ;
+draw p scaled 2 withpen pensquare ;
+drawoptions (withcolor .625yellow) ;
+draw p scaled 3 withpen pensquare scaled 1mm ;
+drawoptions (withcolor .625red) ;
+draw p scaled 4 withpen pensquare xscaled 2mm yscaled 4mm rotated 30 ;
+\stopMPcode
+\stoplinecorrection
+
+You should look at pens in the way an artist does. He follows a shape and in
+doing so he or she twists the pen (and thereby the nib) and puts more or less
+pressure on it.
+
+The chance that you have an appropriate pen laying at your desk is not so big,
+but you can simulate the following \METAPOST's pen by taking two pencils and
+holding them together in one hand. If you position them in a 45 degrees angle,
+and draw a circle, you will get something like:
+
+\startlinecorrection[blank]
+\startMPcode
+path p ; p := fullcircle xscaled 2cm yscaled 3cm ;
+drawoptions(withcolor .625red withpen pencircle scaled .5mm);
+draw p ; draw p shifted (.3cm,.3cm) ;
+\stopMPcode
+\stoplinecorrection
+
+If you take a calligraphic pen with a thin edge of .5cm, you will get:
+
+\startlinecorrection[blank]
+\startMPcode
+drawoptions(withcolor .625red);
+path p ; p := fullcircle xscaled 2cm yscaled 3cm ;
+draw p withpen makepen ((0,0)--(.3cm,.3cm)) withcolor .625white ;
+drawoptions(withcolor .625red withpen pencircle scaled .25mm);
+draw p ; draw p shifted (.3cm,.3cm) ;
+\stopMPcode
+\stoplinecorrection
+
+You can define such a pen yourself:
+
+\starttyping
+path p ; p := fullcircle xscaled 2cm yscaled 3cm ;
+pen doublepen ; doublepen := makepen ((0,0)--(.3cm,.3cm)) ;
+pickup doublepen ; draw p ;
+\stoptyping
+
+Here we define a new pen using the \type {pen} command. Then we define a path,
+and make a pen out of it using the \type {makepen} macro. The path should be a
+relatively simple one, otherwise \METAPOST\ will complain.
+
+You can use \type {makepen} with the previously introduced \type {withpen}:
+
+\starttyping
+draw p withpen makepen ((0,0)--(.3cm,.3cm)) ;
+\stoptyping
+
+and \type {pickup}:
+
+\starttyping
+pickup makepen ((0,0)--(.3cm,.3cm)) ; draw p ;
+\stoptyping
+
+You can use \type {makepen} and \type {makepath} to convert paths into pens and
+vice versa.
+
+Pens are very important when defining fonts, and \METAFONT\ is meant to be a font
+creation tool. Since \METAPOST\ has a slightly different audience, it lacks some
+features in this area, but offers a few others instead. Nevertheless, one can try
+to design a font using \METAPOST. Of course, pens are among the designers best
+kept secrets. But even then, not every~O is a nice looking one.
+
+\startlinecorrection[blank]
+\startMPcode
+path p ; p := fullcircle xscaled 2cm yscaled 3cm ;
+draw p withpen makepen (unitsquare scaled .4cm superellipsed .85)
+withcolor .625white ;
+\stopMPcode
+\stoplinecorrection
+
+\startbuffer[s00]
+ path p ; p := (-1,0) {down} .. {up} (1,0) ;
+ draw pensilled(p, pensquare scaled (1/3))
+ scaled 2cm ;
+ draw boundingbox image(draw p)
+ scaled 2cm ;
+\stopbuffer
+
+\startbuffer[s30]
+ path p ; p := (-1,0) {down} .. {up} (1,0) ;
+ draw pensilled(p, pensquare scaled (1/3) rotated 30)
+ scaled 2cm ;
+ draw boundingbox image(draw p)
+ scaled 2cm ;
+\stopbuffer
+
+\startbuffer[s45]
+ path p ; p := (-1,0) {down} .. {up} (1,0) ;
+ draw pensilled(p, pensquare scaled (1/3) rotated 45)
+ scaled 2cm ;
+ draw boundingbox image(draw p)
+ scaled 2cm ;
+\stopbuffer
+
+\startbuffer[c00]
+ path p ; p := (-1,0) {down} .. {up} (1,0) ;
+ draw pensilled(p, pencircle scaled (1/3))
+ scaled 2cm ;
+ draw boundingbox image(draw p)
+ scaled 2cm ;
+\stopbuffer
+
+\startbuffer[c30]
+ path p ; p := (-1,0) {down} .. {up} (1,0) ;
+ draw pensilled(p, pencircle scaled (1/3) rotated 30)
+ scaled 2cm ;
+ draw boundingbox image(draw p)
+ scaled 2cm ;
+\stopbuffer
+
+\startbuffer[c45]
+ path p ; p := (-1,0) {down} .. {up} (1,0) ;
+ draw pensilled(p, pencircle scaled (1/3) rotated 45)
+ scaled 2cm ;
+ draw boundingbox image(draw p)
+ scaled 2cm ;
+\stopbuffer
+
+\startbuffer[f30]
+ interim pensilstep := 1/6 ;
+ draw pensilled(fullcircle, pencircle xscaled (1/10) yscaled (2/10) rotated 30)
+ scaled 5cm ;
+ draw boundingbox fullcircle
+ scaled 5cm ;
+\stopbuffer
+
+The \type {pensilled} macro is a variant on a macro used for testing some border
+cases in the engine. It provides a nice way to see what actually happens when a
+pen is applied. \in {Figure} [fig:pensilled] demonstrates this macro. The first
+row shows a square pen:
+
+\typebuffer[s30]
+
+and the second row a circular pen:
+
+\typebuffer[c30]
+
+\startplacefigure[title={How pens are applied.},reference=fig:pensilled]
+ \startcombination[3*2]
+ {\processMPbuffer[s00]} {\tttf pensquare rotated 0}
+ {\processMPbuffer[s30]} {\tttf pensquare rotated 30}
+ {\processMPbuffer[s45]} {\tttf pensquare rotated 45}
+ {\processMPbuffer[c00]} {\tttf pencircle rotated 0}
+ {\processMPbuffer[c30]} {\tttf pencircle rotated 30}
+ {\processMPbuffer[c45]} {\tttf pencircle rotated 45}
+ \stopcombination
+\stopplacefigure
+
+The effects of rotation and non|-|proportional scaling are demonstrated
+in \in {figure} [fig:pensilled:fullcircle].
+
+\typebuffer[f30]
+
+\startplacefigure[title={A proportionally scaled and rotated pen.},reference=fig:pensilled:fullcircle]
+ \processMPbuffer[f30]
+\stopplacefigure
+
+\stopsection
+
+\startsection[title={Joining lines}]
+
+\index{joining}
+\index{paths+joining}
+
+The way lines are joined or end is closely related to the way \POSTSCRIPT\
+handles this. By setting the variables \type {linejoin} and \type {linecap}, you
+can influence the drawing process. \in {Figure} [fig:joints] demonstrates the
+alternatives. The gray curves are drawn with both variables set to \type
+{rounded}.
+
+\startnotmode[screen]
+
+\def\showMPline#1#2%
+ {\startMPcode
+ path p ; p := ((0,0)--(.5,1)--(1,0)) xscaled 3cm yscaled 1.5cm ;
+ pickup pencircle scaled 1cm ;
+ draw p withcolor .625white ;
+ interim linejoin := #1 ;
+ interim linecap := #2 ;
+ draw p withcolor transparent(1,.5,.625yellow) ;
+ \stopMPcode}
+
+\stopnotmode
+
+\startmode[screen]
+
+\def\showMPline#1#2%
+ {\startMPcode
+ path p ; p := ((0,0)--(.5,1)--(1,0)) xscaled 2.5cm yscaled 1.25cm ;
+ pickup pencircle scaled .75cm ;
+ draw p withcolor .625white ;
+ interim linejoin := #1 ;
+ interim linecap := #2 ;
+ draw p withcolor transparent(1,.5,.625yellow) ;
+ \stopMPcode}
+
+\stopmode
+
+\def\showMPtext#1#2%
+ {linejoin=#1\par linecap=#2}
+
+\startbuffer
+\startcombination[3*3]
+ {\showMPline{mitered}{butt}} {\showMPtext{mitered}{butt}}
+ {\showMPline{mitered}{rounded}} {\showMPtext{mitered}{rounded}}
+ {\showMPline{mitered}{squared}} {\showMPtext{mitered}{squared}}
+ {\showMPline{rounded}{butt}} {\showMPtext{rounded}{butt}}
+ {\showMPline{rounded}{rounded}} {\showMPtext{rounded}{rounded}}
+ {\showMPline{rounded}{squared}} {\showMPtext{rounded}{squared}}
+ {\showMPline{beveled}{butt}} {\showMPtext{beveled}{butt}}
+ {\showMPline{beveled}{rounded}} {\showMPtext{beveled}{rounded}}
+ {\showMPline{beveled}{squared}} {\showMPtext{beveled}{squared}}
+\stopcombination
+\stopbuffer
+
+\placefigure
+ [here] [fig:joints]
+ {The nine ways to end and join lines.}
+ {\getbuffer}
+
+By setting the variable \type {miterlimit}, you can influence the mitering of
+joints. The next example demonstrates that the value of this variable acts as a
+trigger.
+
+\startbuffer
+interim linejoin := mitered ;
+for i :=1 step 1 until 5 :
+ interim miterlimit := i*pt ;
+ draw ((0,0)--(.5,1)--(1,0)) shifted (1.5i,0) scaled 50pt
+ withpen pencircle scaled 10pt withcolor .625red ;
+endfor ;
+\stopbuffer
+
+\typebuffer
+
+The variables \type {linejoin}, \type {linecap} and \type {miterlimit} are so
+called {\em internal} variables. When we prefix their assignments by \type
+{interim}, the setting will be local within groups, like \typ {beginfig ...
+endfig}.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Colors}]
+
+\index{attributes}
+\index{color}
+So far, we have seen some colors in graphics. It must be said that \METAPOST\
+color model is not that advanced, although playing with colors in the \METAPOST\
+way can be fun. In later chapters we will discuss some extensions that provide
+shading.
+
+Colors are defined as vectors with three components: a red, green and blue one.
+Like pens, colors have their \type {with}||command:
+
+\starttyping
+withcolor (.4,.5.,6)
+\stoptyping
+
+You can define color variables, like:
+
+\starttyping
+color darkred ; darkred := (.625,0.0) ;
+\stoptyping
+
+You can now use this color as:
+
+\starttyping
+withcolor darkred
+\stoptyping
+
+Given that \type {red} is already defined, we also could have said:
+
+\starttyping
+withcolor .625red
+\stoptyping
+
+Because for \METAPOST\ colors are just vectors, you can do things similar to
+points. A color halfway red and green is therefore accomplished with:
+
+\starttyping
+withcolor .5[red,green]
+\stoptyping
+
+Since only the \RGB\ color space is supported, this is about all we can tell
+about colors for this moment. Later we will discuss some nasty details.
+
+\stopsection
+
+\startsection[title={Dashes}]
+
+\index{dashes}
+
+A dash pattern is a simple picture that is build out of straight lines. Any
+slightly more complicated picture will be reduced to straight lines and a real
+complicated one is rejected, and in this respect \METAPOST\ considers a circle to
+be a complicated path.
+
+The next example demonstrates how to get a dashed line. First we built picture
+\type {p}, that we apply to a path. Here we use a straight path, but dashing can
+be applied to any path.
+
+\startbuffer
+picture p ; p := nullpicture ;
+addto p doublepath ((0,0)--(3mm,3mm)) shifted (6mm,6mm) ;
+draw (0,0)--(10cm,0) dashed p withpen pencircle scaled 1mm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+This way of defining a pattern is not that handy, especially if you start
+wondering why you need to supply a slanted path. Therefore, \METAPOST\ provides a
+more convenient mechanism to define a pattern.
+
+\startbuffer
+picture p ; p := dashpattern(on 3mm off 3mm) ;
+draw (0,0)--(10cm,0) dashed p withpen pencircle scaled 1mm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Most dashpatterns can be defined in terms of on and off. This simple on||off
+dashpattern is predefined as picture \type {evenly}. Because this is a picture,
+you can (and often need to) scale it.
+
+\startbuffer
+draw (0,0)--(10cm,0) dashed (evenly scaled 1mm)
+ withpen pencircle scaled 1mm ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+Opposite to a defaultpen, there is no default color and default dash pattern set.
+The macro \type {drawoptions} provides you a way to set the default attributes.
+
+\starttyping
+drawoptions(dashed evenly withcolor red) ;
+\stoptyping
+
+\stopsection
+
+\startsection[reference=sec:text,title={Text}]
+
+\index{text}
+
+Since \METAFONT\ is meant for designing fonts, the only means for including text
+are those that permit you to add labels to positions for the sole purpose of
+documentation.
+
+Because \METAPOST\ is derived from \METAFONT\ it provides labels too, but in
+order to let users add more sophisticated text, like a math formula, to a
+graphic, it also provides an interface to \TEX.
+
+Because we will spend a whole chapter on using text in \METAPOST\ we limit the
+discussion here to a few fundamentals.
+
+\startbuffer[font]
+defaultfont := "\truefontname{Mono}" ;
+defaultscale := .8 ;
+\stopbuffer
+
+\startbuffer[label]
+pair a ; a := (3cm,3cm) ;
+label.top("top",a) ; label.bot("bot",a) ;
+label.lft("lft",a) ; label.rt ("rt" ,a) ;
+\stopbuffer
+
+\typebuffer[label]
+
+These four labels show up at the position stored in the pair variable \type {a},
+anchored in the way specified after the period.
+
+\startlinecorrection[blank]
+\processMPbuffer[font,label]
+\stoplinecorrection
+
+The command \type {dotlabel} also typesets the point as a rather visible dot.
+
+\startbuffer[label]
+pair a ; a := (3cm,3cm) ;
+dotlabel.top("top",a) ; dotlabel.bot("bot",a) ;
+dotlabel.lft("lft",a) ; dotlabel.rt ("rt" ,a) ;
+\stopbuffer
+
+\typebuffer[label]
+
+\startlinecorrection[blank]
+\processMPbuffer[font,label]
+\stoplinecorrection
+
+The command \type {thelabel} returns the typeset label as picture that you can
+manipulate or draw afterwards.
+
+\startbuffer[label]
+pair a ; a := (3cm,3cm) ; pickup pencircle scaled 1mm ;
+drawdot a withcolor .625yellow ;
+draw thelabel.rt("the right way",a) withcolor .625red ;
+\stopbuffer
+
+\typebuffer[label]
+
+You can of course rotate, slant and manipulate such a label picture like any
+other picture.
+
+\startlinecorrection[blank]
+\processMPbuffer[font,label]
+\stoplinecorrection
+
+The font can be specified in the string \type {defaultfont} and the scale in
+\type {defaultscale}. Labels are defined using the low level operator \type
+{infont}. The next statement returns a picture:
+
+\startbuffer[mp]
+draw "this string will become a sequence of glyphs (MP)"
+ infont defaultfont scaled defaultscale ;
+\stopbuffer
+
+\typebuffer[mp]
+
+By default the \type {infont} operator is not that clever and does not apply
+kerning. Also, typesetting math or accented characters are not supported. The way
+out of this problem is using \typ {btex ... etex}.
+
+\startbuffer[tex]
+draw btex this string will become a sequence of glyphs (\TeX) etex ;
+\stopbuffer
+
+\typebuffer[tex]
+
+The difference between those two methods is shown below. The outcome of \type
+{infont} depends on the current setting of the variable \type {defaultfont}.
+
+\startlinecorrection[blank]
+\processMPbuffer[mp]
+\processMPbuffer[tex]
+\stoplinecorrection
+
+When you run inside \CONTEXT\ (as we do here) there is no difference between
+\type {infont} and the \TEX\ methods. This is because we overload the \type
+{infont} operator and also pass its content to \TEX. Both \type {infont} and
+\type {btex} use the macro \type {textext} which is intercepted and redirects the
+task to \TEX. This happens in the current run so there is no need to pass extra
+information about fonts.
+
+Instead of passing strings to \type {infont}, you can also pass characters, using
+\type {char}, for example \type {char(73)}. When you use \type {infont} you
+normally expect the font to be \ASCII\ conforming. If this is not the case, you
+must make sure that the encoding of the font that you use matches your
+expectations. However, as we overload this macro it does not really matter since
+the string is passed to \TEX\ anyway. For instance, \UTF\ encoded text should
+work fine as \CONTEXT\ itself understands this encoding.
+
+\stopsection
+
+\startsection[title={Linear equations}]
+
+\index{equations}
+\index{expressions}
+
+\startbuffer[a]
+\defineMPinstance
+ [solvers]
+ [format=metafun,
+ extensions=yes,
+ initializations=yes]
+\stopbuffer
+
+\startbuffer[b]
+\startMPdefinitions{solvers}
+def draw_problem (expr p, q, r, s, show_labels) =
+ begingroup ; save x, y, a, b, c, d, e, f, g, h ;
+
+ z11 = z42 = p ; z21 = z12 = q ; z31 = z22 = r ; z41 = z32 = s ;
+
+ a = x12 - x11 ; b = y12 - y11 ; c = x22 - x21 ; d = y22 - y21 ;
+ e = x32 - x31 ; f = y32 - y31 ; g = x42 - x41 ; h = y42 - y41 ;
+
+ z11 = (x11, y11) ; z12 = (x12, y12) ;
+ z13 = (x12-b, y12+a) ; z14 = (x11-b, y11+a) ;
+ z21 = (x21, y21) ; z22 = (x22, y22) ;
+ z23 = (x22-d, y22+c) ; z24 = (x21-d, y21+c) ;
+ z31 = (x31, y31) ; z32 = (x32, y32) ;
+ z33 = (x32-f, y32+e) ; z34 = (x31-f, y31+e) ;
+ z41 = (x41, y41) ; z42 = (x42, y42) ;
+ z43 = (x42-h, y42+g) ; z44 = (x41-h, y41+g) ;
+
+ pickup pencircle scaled .5pt ;
+
+ draw z11--z12--z13--z14--cycle ; draw z11--z13 ; draw z12--z14 ;
+ draw z21--z22--z23--z24--cycle ; draw z21--z23 ; draw z22--z24 ;
+ draw z31--z32--z33--z34--cycle ; draw z31--z33 ; draw z32--z34 ;
+ draw z41--z42--z43--z44--cycle ; draw z41--z43 ; draw z42--z44 ;
+
+ z1 = 0.5[z11,z13] ; z2 = 0.5[z21,z23] ;
+ z3 = 0.5[z31,z33] ; z4 = 0.5[z41,z43] ;
+
+ draw z1--z3 dashed evenly ; draw z2--z4 dashed evenly ;
+
+ z0 = whatever[z1,z3] = whatever[z2,z4] ;
+ mark_rt_angle (z1, z0, z2) ; % z2 is not used at all
+
+ if show_labels > 0 :
+ draw_problem_labels ;
+ fi ;
+
+ endgroup ;
+enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\startbuffer[c]
+\startMPdefinitions{solvers}
+angle_radius := 10pt ;
+
+def mark_rt_angle (expr a, b, c) =
+ draw ((1,0)--(1,1)--(0,1))
+ zscaled (angle_radius*unitvector(a-b))
+ shifted b
+enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\startbuffer[d]
+\startMPdefinitions{solvers}
+def draw_problem_labels =
+ pickup pencircle scaled 5pt ;
+
+ dotlabel.llft("$Z_{11}$", z11) ; dotlabel.ulft("$Z_{12}$", z12) ;
+ dotlabel.ulft("$Z_{13}$", z13) ; dotlabel.llft("$Z_{14}$", z14) ;
+
+ dotlabel.lrt ("$Z_{21}$", z21) ; dotlabel.llft("$Z_{22}$", z22) ;
+ dotlabel.urt ("$Z_{23}$", z23) ; dotlabel.ulft("$Z_{24}$", z24) ;
+
+ dotlabel.urt ("$Z_{31}$", z31) ; dotlabel.ulft("$Z_{32}$", z32) ;
+ dotlabel.urt ("$Z_{33}$", z33) ; dotlabel.urt ("$Z_{34}$", z34) ;
+
+ dotlabel.lrt ("$Z_{41}$", z41) ; dotlabel.urt ("$Z_{42}$", z42) ;
+ dotlabel.llft("$Z_{43}$", z43) ; dotlabel.lrt ("$Z_{44}$", z44) ;
+
+ dotlabel.urt ("$Z_{0}$", z0) ;
+ dotlabel.lft ("$Z_{1}$", z1) ; dotlabel.top ("$Z_{2}$", z2) ;
+ dotlabel.rt ("$Z_{3}$", z3) ; dotlabel.bot ("$Z_{4}$", z4) ;
+enddef ;
+\stopMPdefinitions
+\stopbuffer
+
+\startbuffer[e]
+\startuseMPgraphic{solvers::one}{i,j,s}
+ draw_problem (
+ (400pt,400pt), (300pt,600pt),
+ \MPvar{i}[(300pt,600pt), (550pt,800pt)],
+ \MPvar{j}[(400pt,400pt), (550pt,500pt)],
+ \MPvar{s}
+ ) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer[f]
+\placefigure
+ [here][fig:problem]
+ {The problem.}
+ {\scale
+ [width=\textwidth]
+ {\useMPgraphic{solvers::one}{i=0.6,j=1.0,s=1}}}
+\stopbuffer
+
+In the previous sections, we used the assignment operator \type {:=} to assign a
+value to a variable. Although for most of the graphics that we will present in
+later chapters, an assignment is appropriate, specifying a graphic in terms of
+expressions is not only more flexible, but also more in the spirit of the
+designers of \METAFONT\ and \METAPOST.
+
+The \METAFONT\ book and \METAPOST\ manual provide lots of examples, some of which
+involve math that we don't consider to belong to everyones repertoire. But, even
+for non mathematicians using expressions can be a rewarding challenge.
+
+The next introduction to linear equations is based on my first experiences with
+\METAPOST\ and involves a mathematical challenge posed by a friend. I quickly
+ascertained that a graphical proof was far more easy than some proof with a lot
+of $\sin (this)$ and $\cos (that)$ and long forgotten formulas.
+
+I was expected to prove that the lines connecting the centers of four squares
+drawn upon the four sides of a quadrilateral were perpendicular (see \in {figure}
+[fig:problem]).
+
+\getbuffer[a,b,c,d,e]
+
+\getbuffer[f]
+
+This graphic was generated with the following command:
+
+\typebuffer[f]
+
+We will use this example to introduce a few new concepts, one being instances. In
+a large document there can be many \METAPOST\ graphics and they might fall in
+different categories. In this manual we have graphics that are generated as part
+of the style as wel as examples that show what \METAFUN\ can do. As definitions
+and variables in \METAPOST\ are global by default, there is a possibility that we
+end up with clashes. This can be avoided by grouping graphics in instances. Here
+we create an instance for the example that we're about to show.
+
+\typebuffer[a]
+
+We can now limit the scope of definitions to this specific instance. Let's start
+with the macro that takes care of drawing the solution to our problem. The macro
+accepts four pairs of coordinates that determine the central quadrilateral. All
+of them are expressions.
+
+\typebuffer[b]
+
+Because we want to call this macro more than once, we first have to save the
+locally used values. Instead of declaring local variables, one can hide their use
+from the outside world. In most cases variables behave globally. If we don't save
+them, subsequent calls will lead to errors due to conflicting equations. We can
+omit the grouping commands, because we wrap the graphic in a figure, and figures
+are grouped already.
+
+We will use the predefined \type {z} variable, or actually a macro that returns a
+variable. This variable has two components, an \type {x} and \type {y}
+coordinate. So, we don't save \type {z}, but the related variables \type {x} and
+\type {y}.
+
+Next we draw four squares and instead of hard coding their corner points, we use
+\METAPOST's equation solver. Watch the use of \type {=} which means that we just
+state dependencies. In languages like \PERL, the equal sign is used in
+assignments, but in \METAPOST\ it is used to express relations.
+
+In a first version, we will just name a lot of simple relations, as we can read
+them from a sketch drawn on paper. So, we end up with quite some \type {z}
+related expressions.
+
+For those interested in the mathematics behind this code, we add a short
+explanation. Absolutely key to the construction is the fact that you traverse the
+original quadrilateral in a clockwise orientation. What is really going on here
+is vector geometry. You calculate the vector from $z_{11}$ to $z_{12}$ (the first
+side of the original quadrilateral) with:
+
+\starttyping
+(a,b) = z12 - z11 ;
+\stoptyping
+
+This gives a vector that points from $z_{11}$ to $z_{12}$. Now, how about an
+image that shows that the vector $(-b,a)$ is a 90 degree rotation in the
+counterclockwise direction. Thus, the points $z_{13}$ and $z_{14}$ are easily
+calculated with vector addition.
+
+\starttyping
+z13 = z12 + (-b,a) ;
+z14 = z11 + (-b,a) ;
+\stoptyping
+
+This pattern continues as you move around the original quadrilateral in a
+clockwise manner. \footnote {Thanks to David Arnold for this bonus explanation.}
+
+The code that calculates the pairs \type {a} through \type {h}, can be written in
+a more compact way.
+
+\starttyping
+(a,b) = z12 - z11 ; (c,d) = z22 - z21 ;
+(e,f) = z32 - z31 ; (g,h) = z42 - z41 ;
+\stoptyping
+
+The centers of each square can also be calculated by \METAPOST. The next lines
+define that those points are positioned halfway the extremes.
+
+\starttyping
+z1 = 0.5[z11,z13] ; z2 = 0.5[z21,z23] ;
+z3 = 0.5[z31,z33] ; z4 = 0.5[z41,z43] ;
+\stoptyping
+
+Once we have defined the relations we can let \METAPOST\ solve the equations.
+This is triggered when a variable is needed, for instance when we draw the
+squares and their diagonals. We connect the centers of the squares using a dashed
+line style.
+
+Just to be complete, we add a symbol that marks the right angle. First we
+determine the common point of the two lines, that lays at {\em whatever} point
+\METAPOST\ finds suitable.
+
+The definition of \type {mark_rt_angle} is copied from the \METAPOST\ manual and
+shows how compact a definition can be (see \at {page} [zscaled] for an
+introduction to \type {zscaled}).
+
+\typebuffer[c]
+
+So far, most equations are rather simple, and in order to solve them, \METAPOST\
+did not have to work real hard. The only boundary condition is that in order to
+find a solution, \METAPOST\ must be able to solve all dependencies.
+
+The actual value of the \type {whatever} variable is that it saves us from
+introducing a slew of variables that will never be used again. We could write:
+
+\starttyping
+z0 = A[z1,z3] = B[z2,z4] ;
+\stoptyping
+
+and get the same result, but the \type {whatever} variable saves us the trouble
+of introducing intermediate variables for which we have no use once the
+calculation is finished.
+
+The macro \type{mark_rt_angle} draws the angle symbol and later we will see how
+it is defined. First we draw the labels. Unfortunately we cannot package \typ
+{btex ... etex} into a macro, because it is processed in a rather special way.
+Each \typ {btex ... etex} occurance is filtered from the source and converted
+into a snippet of \TEX\ code. When passed through \TEX, each snippet becomes a
+page, and an auxiliary program converts each page into a \METAPOST\ picture
+definition, which is loaded by \METAPOST. The limitation lays in the fact that
+the filtering is done independent from the \METAPOST\ run, which means that loops
+(and other code) are not seen at all. Later we will introduce the \METAFUN\ way
+around this.
+
+In order to get all the labels typeset, we have to put a lot of code here. The
+macro \type {dotlabel} draws a dot and places the typeset label.
+
+\typebuffer[d]
+
+Watch out: as we are in \CONTEXT, we can pass regular \TEX\ code to the label
+macro. In a standalone \METAPOST\ run you'd have to use the \type {btex} variant.
+
+We are going to draw a lot of pictures, so we define an extra macro. This time we
+hard||code some values. The fractions \type {i} and \type {j} are responsible for
+the visual iteration process, while \type {s} determines the labels. We pass
+these variables to the graphic using an extra argument. When you define the
+(useable) graphic you need to tell what variables it can expect.
+
+\typebuffer[e]
+
+Of course we could have used a loop construct here, but defining auxiliary macros
+probably takes more time than simply calling the drawing macro directly. The
+results are shown on a separate page (\in{figure}[fig:solution]).
+
+\startbuffer[x]
+\def\MyTest#1#2%
+ {\scale
+ [width=.25\textwidth]
+ {\useMPgraphic{solvers::one}{i=#1,j=#2,s=0}}}
+\stopbuffer
+
+\startbuffer[y]
+ \startcombination[3*4]
+ {\MyTest{1.0}{1.0}} {1.0 / 1.0} {\MyTest{0.8}{1.0}} {0.8 / 1.0}
+ {\MyTest{0.6}{1.0}} {0.6 / 1.0} {\MyTest{0.4}{1.0}} {0.4 / 1.0}
+ {\MyTest{0.2}{1.0}} {0.2 / 1.0} {\MyTest{0.0}{1.0}} {0.0 / 1.0}
+ {\MyTest{0.0}{1.0}} {0.0 / 1.0} {\MyTest{0.0}{0.8}} {0.0 / 0.8}
+ {\MyTest{0.0}{0.6}} {0.0 / 0.6} {\MyTest{0.0}{0.4}} {0.0 / 0.4}
+ {\MyTest{0.0}{0.2}} {0.0 / 0.2} {\MyTest{0.0}{0.0}} {0.0 / 0.0}
+ \stopcombination
+\stopbuffer
+
+We will use a helper macro (that saves us typing):
+
+\typebuffer[x]
+
+We now can say:
+
+\typebuffer[y]
+
+Watch how we pass the settings to the graphic definition using an extra argument.
+We force using the \type {solvers} instance by prefixing the name.
+
+\startpostponing
+
+ \startnotmode[screen]
+ \placefigure
+ [here][fig:solution]
+ {The solution.}
+ {\getbuffer[x,y]}
+ \stopnotmode
+
+ \startmode[screen]
+ \placefigure
+ [here][fig:solution]
+ {The solution.}
+ {\getbuffer[x,y]}
+ \stopmode
+
+ \page
+
+\stoppostponing
+
+It does not need that much imagination to see the four sided problem converge to
+a three sided one, which itself converges to a two sided one. In the two sided
+alternative it's not that hard to prove that the angle is indeed 90 degrees.
+
+As soon as you can see a clear pattern in some code, it's time to consider using
+loops. In the previous code, we used semi indexes, like \type {12} in \type
+{z12}. In this case \type{12} does reflect something related to square~1 and~2,
+but in reality the 12 is just twelve. This does not harm our expressions.
+
+A different approach is to use a two dimensional array. In doing so, we can
+access the variables more easily using loops. If we omit the labels, and angle
+macro, the previously defined macro can be reduced considerably.
+
+\starttyping
+def draw_problem (expr n, p, q, r, s) = % number and 4 positions
+ begingroup ; save x, y ;
+
+ z[1][1] = p ; z[2][1] = q ; z[3][1] = r ; z[4][1] = s ;
+
+ for i=1 upto 4 :
+ z[i][1] = (x[i][1],y[i][1]) = z[if i=1: 4 else: i-1 fi][2] ;
+ z[i][2] = (x[i][2],y[i][2]) ;
+ z[i][3] = (x[i][2]-y[i][2]+y[i][1], y[i][2]+x[i][2]-x[i][1]) ;
+ z[i][4] = (x[i][1]-y[i][2]+y[i][1], y[i][1]+x[i][2]-x[i][1]) ;
+ z[i] = 0.5[z[i][1],z[i][3]] ;
+ endfor ;
+
+ z[0] = whatever[z[1],z[3]] = whatever[z[2],z[4]] ;
+
+ pickup pencircle scaled .5pt ;
+
+ for i=1 upto 4 :
+ draw z[i][1]--z[i][2]--z[i][3]--z[i][4]--cycle ;
+ draw z[i][1]--z[i][3] ; draw z[i][2]--z[i][4] ;
+ if i<3 : draw z[i]--z[i+2] dashed evenly fi ;
+ endfor ;
+
+ draw ((1,0)--(1,1)--(0,1))
+ zscaled (unitvector(z[1]-z[0])*10pt)
+ shifted z[0] ;
+
+ endgroup ;
+enddef ;
+\stoptyping
+
+I think that we could argue quite some time about the readability of this code.
+If you start from a sketch, and the series of equations does a good job, there is
+hardly any need for such improvements to the code. On the other hand, there are
+situations where the simplified (reduced) case can be extended more easily, for
+instance to handle 10 points instead of~4. It all depends on how you want to
+spend your free hours.
+
+\stopsection
+
+\startsection[title={Clipping}]
+
+\index{clipping}
+
+For applications that do something with a drawing, for instance \TEX\ embedding a
+graphic in a text flow, it is important to know the dimensions of the graphic.
+The maximum dimensions of a graphic are specified by its bounding box.
+
+\startlinecorrection[blank]
+\startMPcode
+path p ; p := fullcircle scaled 3cm ;
+draw p withpen pencircle scaled 1mm withcolor .625red ;
+draw boundingbox p withpen pencircle scaled .1mm ;
+draw llcorner boundingbox p withpen pencircle scaled 2mm withcolor .625yellow ;
+draw urcorner boundingbox p withpen pencircle scaled 2mm withcolor .625yellow ;
+\stopMPcode
+\stoplinecorrection
+
+A bounding box is defined by its lower left and upper right corners. If you open
+the \POSTSCRIPT\ file produced by \METAPOST, you may find lines like:
+
+\starttyping
+%%BoundingBox: -46 -46 46 46
+\stoptyping
+
+or, when supported,
+
+\starttyping
+%%HiResBoundingBox: -45.35432 -45.35432 45.35432 45.35432
+\stoptyping
+
+The first two numbers define the lower left corner and the last two numbers the
+upper right corner. From these values, you can calculate the width and height of
+the graphic.
+
+A graphic may extend beyond its bounding box. It depends on the application that
+uses the graphic whether that part of the graphic is shown.
+
+In \METAPOST\ you can ask for all four points of the bounding box of a path or
+picture as well as the center.
+
+\starttabulate[|lT|l|]
+\HL
+\NC llcorner p \NC lower left corner \NC \NR
+\NC lrcorner p \NC lower right corner \NC \NR
+\NC urcorner p \NC upper right corner \NC \NR
+\NC ulcorner p \NC upper left corner \NC \NR
+\NC center p \NC the center point \NC \NR
+\HL
+\stoptabulate
+
+You can construct the bounding box of path~\type {p} out of the four points
+mentioned:
+
+\starttyping
+llcorner p -- lrcorner p -- urcorner p -- ulcorner p -- cycle
+\stoptyping
+
+You can set the bounding box of a picture, which can be handy if you want to
+build a picture in steps and show the intermediate results using the same
+dimensions as the final picture, or when you want to show only a small piece.
+
+\startbuffer
+fill fullcircle scaled 2cm withcolor .625yellow ;
+setbounds currentpicture to unitsquare scaled 1cm ;
+draw unitsquare scaled 1cm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+Here, we set the bounding box with the command \type {setbounds}, which takes a
+path.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The graphic extends beyond the bounding box, but the bounding box determines the
+placement and therefore the spacing around the graphic. We can get rid of the
+artwork outside the bounding box by clipping it.
+
+\startbuffer
+fill fullcircle scaled 2cm withcolor .625yellow ;
+clip currentpicture to unitsquare scaled 1cm ;
+\stopbuffer
+
+\typebuffer
+
+The resulting picture is just as large but shows less of the picture.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Some extensions}]
+
+We will now encounter a couple of transformations that can make your life easy
+when you use \METAPOST\ for making graphics like the ones demonstrated in this
+document. These transformations are not part of standard \METAPOST, but come with
+\METAFUN.
+
+A very handy extension is \type {enlarged}. Although you can feed it with any
+path, it will return a rectangle larger or smaller than the boundingbox of that
+path. You can specify a pair or a numeric.
+
+\startbuffer
+path p ; p := fullsquare scaled 2cm ;
+drawpath p ; drawpoints p ;
+p := (p shifted (3cm,0)) enlarged (.5cm,.25cm) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+There are a few more alternatives, like \type {bottomenlarged}, \type
+{rightenlarged}, \type {topenlarged} and \type {leftenlarged}.
+
+The \type {cornered} operator will replace sharp corners by rounded ones (we
+could not use \type {rounded} because this is already in use).
+
+\startbuffer
+path p ; p := ((1,0)--(2,0)--(2,2)--(1,2)--(0,1)--cycle)
+ xysized (4cm,2cm) ;
+drawpath p ; drawpoints p ;
+p := (p shifted (5cm,0)) cornered .5cm ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+The \type {smoothed} operation is a less subtle one, since it operates on the
+bounding box and thereby can result in a different shape.
+
+\startbuffer
+path p ; p := ((1,0)--(2,0)--(2,2)--cycle) xysized (4cm,2cm) ;
+drawpath p ; drawpoints p ;
+p := (p shifted (5cm,0)) smoothed .5cm ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+The next one, \type {simplified}, can be applied to paths that are constructed
+automatically. Instead of testing for duplicate points during construction, you
+can clean up the path afterwards.
+
+\startbuffer
+path p ; p :=
+ ((0,0)--(1,0)--(2,0)--(2,1)--(2,2)--(1,2)--(0,2)--(0,1)--cycle)
+ xysized (4cm,2cm) ;
+drawpath p ; drawpoints p ;
+p := simplified (p shifted (5cm,0)) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+A cousin of the previous operation is \type {unspiked}. This one removes ugly
+left|-|overs. It works well for the average case.
+
+\startbuffer
+path p ; p :=
+ ((0,0)--(2,0)--(3,1)--(2,0)--(2,2)--(1,2)--(1,3)--(1,2)--(0,1)--cycle)
+ xysized (4cm,2cm) ;
+drawpath p ; drawpoints p ;
+p := unspiked (p shifted (5cm,0)) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+There are a couple of operations that manipulate the path in more drastic ways.
+Take \type {randomized}.
+
+\startbuffer
+path p ; p := fullsquare scaled 2cm ;
+drawpath p ; drawpoints p ;
+p := (p shifted (5cm,0)) randomized .5cm ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+Or how about \type {squeezed}:
+
+\startbuffer
+path p ; p := fullsquare scaled 2cm randomized .5cm ;
+drawpath p ; drawpoints p ;
+p := (p shifted (5cm,0)) squeezed .5cm ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+A \type {punked} path is, like a punked font, a font with less smooth curves (in
+our case, only straight lines).
+
+\startbuffer
+path p ; p := fullcircle scaled 2cm randomized .5cm ;
+drawpath p ; drawpoints p ;
+p := punked (p shifted (5cm,0)) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+A \type {curved} path on the other hand has smooth connections. Where in many
+cases a punked path becomes smaller, a curved path will be larger.
+
+\startbuffer
+path p ; p := fullsquare scaled 2cm randomized .5cm ;
+drawpath p ; drawpoints p ;
+p := curved (p shifted (5cm,0)) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+Probably less usefull (although we use it in one of the \OPENTYPE\ visualizers)
+is \type {laddered}:
+
+\startbuffer
+path p ; p := fullcircle scaled 3cm ;
+drawpath p ; drawpoints p ;
+p := laddered (p shifted (5cm,0)) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+When writing \PPCHTEX\ (that can be used to draw chemical structure formulas) I
+needed a parallelizing macro, so here it is:
+
+\startbuffer
+path p ; p := fullcircle scaled 3cm ;
+drawpath p ; drawpoints p ;
+p := p paralleled 1cm ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+If you use a negative argument (like \type {-1cm}) the parallel line will be
+drawn at the other side.
+
+The \type {blownup} operation scales the path but keeps the center in the same
+place.
+
+\startbuffer
+path p ; p := fullsquare xyscaled (4cm,1cm) randomized .5cm ;
+drawpath p ; drawpoints p ;
+p := p blownup .5cm ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+The \type {shortened} operation also scales the path but only makes it longer or
+shorter. This macro only works on straight paths.
+
+\startbuffer
+path p ; p := (0,0) -- (2cm,3cm) ;
+drawpath p ; drawpoints p ;
+p := p shortened 1cm ;
+drawpath p ; drawpoints p ;
+p := p shortened -1cm ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+Here are a few more drawing helpers. Even if you don't need them you might at
+some point take a look at their definitions to see what happens there. First we
+give a square round corners with \type {roundedsquare}:
+
+\startbuffer
+path p ; p := roundedsquare(2cm,4cm,.25cm) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+Next we draw a square|-|like circle (or circle|-|like square) using \type
+{tensecircle}:
+
+\startbuffer
+path p ; p := tensecircle(2cm,4cm,.25cm) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+Often I make such helpers in the process of writing larger drawing systems. Take
+\type {crossed}:
+
+\startbuffer
+path p ; p := origin crossed 1cm ;
+drawpath p ; drawpoints p ;
+p := (origin crossed fullcircle scaled 2cm crossed .5cm) shifted (3cm,0) ;
+drawpath p ; drawpoints p ;
+\stopbuffer
+
+\typebuffer
+
+These examples demonstrate that a path is made up out of points (something that
+you probably already knew by now). The \METAPOST\ operator \type {of} can be used
+to \quote {access} a certain point at a curve.
+
+\startbuffer
+path p ; p := fullsquare xyscaled (3cm,2cm) randomized .5cm ;
+drawpath p ; drawpoints p ; drawpointlabels p ;
+draw point 2.25 of p withpen pencircle scaled 5mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+To this we add two more operators: \type {on} and \type {along}. With \type {on}
+you get the point at the supplied distance from point~0; with \type {along} you
+get the point at the fraction of the length of the path.
+
+\startbuffer
+path p, q, r ;
+p := fullsquare xyscaled (2cm,2cm) randomized .5cm ;
+q := p shifted (3cm,0) ; r := q shifted (3cm,0) ;
+drawpath p ; drawpoints p ; drawpointlabels p ;
+drawpath q ; drawpoints q ; drawpointlabels q ;
+drawpath r ; drawpoints r ; drawpointlabels r ;
+pickup pencircle scaled 5mm ;
+draw point 2.25 of p withcolor .625red ;
+draw point 2.50cm on q withcolor .625yellow ;
+draw point .45 along r withcolor .625white ;
+\stopbuffer
+
+\typebuffer
+
+Beware: the \type {length} of a path is the number of points minus one. The
+shapes below are constructed from 5~points and a length of~4. If you want the
+length as dimension, you should use \type {arclength}.
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+We will now play a bit with simple lines. With \type {cutends}, you can (indeed)
+cut off the ends of a curve. The specification is a dimension.
+
+\startbuffer
+path p ; p := (0cm,0cm) -- (4cm,1cm) ;
+path q ; q := (5cm,0cm){right} .. (9cm,1cm) ;
+drawpath p ; drawpoints p ; drawpath q ; drawpoints q ;
+p := p cutends .5cm ; q := q cutends .5cm ;
+drawpathoptions (withpen pencircle scaled 5pt withcolor .625yellow) ;
+drawpointoptions(withpen pencircle scaled 4pt withcolor .625red) ;
+drawpath p ; drawpoints p ; drawpath q ; drawpoints q ;
+resetdrawoptions ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+As with more operators, \type {cutends} accepts a numeric or a pair. Watch the
+subtle difference between the next and the previous use of \type {cutends}.
+
+\startbuffer
+path p ; p := (0cm,0) .. (4cm,0) .. (8cm,0) .. (4cm,0) .. cycle ;
+drawpath p ; drawpoints p ; p := p cutends (2cm,1cm) ;
+drawpathoptions (withpen pencircle scaled 5pt withcolor .625yellow) ;
+drawpointoptions(withpen pencircle scaled 4pt withcolor .625red) ;
+drawpath p ; drawpoints p ;
+resetdrawoptions ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+When \type {stretched} is applied to a path, it is scaled but the starting point
+(point~0) keeps its location. The specification is a scale.
+
+\startbuffer
+path p ; p := (0cm,0) .. (3cm,1cm) .. (4cm,0) .. (5cm,1cm) ;
+drawpath p ; drawpoints p ; p := p stretched 1.1 ;
+drawpathoptions (withpen pencircle scaled 2.5pt withcolor .625yellow) ;
+drawpointoptions(withpen pencircle scaled 4.0pt withcolor .625red) ;
+drawpath p ; drawpoints p ; resetdrawoptions ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+We can scale in two directions independently or even in one direction by
+providing a zero value. In the next example we apply the stretch two times.
+
+\startbuffer
+path p ; p := (0cm,0) .. (3cm,1cm) .. (4cm,0) .. (5cm,1cm) ;
+drawpath p ; drawpoints p ; p := p stretched (.75,1.25) ;
+drawpathoptions (withpen pencircle scaled 2.5pt withcolor .625yellow) ;
+drawpointoptions(withpen pencircle scaled 4.0pt withcolor .625red) ;
+drawpath p ; drawpoints p ; p := p stretched (0,1.5) ;
+drawpathoptions (withpen pencircle scaled 4.0pt withcolor .625red) ;
+drawpointoptions(withpen pencircle scaled 2.5pt withcolor .625yellow) ;
+drawpath p ; drawpoints p ; resetdrawoptions ;
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+We already met the \type {randomize} operator. This one is the chameleon under
+the operators.
+
+\startbuffer
+draw fullsquare xyscaled (4cm,2cm)
+ randomized .25cm
+ shifted origin randomized (1cm, 2cm)
+ withcolor red randomized (.625, .850)
+ withpen pencircle scaled (5pt randomized 1pt) ;
+\stopbuffer
+
+\typebuffer
+
+So, \type {randomized} can handle a numeric, pair, path and color, and its
+specification can be a numeric, pair or color, depending on what we're dealing
+with.
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+In the previous example we also see \type {xyscaled} in action. Opposite to \type
+{scaled}, \type {xscaled} and \type {yscaled}, this is not one of \METAPOST\
+build in features. The same is true for the \type {.sized} operators.
+
+\startbuffer[a]
+picture p ; p := image
+ ( draw fullsquare
+ xyscaled (300,800)
+ withpen pencircle scaled 50
+ withcolor .625 yellow ; ) ;
+draw p xysized (3cm,2cm) shifted (bbwidth(currentpicture)+.5cm,0) ;
+draw p xysized 2cm shifted (bbwidth(currentpicture)+.5cm,0) ;
+draw p xsized 1cm shifted (bbwidth(currentpicture)+.5cm,0) ;
+draw p ysized 2cm shifted (bbwidth(currentpicture)+.5cm,0) ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startlinecorrection[blank] \processMPbuffer[a] \stoplinecorrection
+
+Here, the \type {image} macro creates an (actually rather large) picture. The
+last four lines actually draw this picture, but at the given dimensions. Watch
+how the line width scales accordingly. If you don't want this, you can add the
+following line:
+
+\startbuffer[b]
+redraw currentpicture withpen pencircle scaled 2pt ;
+draw boundingbox currenpicture withpen pencircle scaled .5mm ;
+\stopbuffer
+
+\typebuffer[b]
+
+Watch how the boundingbox is not affected:
+
+\startlinecorrection[blank] \processMPbuffer[a,b] \stoplinecorrection
+
+In this example we also used \type {bbwidth} (which has a companion macro \type
+{bbheight}). You can apply this macro to a path or a picture.
+
+In fact you don't always need to follow this complex route if you want to simply
+redraw a path with another pen or color.
+
+\startbuffer
+draw fullcircle scaled 1cm
+ withcolor .625red withpen pencircle scaled 1mm ;
+draw currentpicture
+ withcolor .625yellow withpen pencircle scaled 3mm ;
+draw boundingbox currentpicture
+ withpen pencircle scaled .5mm ;
+\stopbuffer
+
+\typebuffer
+
+This is what you will get from this:
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+If you want to add a background color to a picture you can do that afterwards.
+This can be handy when you don't know in advance what size the picture will have.
+
+\startbuffer
+fill fullcircle scaled 1cm withcolor .625red ;
+addbackground withcolor .625 yellow ;
+\stopbuffer
+
+\typebuffer
+
+The background is just a filled rectangle that gets the same size as the current
+picture, that is put on top of it.
+
+\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+\stopsection
+
+\startsection[title={Cutting and pasting}]
+
+\index{paths+cutting}
+\index{cutting}
+
+When enhancing or building a graphic, often parts of already constructed paths
+are needed. The \type {subpath}, \type {cutbefore} and \type {cutafter} operators
+can be used to split paths in smaller pieces. In order to do so, we must know
+where we are on the path that is involved. For this we use points on the path.
+Unfortunately we can only use these points when we know where they are located.
+In this section we will combine some techniques discussed in previous sections.
+We will define a few macros, manipulate some paths and draw curves and points.
+
+\startbuffer
+path p ; p := fullcircle yscaled 3cm xscaled .9TextWidth ;
+drawpath p ; drawpoints p withcolor .625red ; drawpointlabels p ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+This circle is drawn by scaling the predefined path \type {fullcircle}. This path
+is constructed using 8~points. As you can see, these points are not distributed
+equally along the path. In the following graphic, the second and third point of
+the curve are colored red, and point 2.5 is colored yellow. Point~0 is marked in
+black. This point is positioned halfway between point~2 and~3.
+
+\startbuffer
+path p ; p := fullcircle scaled 3cm xscaled 2 ;
+pickup pencircle scaled 5mm ; autoarrows := true ;
+drawarrow p withcolor .625white ;
+draw point 0.0 of p ;
+draw point 2.0 of p withcolor .625red ;
+draw point 2.5 of p withcolor .625yellow ;
+draw point 3.0 of p withcolor .625red ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+It is clear that, unless you know exactly how the path is constructed, other
+methods should be available. A specific point on a path is accessed by \typ
+{point ... of}, but the next example demonstrates two more alternatives.
+
+\startbuffer
+path p ; p := fullcircle scaled 3cm xscaled 2 ;
+pickup pencircle scaled 5mm ;
+draw p withcolor .625white ;
+draw point 3 of p withcolor .625red ;
+draw point .6 along p withcolor .625yellow ;
+draw point 3cm on p ;
+\stopbuffer
+
+\typebuffer
+
+So, in addition to \type {on} to specify a point by number (in \METAPOST\
+terminology called time), we have \type {along} to specify a point as fraction of
+the path, and \type {on} to specify the position in a dimension.
+
+\startlinecorrection[blank]
+\processMPbuffer
+\stoplinecorrection
+
+The \type {on} and \type {along} operators are macros and can be defined as:
+
+\starttyping
+primarydef len on pat =
+ (arctime len of pat) of pat
+enddef ;
+
+primarydef pct along pat =
+ (arctime (pct * (arclength pat)) of pat) of pat
+enddef ;
+\stoptyping
+
+These macros introduce two new primitives, \type {arctime} and \type {arclength}.
+While \type {arctime} returns a number denoting the time of the point on the
+path, \type {arclength} returns a dimension.
+
+\quotation {When mathematicians draw parametric curves, they frequently need to
+indicate the direction of motion. I often have need of a little macro that will
+put an arrow of requested length, anchored at a point on the curve, and bending
+with the curve in the direction of motion.}
+
+When David Arnold asked me how this could be achieved, the fact that a length was
+requested meant that the solution should be sought in using the primitives and
+macros we introduced a few paragraphs before. Say that we want to call for such
+an arrow as follows.
+
+\startbuffer[a]
+path p ; p := fullcircle scaled 3cm ;
+pair q ; q := point .4 along p ;
+pickup pencircle scaled 2mm ;
+draw p withcolor .625white ;
+drawarrow somearrow(p,q,2cm) withcolor .625red ;
+draw q withcolor .625yellow ;
+\stopbuffer
+
+\typebuffer[a]
+
+Because we want to follow the path, we need to construct the arrow from this
+path. Therefore, we first reduce the path by cutting off the part before the
+given point. Next we cut off the end of the resulting path so that we keep a
+slice that has the length that was asked for. Since we can only cut at points, we
+determine this point using the \type {arctime} primitive.
+
+\startbuffer[b]
+vardef somearrow (expr pat, loc, len) =
+ save p ; path p ; p := pat cutbefore loc ;
+ (p cutafter point (arctime len of p) of p)
+enddef ;
+\stopbuffer
+
+\typebuffer[b]
+
+By using a \type {vardef} we hide the intermediate assignments. Such \type
+{vardef} is automatically surrounded by \type {begingroup} and \type {endgroup},
+so the \type {save} is local to this macro. When processed, this code produces
+the following graphic:
+
+\startbuffer[c]
+autoarrows := true ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[c,b,a]
+\stoplinecorrection
+
+This graphic shows that we need a bit more control over the exact position of the
+arrow. It would be nice if we could start the arrow at the point, or end there,
+or center the arrow around the point. Therefore, the real implementation is a bit
+more advanced.
+
+\startbuffer
+vardef pointarrow (expr pat, loc, len, off) =
+ save l, r, s, t ; path l, r ; numeric s ; pair t ;
+ t := if pair loc : loc else : point loc along pat fi ;
+ s := len/2 - off ; if s<=0 : s := 0 elseif s>len : s := len fi ;
+ r := pat cutbefore t ;
+ r := (r cutafter point (arctime s of r) of r) ;
+ s := len/2 + off ; if s<=0 : s := 0 elseif s>len : s := len fi ;
+ l := reverse (pat cutafter t) ;
+ l := (reverse (l cutafter point (arctime s of l) of l)) ;
+ (l..r)
+enddef ;
+\stopbuffer
+
+\typebuffer
+
+This code fragment also demonstrates how we can treat the \type {loc} argument as
+pair (coordinates) or fraction of the path. We calculate the piece of path before
+and after the given point separately and paste them afterwards as \type {(l..r)}.
+By adding braces we can manipulate the path in expressions without the danger of
+handling \type {r} alone.
+
+We can now implement left, center and right arrows by providing this macro the
+right parameters. The offset (the fourth parameter), is responsible for a
+backward displacement. This may seem strange, but negative values would be even
+more confusing.
+
+\startbuffer
+def rightarrow (expr p,t,l) = pointarrow(p,t,l,-l) enddef ;
+def leftarrow (expr p,t,l) = pointarrow(p,t,l,+l) enddef ;
+def centerarrow(expr p,t,l) = pointarrow(p,t,l, 0) enddef ;
+\stopbuffer
+
+\typebuffer
+
+We can now apply this macro as follows:
+
+\startbuffer[a]
+path p ; p := fullcircle scaled 3cm ;
+pickup pencircle scaled 2mm ;
+draw p withcolor .625white ;
+drawarrow leftarrow (p, .4 ,2cm) withcolor .625red ;
+drawarrow centerarrow(p,point 5 of p,2cm) withcolor .625yellow ;
+draw point .4 along p withcolor .625yellow ;
+draw point 5 of p withcolor .625red ;
+\stopbuffer
+
+\typebuffer[a]
+
+\startlinecorrection[blank]
+\processMPbuffer[a]
+\stoplinecorrection
+
+Watch how we can pass a point (\typ {point 5 of p}) as well as a fraction (\type
+{.4}). The following graphic demonstrates a few more alternatives.
+
+\startbuffer[a]
+pickup pencircle scaled 2mm; autoarrows := true ;
+
+path p ; p := fullcircle yscaled 3cm xscaled .9TextWidth ;
+
+draw p withcolor .5white;
+
+for i=1, 2, 3 :
+ drawdot point i of p withpen pencircle scaled 5mm withcolor .625white ;
+endfor ;
+for i=.60, .75, .90 :
+ drawdot point i along p withpen pencircle scaled 5mm withcolor .625white ;
+endfor ;
+\stopbuffer
+
+\startbuffer[b]
+drawarrow leftarrow (p,point 1 of p,2cm) withcolor red ;
+drawarrow centerarrow (p,point 2 of p,2cm) withcolor blue ;
+drawarrow rightarrow (p,point 3 of p,2cm) withcolor green ;
+drawarrow pointarrow (p,.60,4cm,+.5cm) withcolor yellow ;
+drawarrow pointarrow (p,.75,3cm,-.5cm) withcolor cyan ;
+drawarrow centerarrow (p,.90,3cm) withcolor magenta ;
+\stopbuffer
+
+\startlinecorrection[blank]
+\processMPbuffer[a,b]
+\stoplinecorrection
+
+The arrows are drawn using the previously defined macros. Watch the positive and
+negative offsets in call to \type {pointarrow}.
+
+\typebuffer[b]
+
+\stopsection
+
+\startsection[title={Current picture}]
+
+\index {pictures}
+
+When you draw paths, texts and|/|or pictures they are added to the so called
+current picture. You can manipulate this current picture as is demonstrated in
+this manual. Let's show a few current picture related tricks.
+
+\startbuffer
+ draw fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625red ;
+\stopbuffer
+
+\typebuffer \startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+We can manipulate the picture as a whole:
+
+\startbuffer
+ draw fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625red ;
+ currentpicture := currentpicture slanted .5 ;
+\stopbuffer
+
+\typebuffer \startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+Sometimes it's handy to temporarily set aside the current picture.
+
+\startbuffer
+ draw fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625red ;
+ currentpicture := currentpicture slanted .5 ;
+ pushcurrentpicture ;
+ draw fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625yellow ;
+ currentpicture := currentpicture slanted -.5 ;
+ popcurrentpicture ;
+\stopbuffer
+
+\typebuffer \startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+These are \METAFUN\ commands but \METAPOST\ itself comes with a variant, \type
+{image}, and you explicitly have to draw this picture (or otherwise add it to the
+currentpicture).
+
+\startbuffer
+ draw fullcircle scaled 1cm withpen pencircle scaled 1mm withcolor .625red ;
+ currentpicture := currentpicture slanted .5 ;
+ draw image (
+ draw fullcircle scaled 1cm
+ withpen pencircle scaled 1mm withcolor .625yellow ;
+ currentpicture := currentpicture slanted -.5 ;
+ ) ;
+\stopbuffer
+
+\typebuffer \startlinecorrection[blank] \processMPbuffer \stoplinecorrection
+
+Each graphic starts fresh with an empty current picture. In \METAFUN\ we make
+sure that we also reset some otherwise global variables, like color, pen and some
+line properties.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun.tex b/doc/context/sources/general/manuals/metafun/metafun.tex
new file mode 100644
index 000000000..dc90bb611
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun.tex
@@ -0,0 +1,108 @@
+% language=uk macros=mkvi
+
+% author : Hans Hagen
+% copyright : PRAGMA ADE & ConTeXt Development Team
+% license : Creative Commons Attribution ShareAlike 4.0 International
+% reference : pragma-ade.nl | contextgarden.net | texlive (related) distributions
+% origin : the ConTeXt distribution
+%
+% comment : Because this manual is distributed with TeX distributions it comes with a rather
+% liberal license. We try to adapt these documents to upgrades in the (sub)systems
+% that they describe. Using parts of the content otherwise can therefore conflict
+% with existing functionality and we cannot be held responsible for that. Many of
+% the manuals contain characteristic graphics and personal notes or examples that
+% make no sense when used out-of-context.
+%
+% comment : Some chapters might have been published in TugBoat, the NTG Maps, the ConTeXt
+% Group journal or otherwise. Thanks to the editors for corrections. Also thanks
+% to users for testing, feedback and corrections.
+%
+% comment : This manual was originally written for MkII and as a consequence many examples
+% are coded in a bit different way than we would nowadays do in MkIV. But, as we
+% try to be downward compatible, it doesn't hurt.
+%
+% comment : I also use this manual for benchmarking ConTeXt MkIV. On my current machine (a
+% 2013 dell i7 laptop) one run takes some 18.1 seconds for LuaTeX and around 14.2
+% seconds for LuajitTeX which is quite okay given the amount of graphics (428
+% pages).
+%
+% comment : This is one of the manuals that can be ordered at http://www.h2o-books.com and
+% it's actually meant to be read on paper.
+
+\enabledirectives[hyphenator.optimize]
+\enabledirectives[hyphenator.flatten]
+% \setuphyphenation[method=traditional]
+
+% \enabletrackers[*defin*]
+
+% \enablemode[screen]
+\enablemode[print]
+% \enablemode[book]
+
+% \usemodule[luacalls]
+
+% todo: check startintro .. stopintro each chapter
+
+% \showframe
+
+\startproduct metafun
+
+\environment metafun-environment
+
+\startnotmode[screen]
+ \component metafun-titlepage-paper
+ \component metafun-colofon-paper
+\stopnotmode
+
+\startmode[screen]
+ \environment metafun-environment-screen
+ \component metafun-titlepage-screen
+\stopmode
+
+\startfrontmatter
+ \component metafun-introduction
+ \component metafun-contents
+ \component metafun-conventions
+\stopfrontmatter
+
+\startbodymatter
+ \component metafun-welcome
+ \component metafun-basics
+ \component metafun-embedding
+ \component metafun-layout
+ \component metafun-positioning
+ \component metafun-backgrounds
+ \component metafun-gadgets
+ \component metafun-effects
+ \component metafun-functions
+ \component metafun-text
+ \component metafun-debugging
+ \component metafun-styles
+ \component metafun-examples
+ \component metafun-macros
+ \component metafun-lua
+ %component metafun-graphics
+ \component metafun-sneaky
+\stopbodymatter
+
+\startappendices
+ % \component metafun-programs
+ \component metafun-syntax
+ \component metafun-document
+ \component metafun-reference
+ % \component metafun-literature
+\stopappendices
+
+\startbackmatter
+ \component metafun-index
+\stopbackmatter
+
+\startmode[screen]
+ \component metafun-colofon-screen
+\stopmode
+
+\startnotmode[screen]
+ \component metafun-backpage
+\stopnotmode
+
+\stopproduct
diff --git a/doc/context/sources/general/manuals/metafun/mfun-700.tex b/doc/context/sources/general/manuals/metafun/mfun-700.tex
new file mode 100644
index 000000000..e393a34f3
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-700.tex
@@ -0,0 +1,17 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\starttext
+
+\TitlePage
+ {A Few Nice Quotes\\
+ A Simple Style Demo\\
+ Hans Hagen, August 2000}
+
+\Topic {Douglas R. Hofstadter} \input douglas \page
+\Topic {Donald E. Knuth} \input knuth \page
+\Topic {Edward R. Tufte} \input tufte \page
+\Topic {Hermann Zapf} \input zapf \page
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/metafun/mfun-771.tex b/doc/context/sources/general/manuals/metafun/mfun-771.tex
new file mode 100644
index 000000000..460c16f2a
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-771.tex
@@ -0,0 +1,9 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\usemodule[present-organic]
+
+\setupMPvariables[page][alternative=1]
+
+\input mfun-700
diff --git a/doc/context/sources/general/manuals/metafun/mfun-772.tex b/doc/context/sources/general/manuals/metafun/mfun-772.tex
new file mode 100644
index 000000000..99dec1551
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-772.tex
@@ -0,0 +1,9 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\usemodule[present-organic]
+
+\setupMPvariables[page][alternative=2]
+
+\input mfun-700
diff --git a/doc/context/sources/general/manuals/metafun/mfun-773.tex b/doc/context/sources/general/manuals/metafun/mfun-773.tex
new file mode 100644
index 000000000..daefcfe66
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-773.tex
@@ -0,0 +1,9 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\usemodule[present-organic]
+
+\setupMPvariables[page][alternative=3]
+
+\input mfun-700
diff --git a/doc/context/sources/general/manuals/metafun/mfun-774.tex b/doc/context/sources/general/manuals/metafun/mfun-774.tex
new file mode 100644
index 000000000..725d1199b
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-774.tex
@@ -0,0 +1,103 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\usemodule[present-organic]
+
+\setupMPvariables[page][alternative=1]
+
+\startuseMPgraphic{page}
+
+ \includeMPgraphic{rightsuperbutton}
+
+ StartPage ;
+
+ path p, q ;
+
+ p := Field[Text][Text] enlarged 36pt superellipsed .90 ;
+
+ fill Page
+ withcolor \MPcolor{yellow} ;
+ fill p
+ withcolor \MPcolor{white} ;
+ draw p
+ dashed dashpattern (on 9pt off 9pt)
+ withpen pencircle scaled 3pt
+ withcolor \MPcolor{red} ;
+
+ p := Field[Text][Text] enlarged 48pt superellipsed .90 ;
+
+ draw p
+ dashed dashpattern (on 9pt off 9pt)
+ withpen pencircle scaled 1.5pt ;
+
+ def right_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) =
+ if (pp>0) and (rr>0) :
+ q := rightsuperbutton(p,xx,yy,RightEdgeWidth,hh) ;
+ fill q
+ withcolor \MPcolor{white} ;
+ draw ptop
+ withpen pencircle scaled 1.5pt ;
+ draw pbot
+ withpen pencircle scaled 1.5pt ;
+ draw q
+ dashed dashpattern (on 9pt off 9pt)
+ withpen pencircle scaled 3pt
+ withcolor if rr=2 : \MPcolor{gray} else : \MPcolor{red} fi ;
+ fi ;
+ enddef ;
+
+ \MPmenubuttons{right}
+
+ StopPage ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{rightsuperbutton}
+
+vardef rightsuperbutton (expr pat, xpos, ypos, wid, hei) =
+
+ save p, t, b, edge, shift, width, height ;
+ path p, ptop, pbot ; pair t, b ; numeric edge, shift, width, height ;
+
+ edge := xpos + wid ; shift := ypos + hei ;
+
+ p := rightpath pat ;
+
+draw p withpen pencircle scaled 1.5pt ;
+
+ ptop := ((-infinity,shift)--(edge,shift)) ;
+ pbot := ((-infinity,shift-hei)--(edge,shift-hei)) ;
+
+ t := p intersectionpoint ptop ;
+ b := p intersectionpoint pbot ;
+
+ label.llft("t",t) ;
+ label.ulft("b",b) ;
+
+ p := subpath(0,xpart (p intersectiontimes ptop)) of p ;
+ p := subpath(xpart (p intersectiontimes pbot),length(p)) of p ;
+
+ (p -- t -- point 1 of ptop &
+ point 1 of ptop -- point 1 of pbot &
+ point 1 of pbot -- b
+ -- cycle)
+
+enddef ;
+
+\stopuseMPgraphic
+
+
+
+\starttext
+
+\TitlePage
+ {A Few Nice Quotes\\
+ A Simple Style Demo\\
+ Hans Hagen, August 2000}
+
+\Topic {Douglas R. Hofstadter} \input douglas \page
+\Topic {Donald E. Knuth} \input knuth \page
+\Topic {Edward R. Tufte} \input tufte \page
+\Topic {Hermann Zapf} \input zapf \page
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/metafun/mfun-775.tex b/doc/context/sources/general/manuals/metafun/mfun-775.tex
new file mode 100644
index 000000000..e9d2b85a7
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-775.tex
@@ -0,0 +1,9 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\usemodule[present-organic]
+
+\setupMPvariables[page][alternative=11]
+
+\input mfun-700
diff --git a/doc/context/sources/general/manuals/metafun/mfun-776.tex b/doc/context/sources/general/manuals/metafun/mfun-776.tex
new file mode 100644
index 000000000..82b5c18dd
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-776.tex
@@ -0,0 +1,9 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\usemodule[present-organic]
+
+\setupMPvariables[page][alternative=12]
+
+\input mfun-700
diff --git a/doc/context/sources/general/manuals/metafun/mfun-800.tex b/doc/context/sources/general/manuals/metafun/mfun-800.tex
new file mode 100644
index 000000000..aa0c1260f
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-800.tex
@@ -0,0 +1,27 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\setupMPpage
+ [offset=1pt,
+ background=color,
+ backgroundcolor=gray]
+
+\definecolor [gray] [s=.625]
+\definecolor [red] [r=.625]
+\definecolor [yellow] [r=.625,g=.625]
+
+\startuseMPgraphic{test}
+ fill fullsquare rotated 45 scaled 4cm
+ withcolor \MPcolor{yellow} ;
+\stopuseMPgraphic
+
+\starttext
+
+\startMPpage
+ \includeMPgraphic{test}
+ fill fullcircle scaled 3cm
+ withcolor \MPcolor{red} ;
+\stopMPpage
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/metafun/mfun-900.tex b/doc/context/sources/general/manuals/metafun/mfun-900.tex
new file mode 100644
index 000000000..c295ec908
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-900.tex
@@ -0,0 +1,48 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent mfun-900
+
+\environment metafun-environment
+
+% Page 1
+
+\getbuffer[pagetext]
+
+% Page 2/3
+
+\getbuffer[back-0,back-1,pagetext]
+\getbuffer[back-0,back-1,pagetext]
+
+\setupbackgrounds[page][background=]
+
+% Page 4/5
+
+\getbuffer[back-0,back-2,pagetext]
+\getbuffer[back-0,back-2,pagetext]
+
+\setupbackgrounds[page][background=]
+
+% Page 6/7
+
+\getbuffer[back-0,back-3,pagetext]
+\getbuffer[back-0,back-3,pagetext]
+
+\setupbackgrounds[page][background=]
+
+% Page 8/9
+
+\getbuffer[back-0,back-4,pagetext]
+\getbuffer[back-0,back-4,pagetext]
+
+\setupbackgrounds[page][background=]
+
+% Page 10/11
+
+\getbuffer[back-0,back-5,pagetext]
+\getbuffer[back-0,back-5,pagetext]
+
+\setupbackgrounds[page][background=]
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/mfun-901.tex b/doc/context/sources/general/manuals/metafun/mfun-901.tex
new file mode 100644
index 000000000..23adf77b4
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-901.tex
@@ -0,0 +1,11 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent mfun-901
+
+\environment metafun-environment
+
+\getbuffer[gridpage]
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/mfun-902.tex b/doc/context/sources/general/manuals/metafun/mfun-902.tex
new file mode 100644
index 000000000..7c4fed73e
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-902.tex
@@ -0,0 +1,11 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent mfun-902
+
+\environment metafun-environment
+
+\getbuffer[handwrit]
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/mfun-mrun-demo.mp b/doc/context/sources/general/manuals/metafun/mfun-mrun-demo.mp
new file mode 100644
index 000000000..c6589beb5
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mfun-mrun-demo.mp
@@ -0,0 +1,212 @@
+%D Downloading
+
+beginfig (1) ;
+
+ path p, q ;
+
+ p := (0,110)..(50,110) shifted (0,-15)..(100,110)--
+ (50,50) shifted (10,0) ..(50,50) shifted (0,2.5)..
+ (50,50) shifted(-10,0)--cycle ;
+ q := (5,0)--(95,0)--(95,30)..(50,0) shifted (0,10)..(5,30)--cycle ;
+
+ pickup pencircle scaled 15 ;
+ drawdot (80,100) withcolor .6red ;
+ drawdot (65,95) withcolor .6red ;
+ drawdot (50,95) withcolor .6red ;
+ drawdot (35,95) withcolor .6red ;
+
+ drawdot (50,60) withcolor .6red ;
+ drawdot (50,35) withcolor .6red ;
+ drawdot (50,10) withcolor .6red ;
+ drawdot (70,10) withcolor .6red ;
+ drawdot (32.5,10) withcolor .6red ;
+
+ pickup pencircle scaled 5 ;
+ fill p withcolor .6green ; draw p withcolor .4green ;
+ fill q withcolor .6green ; draw q withcolor .4green ;
+
+ bboxmargin := 2.5 ; p := bbox currentpicture ;
+ picture s ; s := currentpicture ; currentpicture := nullpicture ;
+
+ pickup pencircle scaled 2.5 ;
+ fill p withcolor .4blue ;
+ addto currentpicture also s ;
+
+endfig ;
+
+%D WWW Links
+
+beginfig (2) ;
+
+ boolean angles [], lengths[], colors [][][] ;
+ numeric a, l, r, g, b, n ;
+ path p ;
+ color c ;
+
+ draw fullsquare scaled 150 withpen pencircle scaled 1 withcolor .5white ;
+
+ n := 0 ;
+ forever :
+ a := 6 * round(uniformdeviate 60) ;
+ l := 40 + round(uniformdeviate 60) ;
+ r := 2 + round(uniformdeviate 6) ;
+ g := 2 + round(uniformdeviate 6) ;
+ b := 2 + round(uniformdeviate 6) ;
+ if (a>0) and not known angles [a] and not known lengths[l] and not known colors [r][g][b] :
+ n := n + 1 ;
+ angles [a] := true ;
+ lengths[l] := true ;
+ colors [r][g][b] := true ;
+ p := (origin--origin shifted (0,.5l)) rotatedaround(origin,a) ;
+ draw p withpen pencircle scaled 2 withcolor (r/10,g/10,b/10) ;
+ drawdot point 1 of p withpen pencircle scaled 4 withcolor (r/10,g/10,b/10) ;
+ p := (origin shifted (0,.5l+8)--origin shifted(0,100)) rotatedaround(origin,a) ;
+ draw p withpen pencircle scaled 2 withcolor (r/10,g/10,b/10) ;
+ drawdot point 0 of p withpen pencircle scaled 4 withcolor (r/10,g/10,b/10) ;
+ fi ;
+ exitif n >= 60 ;
+ endfor ;
+
+ drawdot
+ origin
+ withpen pencircle scaled 10
+ withcolor white ;
+
+ fill
+ ((fullcircle scaled 130) peepholed (fullsquare scaled 150))
+ withcolor (1,1,1)-(1,.62,.06);
+
+ clip currentpicture to fullsquare scaled 130 ;
+
+endfig ;
+
+%D Mirrors
+
+beginfig(3)
+
+ path a, b, p, q ;
+ pair s, t, u, v ;
+ color c ;
+ numeric h, w, r ;
+
+ pickup pencircle scaled 10 ;
+
+ h := 120 ;
+ w := 80 ;
+ r := 30 ;
+
+ a := (0,0)..(0,.5h) shifted (-r,0)..(0,h) ;
+ b := (w,0)..(w,.5h) shifted ( r,0)..(w,h) ;
+
+ draw a withcolor .4white;
+ draw b withcolor .4white;
+
+ def moved (expr i) =
+ ((i) - 10 + uniformdeviate 20)
+ enddef ;
+
+ for i=5 step 10 until h-5 :
+ s := (point (length(a)*(i/h)) of a) ;
+ t := (point (length(b)*(1-i/h)) of b) ;
+ u := (s--t) intersectionpoint ((.25w,0)--(.25w,h)) ;
+ v := (s--t) intersectionpoint ((.75w,0)--(.75w,h)) ;
+ p := s..(xpart u,moved(ypart u))..(xpart v,moved(ypart v))..t ;
+ c := (0,.4+uniformdeviate.55,0) ;
+ l := length(p) ;
+ l := .25l+uniformdeviate.5l ;
+ q := p cutafter point l of p ;
+ pickup pencircle scaled 2.5 ;
+ draw p withcolor c ;
+ pickup pencircle scaled 5 ;
+ drawdot point 0 of p withcolor c ;
+ drawdot point infinity of p withcolor c ;
+ endfor ;
+
+ picture s ; s := currentpicture ; currentpicture := nullpicture ;
+
+ bboxmargin := 2.5 ; fill bbox s withcolor .85white ;
+
+ addto currentpicture also s ;
+
+endfig;
+
+%D Team
+
+def dpuppet (expr v, w) =
+ v - .5w + uniformdeviate w
+enddef ;
+
+def somepuppet (expr s, r) =
+ picture p ; p := currentpicture ; currentpicture := nullpicture ;
+ draw ((-10,0)--(10,0)) ;
+ for i:=-10 step 5 until 10 :
+ draw ((i,0)--(dpuppet(i,2),-10)) ;
+ endfor ;
+ currentpicture := currentpicture rotated r shifted s ;
+ addto currentpicture also p ;
+enddef ;
+
+def puppet (expr loc, sca, col) =
+ picture s ; s := currentpicture ; currentpicture := nullpicture ;
+
+ pair a ; a := (dpuppet( 20,5),dpuppet( 0, 5)) ;
+ pair b ; b := (dpuppet(-20,5),dpuppet( 0, 5)) ;
+ pair c ; c := (dpuppet( 30,5),dpuppet(60,10)) ;
+ pair d ; d := (dpuppet(-30,5),dpuppet(60,10)) ;
+ pair e ; e := (dpuppet( 0,5),dpuppet(30,10)) ;
+ pair f ; f := (dpuppet( 0,5),dpuppet(50,10)) ;
+ pair g ; g := (dpuppet( 0,5),dpuppet(65,10)) ;
+
+ pair f ; f := (.6+uniformdeviate.1)[e,g] ;
+
+ drawoptions (withcolor col) ;
+
+ somepuppet(a,dpuppet( 20,5)) ;
+ somepuppet(b,dpuppet( -20,5)) ;
+ somepuppet(c,dpuppet( 120,5)) ;
+ somepuppet(d,dpuppet(-120,5)) ;
+
+ draw a -- e ;
+ draw b -- e ;
+ draw c -- f ;
+ draw d -- f ;
+ draw e -- g ;
+ draw fullcircle scaled 25 shifted (g shifted (0,12.5));
+
+ drawoptions () ;
+
+ currentpicture := currentpicture scaled sca shifted loc ;
+ addto currentpicture also s ;
+enddef ;
+
+beginfig (4) ;
+
+ pickup pencircle scaled 0 ;
+
+ color col ; col := (.4,.8,.6) ;
+
+ puppet((-20, 0) ,.20, 0.700col) ;
+ puppet(( 10,10) ,.30, 0.750col) ;
+ puppet(( 30,20) ,.40, 0.800col) ;
+ puppet((-20,30) ,.35, 0.850col) ;
+ puppet(( 20,60) ,.20, 0.900col) ;
+ puppet(( -5,65) ,.25, 0.950col) ;
+
+ picture s ; s := currentpicture ; currentpicture := nullpicture ;
+
+ bboxmargin := 15 ; fill bbox s withcolor .8(1,1,0) ;
+
+ addto currentpicture also s withpen pencircle scaled .8 ;
+
+ path b ; bboxmargin := -10 ; b := bbox currentpicture ;
+ numeric len ; len := length(b) ;
+ numeric stp ; stp := 20 ;
+ drawoptions(withpen pencircle scaled .8 withcolor .7red) ;
+ for i=len/8stp step len/4stp until len+len/8stp :
+ pair ii ; ii := point (dpuppet(i,len/20stp)) of b ;
+ pair dd ; dd := (direction i of b) rotated (dpuppet(-90,10)) ;
+ draw ii shifted -.1dd withpen pencircle scaled 1.2 ;
+ draw ii--(ii shifted .25dd) ;
+ endfor ;
+
+endfig ;
diff --git a/doc/context/sources/general/manuals/metafun/mycow.mp b/doc/context/sources/general/manuals/metafun/mycow.mp
new file mode 100644
index 000000000..24c3e0f7d
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mycow.mp
@@ -0,0 +1,299 @@
+% Converted from PostScript(TM) to MetaPost by pstoedit
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+% MetaPost backend contributed by Scott Pakin <pakin@uiuc.edu>
+% pstoedit is Copyright (C) 1993 - 1999 Wolfgang Glunz <wglunz@geocities.com>
+
+% Generate structured PostScript
+prologues := 1;
+
+% Display a given string with its *baseline* at a given location
+% and with a given rotation angle
+vardef showtext(expr origin)(expr angle)(expr string) =
+ draw string infont defaultfont scaled defaultscale
+ rotated angle shifted origin;
+enddef;
+
+beginfig(1);
+drawoptions (withcolor (1,1,1));
+fill (84.3799,618.55)..controls (88.3398,624.38) and (92.5898,622.94)..(96.3398,615.67)
+ ..controls (101.23,615.6) and (102.46,612.43)..(104.98,610.78)
+ ..controls (122.62,598.39) and (147.46,607.18)..(167.9,601.92)
+ ..controls (180.94,598.54) and (190.87,599.76)..(200.09,602.06)
+ ..controls (220.32,607.25) and (246.1,596.16)..(263.74,603.86)
+ ..controls (274.75,608.62) and (284.76,605.66)..(292.97,600.91)
+ ..controls (297.58,597.96) and (299.59,596.09)..(300.96,591.26)
+ ..controls (306.29,572.54) and (306.29,551.02)..(309.53,530.57)
+ ..controls (309.53,528.84) and (312.19,526.1)..(312.48,522.07)
+ ..controls (315.79,511.34) and (316.08,510.12)..(317.16,502.2)
+ ..controls (317.16,501.34) and (326.52,488.45)..(325.01,479.02)
+ ..controls (323.93,481.25) and (323.86,482.83)..(321.62,481.68)
+ ..controls (320.33,479.3) and (320.9,473.9)..(322.56,471.74)
+ ..controls (320.83,470.81) and (318.46,473.47)..(317.52,475.2)
+ ..controls (318.17,473.04) and (317.81,470.81)..(316.73,469.3)
+ ..controls (315.86,472.25) and (316.58,473.18)..(315.36,473.9)
+ ..controls (313.99,472.9) and (314.21,469.3)..(314.28,466.2)
+ ..controls (313.49,468.07) and (311.47,472.46)..(312.55,476.42)
+ ..controls (312.48,484.2) and (308.81,489.1)..(310.32,499.1)
+ ..controls (310.1,504.43) and (307.3,521.06)..(304.56,524.3)
+ ..controls (303.12,526.25) and (306.36,510.77)..(306.36,506.16)
+ ..controls (306.65,500.9) and (307.08,468.72)..(306.43,463.1)
+ ..controls (306.43,459.22) and (306.22,453.96)..(307.08,452.16)
+ ..controls (308.74,450.79) and (309.38,450.5)..(309.6,447.98)
+ ..controls (309.24,446.62) and (308.74,446.04)..(307.73,445.54)
+ ..controls (306.07,444.6) and (307.37,441.79)..(306.07,439.85)
+ ..controls (304.49,438.77) and (304.13,441.86)..(303.34,441.86)
+ ..controls (302.69,441) and (303.05,437.98)..(302.47,436.18)
+ ..controls (299.66,433.8) and (292.18,432.5)..(289.15,434.66)
+ ..controls (289.73,440.64) and (291.74,441.58)..(295.63,446.62)
+ ..controls (298.66,452.59) and (297,460.94)..(296.93,468.14)
+ ..controls (295.49,480.38) and (289.22,487.3)..(289.44,496.44)
+ ..controls (287.86,495.72) and (286.42,494.57)..(284.26,494.86)
+ ..controls (283.39,489.46) and (286.42,484.56)..(284.83,480.82)
+ ..controls (281.95,471.96) and (277.06,446.62)..(279,437.76)
+ ..controls (280.01,434.74) and (278.21,433.15)..(277.06,433.94)
+ ..controls (276.77,433.94) and (276.55,433.94)..(276.41,433.94)
+ ..controls (276.41,433.94) and (276.55,431.42)..(275.69,430.92)
+ ..controls (274.1,430.34) and (273.67,431.71)..(272.66,432.14)
+ ..controls (271.22,430.85) and (272.52,429.48)..(271.15,428.04)
+ ..controls (267.19,428.04) and (261.36,425.38)..(257.98,428.26)
+ ..controls (257.33,434.16) and (263.3,436.68)..(266.47,440.71)
+ ..controls (268.63,446.62) and (271.08,462.89)..(267.77,474.62)
+ ..controls (267.77,475.56) and (264.38,485.28)..(261.43,488.66)
+ ..controls (258.7,487.66) and (257.33,485.5)..(253.22,486.29)
+ ..controls (252.58,484.34) and (253.3,482.33)..(252.22,480.1)
+ ..controls (251.86,479.52) and (249.34,478.58)..(249.19,481.39)
+ ..controls (248.98,483.05) and (248.9,486.36)..(248.26,486.72)
+ ..controls (243.65,486.72) and (233.71,487.08)..(231.77,493.92)
+ ..controls (219.89,492.34) and (215.93,491.26)..(206.57,493.42)
+ ..controls (196.63,489.67) and (183.24,506.16)..(174.53,502.2)
+ ..controls (172.51,496.15) and (173.09,485.64)..(171.65,481.39)
+ ..controls (169.34,474.77) and (171.14,467.14)..(171.14,456.41)
+ ..controls (170.57,455.4) and (169.85,454.46)..(168.48,454.46)
+ ..controls (168.48,453.1) and (169.34,450.86)..(168.62,449.42)
+ ..controls (167.18,447.62) and (165.89,451.8)..(165.02,444.6)
+ ..controls (163.15,443.74) and (157.75,442.22)..(155.59,445.18)
+ ..controls (155.88,448.99) and (158.33,451.3)..(160.13,453.38)
+ ..controls (161.42,456.91) and (160.99,458.28)..(160.7,461.81)
+ ..controls (160.99,464.98) and (161.71,468.58)..(161.86,470.09)
+ ..controls (161.86,473.04) and (162.5,479.3)..(161.14,481.18)
+ --(159.41,482.69)..controls (157.18,487.22) and (158.33,494.64)..(157.61,500.26)
+ ..controls (155.81,500.69) and (155.81,500.98)..(154.01,498.31)
+ ..controls (154.01,494.42) and (153.5,486.36)..(152.35,483.84)
+ ..controls (149.69,479.81) and (150.84,459.65)..(151.42,448.56)
+ ..controls (151.78,446.47) and (149.69,447.7)..(149.76,444.74)
+ ..controls (150.05,442.8) and (147.89,443.59)..(146.09,444.6)
+ ..controls (145.15,445.18) and (146.59,439.78)..(145.37,439.56)
+ ..controls (142.34,438.84) and (136.87,438.19)..(135.22,440.71)
+ ..controls (134.57,444.6) and (137.88,448.06)..(140.62,451.01)
+ ..controls (143.14,455.83) and (140.9,465.7)..(140.47,476.28)
+ --(138.89,478.22)..controls (134.86,483.19) and (139.61,496.94)..(136.51,506.23)
+ ..controls (120.02,514.87) and (122.11,519.19)..(118.73,537.62)
+ ..controls (115.13,557.64) and (93.3799,567.65)..(79.0598,567.65)
+ ..controls (73.4399,563.04) and (66.24,563.62)..(58.5398,567.65)
+ ..controls (55.6599,569.23) and (54.4299,573.19)..(54.5,576.5)
+ ..controls (52.6299,580.75) and (55.22,582.19)..(59.6199,583.49)
+ ..controls (62.71,587.81) and (68.6199,594.65)..(69.1899,597.74)
+ ..controls (70.3398,601.92) and (75.5298,608.11)..(77.7598,609.77)
+ ..controls (75.8198,613.01) and (74.8098,615.17)..(77.1099,618.55)
+ ..controls (79.5598,620.14) and (81.7898,616.61)..(84.3799,618.55)
+ --cycle;
+drawoptions (withcolor (0,0,0));
+pickup pencircle scaled 0.636492bp;
+draw (84.3799,618.55)..controls (88.3398,624.38) and (92.5898,622.94)..(96.3398,615.67)
+ ..controls (101.23,615.6) and (102.46,612.43)..(104.98,610.78)
+ ..controls (122.62,598.39) and (147.46,607.18)..(167.9,601.92)
+ ..controls (180.94,598.54) and (190.87,599.76)..(200.09,602.06)
+ ..controls (220.32,607.25) and (246.1,596.16)..(263.74,603.86)
+ ..controls (274.75,608.62) and (284.76,605.66)..(292.97,600.91)
+ ..controls (297.58,597.96) and (299.59,596.09)..(300.96,591.26)
+ ..controls (306.29,572.54) and (306.29,551.02)..(309.53,530.57)
+ ..controls (309.53,528.84) and (312.19,526.1)..(312.48,522.07)
+ ..controls (315.79,511.34) and (316.08,510.12)..(317.16,502.2)
+ ..controls (317.16,501.34) and (326.52,488.45)..(325.01,479.02)
+ ..controls (323.93,481.25) and (323.86,482.83)..(321.62,481.68)
+ ..controls (320.33,479.3) and (320.9,473.9)..(322.56,471.74)
+ ..controls (320.83,470.81) and (318.46,473.47)..(317.52,475.2)
+ ..controls (318.17,473.04) and (317.81,470.81)..(316.73,469.3)
+ ..controls (315.86,472.25) and (316.58,473.18)..(315.36,473.9)
+ ..controls (313.99,472.9) and (314.21,469.3)..(314.28,466.2)
+ ..controls (313.49,468.07) and (311.47,472.46)..(312.55,476.42)
+ ..controls (312.48,484.2) and (308.81,489.1)..(310.32,499.1)
+ ..controls (310.1,504.43) and (307.3,521.06)..(304.56,524.3)
+ ..controls (303.12,526.25) and (306.36,510.77)..(306.36,506.16)
+ ..controls (306.65,500.9) and (307.08,468.72)..(306.43,463.1)
+ ..controls (306.43,459.22) and (306.22,453.96)..(307.08,452.16)
+ ..controls (308.74,450.79) and (309.38,450.5)..(309.6,447.98)
+ ..controls (309.24,446.62) and (308.74,446.04)..(307.73,445.54)
+ ..controls (306.07,444.6) and (307.37,441.79)..(306.07,439.85)
+ ..controls (304.49,438.77) and (304.13,441.86)..(303.34,441.86)
+ ..controls (302.69,441) and (303.05,437.98)..(302.47,436.18)
+ ..controls (299.66,433.8) and (292.18,432.5)..(289.15,434.66)
+ ..controls (289.73,440.64) and (291.74,441.58)..(295.63,446.62)
+ ..controls (298.66,452.59) and (297,460.94)..(296.93,468.14)
+ ..controls (295.49,480.38) and (289.22,487.3)..(289.44,496.44)
+ ..controls (287.86,495.72) and (286.42,494.57)..(284.26,494.86)
+ ..controls (283.39,489.46) and (286.42,484.56)..(284.83,480.82)
+ ..controls (281.95,471.96) and (277.06,446.62)..(279,437.76)
+ ..controls (280.01,434.74) and (278.21,433.15)..(277.06,433.94)
+ ..controls (276.77,433.94) and (276.55,433.94)..(276.41,433.94)
+ ..controls (276.41,433.94) and (276.55,431.42)..(275.69,430.92)
+ ..controls (274.1,430.34) and (273.67,431.71)..(272.66,432.14)
+ ..controls (271.22,430.85) and (272.52,429.48)..(271.15,428.04)
+ ..controls (267.19,428.04) and (261.36,425.38)..(257.98,428.26)
+ ..controls (257.33,434.16) and (263.3,436.68)..(266.47,440.71)
+ ..controls (268.63,446.62) and (271.08,462.89)..(267.77,474.62)
+ ..controls (267.77,475.56) and (264.38,485.28)..(261.43,488.66)
+ ..controls (258.7,487.66) and (257.33,485.5)..(253.22,486.29)
+ ..controls (252.58,484.34) and (253.3,482.33)..(252.22,480.1)
+ ..controls (251.86,479.52) and (249.34,478.58)..(249.19,481.39)
+ ..controls (248.98,483.05) and (248.9,486.36)..(248.26,486.72)
+ ..controls (243.65,486.72) and (233.71,487.08)..(231.77,493.92)
+ ..controls (219.89,492.34) and (215.93,491.26)..(206.57,493.42)
+ ..controls (196.63,489.67) and (183.24,506.16)..(174.53,502.2)
+ ..controls (172.51,496.15) and (173.09,485.64)..(171.65,481.39)
+ ..controls (169.34,474.77) and (171.14,467.14)..(171.14,456.41)
+ ..controls (170.57,455.4) and (169.85,454.46)..(168.48,454.46)
+ ..controls (168.48,453.1) and (169.34,450.86)..(168.62,449.42)
+ ..controls (167.18,447.62) and (165.89,451.8)..(165.02,444.6)
+ ..controls (163.15,443.74) and (157.75,442.22)..(155.59,445.18)
+ ..controls (155.88,448.99) and (158.33,451.3)..(160.13,453.38)
+ ..controls (161.42,456.91) and (160.99,458.28)..(160.7,461.81)
+ ..controls (160.99,464.98) and (161.71,468.58)..(161.86,470.09)
+ ..controls (161.86,473.04) and (162.5,479.3)..(161.14,481.18)
+ --(159.41,482.69)..controls (157.18,487.22) and (158.33,494.64)..(157.61,500.26)
+ ..controls (155.81,500.69) and (155.81,500.98)..(154.01,498.31)
+ ..controls (154.01,494.42) and (153.5,486.36)..(152.35,483.84)
+ ..controls (149.69,479.81) and (150.84,459.65)..(151.42,448.56)
+ ..controls (151.78,446.47) and (149.69,447.7)..(149.76,444.74)
+ ..controls (150.05,442.8) and (147.89,443.59)..(146.09,444.6)
+ ..controls (145.15,445.18) and (146.59,439.78)..(145.37,439.56)
+ ..controls (142.34,438.84) and (136.87,438.19)..(135.22,440.71)
+ ..controls (134.57,444.6) and (137.88,448.06)..(140.62,451.01)
+ ..controls (143.14,455.83) and (140.9,465.7)..(140.47,476.28)
+ --(138.89,478.22)..controls (134.86,483.19) and (139.61,496.94)..(136.51,506.23)
+ ..controls (120.02,514.87) and (122.11,519.19)..(118.73,537.62)
+ ..controls (115.13,557.64) and (93.3799,567.65)..(79.0598,567.65)
+ ..controls (73.4399,563.04) and (66.24,563.62)..(58.5398,567.65)
+ ..controls (55.6599,569.23) and (54.4299,573.19)..(54.5,576.5)
+ ..controls (52.6299,580.75) and (55.22,582.19)..(59.6199,583.49)
+ ..controls (62.71,587.81) and (68.6199,594.65)..(69.1899,597.74)
+ ..controls (70.3398,601.92) and (75.5298,608.11)..(77.7598,609.77)
+ ..controls (75.8198,613.01) and (74.8098,615.17)..(77.1099,618.55)
+ ..controls (79.5598,620.14) and (81.7898,616.61)..(84.3799,618.55)
+ --cycle;
+pickup pencircle scaled 0bp;
+fill (305.28,560.95)..controls (304.63,560.95) and (299.95,561.24)..(299.38,561.24)
+ ..controls (302.4,550.44) and (303.98,536.47)..(304.2,525.31)
+ ..controls (303.7,521.35) and (299.81,517.46)..(299.38,525.67)
+ ..controls (295.85,530.86) and (296.42,540.07)..(293.4,540.29)
+ ..controls (287.35,539.64) and (285.34,513.22)..(280.01,509.33)
+ ..controls (276.26,512.28) and (280.73,524.02)..(275.54,524.74)
+ ..controls (270.5,524.02) and (264.31,526.68)..(266.69,534.46)
+ ..controls (270.29,543.02) and (268.34,554.76)..(266.54,561.6)
+ ..controls (262.37,578.59) and (264.02,587.09)..(271.58,596.09)
+ --(267.48,604.51)..controls (275.4,608.26) and (285.62,604.58)..(290.02,602.21)
+ ..controls (294.62,600.26) and (300.24,595.94)..(301.1,587.38)
+ ..controls (303.34,578.88) and (304.42,569.74)..(305.28,560.95)
+ --cycle;
+fill (245.45,600.34)..controls (242.78,599.4) and (239.62,596.02)..(237.67,594.07)
+ ..controls (236.74,584.42) and (244.58,583.63)..(250.2,577.44)
+ ..controls (258.77,573.7) and (251.21,567.72)..(256.18,557.42)
+ ..controls (257.04,550.94) and (257.9,543.89)..(255.31,539.78)
+ ..controls (249.48,538.92) and (247.97,540.22)..(246.89,531.43)
+ ..controls (246.31,526.97) and (231.77,529.06)..(229.03,538.27)
+ ..controls (227.09,544.97) and (221.33,546.7)..(217.8,543.17)
+ ..controls (213.77,538.06) and (215.78,531.22)..(217.8,527.47)
+ ..controls (224.93,517.32) and (212.04,511.42)..(205.13,516.74)
+ ..controls (199.73,508.68) and (211.39,500.04)..(207.43,494.5)
+ ..controls (205.78,493.99) and (204.77,489.17)..(185.47,500.54)
+ ..controls (180.36,504.14) and (167.83,500.76)..(168.77,520.63)
+ ..controls (168.77,525.82) and (165.6,543.53)..(162.14,555.91)
+ ..controls (159.41,561.24) and (156.74,559.08)..(156.89,553.9)
+ ..controls (157.18,547.85) and (162.94,531.22)..(155.52,540.22)
+ ..controls (153.58,539.21) and (156.89,523.58)..(156.89,521.64)
+ ..controls (162,517.03) and (157.39,513.58)..(154.73,512.28)
+ ..controls (151.27,518.33) and (149.62,518.04)..(147.17,514.44)
+ ..controls (141.7,514.08) and (144.58,528.19)..(140.26,528.62)
+ ..controls (137.02,527.76) and (139.18,520.06)..(138.24,518.76)
+ ..controls (132.98,524.74) and (130.9,529.27)..(127.01,521.64)
+ ..controls (126.14,521.64) and (122.11,519.19)..(120.96,526.54)
+ ..controls (117.65,552.74) and (107.06,558.36)..(93.8198,565.13)
+ ..controls (92.0198,565.63) and (84.24,566.71)..(79.3398,568.15)
+ ..controls (73.5098,560.88) and (58.3198,565.63)..(56.23,570.31)
+ ..controls (54.7898,572.69) and (54.6499,575.21)..(54.7898,576.5)
+ ..controls (52.3398,580.1) and (55.8699,582.7)..(59.6199,583.06)
+ ..controls (62.8599,587.16) and (68.5398,594.94)..(71.2798,601.56)
+ ..controls (72.2898,603.07) and (74.95,609.34)..(78.1899,609.55)
+ ..controls (74.95,612.94) and (74.2998,622.51)..(82.6599,617.33)
+ ..controls (87.1199,624.02) and (92.0898,624.31)..(95.7598,615.82)
+ ..controls (102.89,615.38) and (102.31,608.69)..(115.78,605.52)
+ ..controls (122.76,602.86) and (132.77,604.58)..(140.26,603.72)
+ ..controls (136.22,596.88) and (127.44,566.86)..(132.98,559.8)
+ ..controls (140.76,564.7) and (141.84,605.38)..(157.03,595.66)
+ ..controls (160.56,593.93) and (159.91,590.04)..(164.09,590.18)
+ ..controls (170.42,587.45) and (169.13,600.77)..(172.51,600.77)
+ ..controls (176.47,599.76) and (183.02,599.04)..(186.98,599.54)
+ ..controls (197.71,600.77) and (206.93,604.08)..(223.92,602.5)
+ ..controls (231.12,601.78) and (238.25,601.06)..(245.45,600.34)
+ --cycle;
+pickup pencircle scaled 0.636492bp;
+draw (305.28,560.95)..controls (304.63,560.95) and (299.95,561.24)..(299.38,561.24)
+ ..controls (302.4,550.44) and (303.98,536.47)..(304.2,525.31)
+ ..controls (303.7,521.35) and (299.81,517.46)..(299.38,525.67)
+ ..controls (295.85,530.86) and (296.42,540.07)..(293.4,540.29)
+ ..controls (287.35,539.64) and (285.34,513.22)..(280.01,509.33)
+ ..controls (276.26,512.28) and (280.73,524.02)..(275.54,524.74)
+ ..controls (270.5,524.02) and (264.31,526.68)..(266.69,534.46)
+ ..controls (270.29,543.02) and (268.34,554.76)..(266.54,561.6)
+ ..controls (262.37,578.59) and (264.02,587.09)..(271.58,596.09)
+ --(267.48,604.51)..controls (275.4,608.26) and (285.62,604.58)..(290.02,602.21)
+ ..controls (294.62,600.26) and (300.24,595.94)..(301.1,587.38)
+ ..controls (303.34,578.88) and (304.42,569.74)..(305.28,560.95)
+ --cycle;
+draw (245.45,600.34)..controls (242.78,599.4) and (239.62,596.02)..(237.67,594.07)
+ ..controls (236.74,584.42) and (244.58,583.63)..(250.2,577.44)
+ ..controls (258.77,573.7) and (251.21,567.72)..(256.18,557.42)
+ ..controls (257.04,550.94) and (257.9,543.89)..(255.31,539.78)
+ ..controls (249.48,538.92) and (247.97,540.22)..(246.89,531.43)
+ ..controls (246.31,526.97) and (231.77,529.06)..(229.03,538.27)
+ ..controls (227.09,544.97) and (221.33,546.7)..(217.8,543.17)
+ ..controls (213.77,538.06) and (215.78,531.22)..(217.8,527.47)
+ ..controls (224.93,517.32) and (212.04,511.42)..(205.13,516.74)
+ ..controls (199.73,508.68) and (211.39,500.04)..(207.43,494.5)
+ ..controls (205.78,493.99) and (204.77,489.17)..(185.47,500.54)
+ ..controls (180.36,504.14) and (167.83,500.76)..(168.77,520.63)
+ ..controls (168.77,525.82) and (165.6,543.53)..(162.14,555.91)
+ ..controls (159.41,561.24) and (156.74,559.08)..(156.89,553.9)
+ ..controls (157.18,547.85) and (162.94,531.22)..(155.52,540.22)
+ ..controls (153.58,539.21) and (156.89,523.58)..(156.89,521.64)
+ ..controls (162,517.03) and (157.39,513.58)..(154.73,512.28)
+ ..controls (151.27,518.33) and (149.62,518.04)..(147.17,514.44)
+ ..controls (141.7,514.08) and (144.58,528.19)..(140.26,528.62)
+ ..controls (137.02,527.76) and (139.18,520.06)..(138.24,518.76)
+ ..controls (132.98,524.74) and (130.9,529.27)..(127.01,521.64)
+ ..controls (126.14,521.64) and (122.11,519.19)..(120.96,526.54)
+ ..controls (117.65,552.74) and (107.06,558.36)..(93.8198,565.13)
+ ..controls (92.0198,565.63) and (84.24,566.71)..(79.3398,568.15)
+ ..controls (73.5098,560.88) and (58.3198,565.63)..(56.23,570.31)
+ ..controls (54.7898,572.69) and (54.6499,575.21)..(54.7898,576.5)
+ ..controls (52.3398,580.1) and (55.8699,582.7)..(59.6199,583.06)
+ ..controls (62.8599,587.16) and (68.5398,594.94)..(71.2798,601.56)
+ ..controls (72.2898,603.07) and (74.95,609.34)..(78.1899,609.55)
+ ..controls (74.95,612.94) and (74.2998,622.51)..(82.6599,617.33)
+ ..controls (87.1199,624.02) and (92.0898,624.31)..(95.7598,615.82)
+ ..controls (102.89,615.38) and (102.31,608.69)..(115.78,605.52)
+ ..controls (122.76,602.86) and (132.77,604.58)..(140.26,603.72)
+ ..controls (136.22,596.88) and (127.44,566.86)..(132.98,559.8)
+ ..controls (140.76,564.7) and (141.84,605.38)..(157.03,595.66)
+ ..controls (160.56,593.93) and (159.91,590.04)..(164.09,590.18)
+ ..controls (170.42,587.45) and (169.13,600.77)..(172.51,600.77)
+ ..controls (176.47,599.76) and (183.02,599.04)..(186.98,599.54)
+ ..controls (197.71,600.77) and (206.93,604.08)..(223.92,602.5)
+ ..controls (231.12,601.78) and (238.25,601.06)..(245.45,600.34)
+ --cycle;
+endfig;
+end
+pstoedit: version 3.18 / DLL interface 106 (build May 1 2000) : Copyright (C) 1993 - 2000 Wolfgang Glunz
+Interpreter finished. Return status 0
diff --git a/doc/context/sources/general/manuals/metafun/mycow.pdf b/doc/context/sources/general/manuals/metafun/mycow.pdf
new file mode 100644
index 000000000..9cc8fb0b4
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/mycow.pdf
Binary files differ
diff --git a/doc/context/sources/general/manuals/metafun/somecow.pdf b/doc/context/sources/general/manuals/metafun/somecow.pdf
new file mode 100644
index 000000000..1a43087fd
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/somecow.pdf
Binary files differ
diff --git a/doc/context/sources/general/manuals/notnow/notnow-columns-and-notes.tex b/doc/context/sources/general/manuals/notnow/notnow-columns-and-notes.tex
new file mode 100644
index 000000000..336c39480
--- /dev/null
+++ b/doc/context/sources/general/manuals/notnow/notnow-columns-and-notes.tex
@@ -0,0 +1,26 @@
+\usemodule[art-01]
+
+\starttext
+
+ \samplefile{tufte}
+ \footnote{\samplefile{tufte}}
+
+ \startitemize[packed,columns]
+ \startitem one \stopitem
+ \startitem two \stopitem
+ \startitem three \footnote{A note (three).}
+ \stopitem
+ \startitem four \stopitem
+ \startitem five \stopitem
+ \startitem six \stopitem
+ \startitem seven \stopitem
+ \startitem eight \stopitem
+ \stopitemize
+
+ \dorecurse {10} {
+ \samplefile{ward}
+ \footnote{Another note #1!}
+ \par
+ }
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/notnow/notnow-sidefloats.tex b/doc/context/sources/general/manuals/notnow/notnow-sidefloats.tex
new file mode 100644
index 000000000..4a8a1ba3b
--- /dev/null
+++ b/doc/context/sources/general/manuals/notnow/notnow-sidefloats.tex
@@ -0,0 +1,59 @@
+\usemodule[art-01]
+
+\starttext
+
+\definefloat
+ [figure-column]
+
+\setupfloat
+ [figure-column]
+ [default={left,nonumber,none,high}, % high kills sidespacebefore
+ topoffset=\strutgap]
+
+\setupfloat
+ [sidespacebefore=,
+ sidespaceafter=]
+
+\enabletrackers[*float*]
+
+\starttext
+
+\input ward
+
+\placefloat
+ [figure-column][][]{}
+ {\externalfigure[t:/sources/cow.pdf][width=3cm,frame=on]}
+
+\input ward
+
+\placefloat
+ [figure-column][][]{}
+ {\externalfigure[t:/sources/cow.pdf][width=3cm,frame=on]}
+
+\input ward
+
+\placefloat
+ [figure-column][][]{}
+ {\externalfigure[t:/sources/cow.pdf][width=3cm,frame=on]}
+
+\flushsidefloats
+
+\input ward
+
+\page
+
+\setupfloat
+ [spacebeforeside=3*big,
+ spaceafterside=5*big]
+
+\input ward
+
+\placefloat
+ [figure-column][][]{}
+ {\externalfigure[t:/sources/cow.pdf][width=3cm,frame=on]}
+
+\flushsidefloats
+
+\input ward
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/notnow/notnow.tex b/doc/context/sources/general/manuals/notnow/notnow.tex
new file mode 100644
index 000000000..e1768db41
--- /dev/null
+++ b/doc/context/sources/general/manuals/notnow/notnow.tex
@@ -0,0 +1,175 @@
+% language=uk
+
+\usemodule[typesetting]
+
+\defineexternalfigure
+ [typesetting]
+ [frame=on,
+ framecolor=darkblue,
+ rulethickness=1pt]
+
+\setupcombination
+ [twopages]
+ [style=bold,
+ color=darkblue]
+
+\setupbodyfont
+ [ebgaramond,14.4pt]
+
+\setuphead
+ [chapter]
+ [style=\bfc,
+ header=empty,
+ color=darkblue]
+
+\setuplist
+ [chapter]
+ [alternative=c,
+ width=1.5em]
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ topspace=15mm,
+ backspace=15mm,
+ header=15mm,
+ footer=0mm]
+
+\setupwhitespace
+ [big]
+
+\setuptype
+ [color=darkblue]
+
+\setuptyping
+ [color=darkblue]
+
+\setuppagenumbering
+ [alternative=doublesided]
+
+% \showframe
+
+\startdocument[author=Hans Hagen]
+
+\definefont[NotNow][Serif*default @ 18pt]%
+\definefont[NotNot][Serif*default @ 2.5pt]%
+
+\startpagemakeup[pagestate=stop]
+ \scale[width=\paperwidth,height=\paperheight] \bgroup
+ \bTABLE[strut=no,height=29.7pt,width=21pt,align={lohi,middle},foregroundcolor=white,framecolor=white,background=color]
+ \bTR
+ \bTD[backgroundcolor=darkblue] \NotNow W \eTD
+ \bTD[backgroundcolor=darkgray] \NotNow H \eTD
+ \bTD[backgroundcolor=darkblue] \NotNow Y \eTD
+ \eTR
+ \bTR
+ \bTD[backgroundcolor=darkgray] \NotNow N \eTD
+ \bTD[backgroundcolor=darkblue] \NotNow O \eTD
+ \bTD[backgroundcolor=darkgray] \NotNow T \eTD
+ \eTR
+ \bTR
+ \bTD[backgroundcolor=darkblue] \NotNow N \eTD
+ \bTD[backgroundcolor=darkgray] \NotNow O \eTD
+ \bTD[backgroundcolor=darkblue] \NotNow W \eTD
+ \eTR
+ \eTABLE
+ \egroup
+\stoppagemakeup
+
+\starttitle[title=Contents]
+
+ \placelist[chapter]
+
+\stoptitle
+
+\startchapter[title=Introduction]
+
+You can do a lot in \CONTEXT\ but for sure there are limitations too. There are
+quite some sub|-|mechanisms and sometimes there are more solutions for one
+problem. For instance, we have several table mechanisms and several
+multi|-|column mechanisms. In this document we will collect information about
+what doesn't work (well) and if possible indicate why. Feel free to submit more
+items. We will also discuss features that do work in most cases but are somewhat
+unreliable.
+
+Does that mean that we cannot make everything work? No, sometimes demands are too
+conflicting. Yes, we can implement more, but it simply doesn't pay off to spend
+time on writing code that is used seldom. Keep in mind that much of \CONTEXT\ is
+written in spare time without any compensation. Publishers have demands but
+seldom are willing to pay for it. Users have demands and no means to pay for it.
+On the other hand, user demands often have challenging properties that trigger
+development. Sometimes a project has as side effect that some mechanism become
+better.
+
+The good news that one can often work around it. Not all typesetting has to be
+fully automatic. And there are always reasonable typographic alternatives. The
+examples shown here can be run on your machine.
+
+\stopchapter
+
+\startchapter[title=Columns and notes]
+
+Because \TEX\ doesn't really support columns we need to cook up some magic to
+achieve them. Especially a mix between single and multi|-|columns is sort of
+tricky. Because notes are inserts and inserts play a role in determining the
+optimal breakpoints they can interfere badly, depending on the mechanism used. In
+\CONTEXT\ we use mixed columns for multi|-|column itemizations and as these can
+have footnotes you can end up in troubles.
+
+\typefile{notnow-columns-and-notes.tex}
+
+In such case the notes are postponed and flushed {\em after} the itemized list so
+they can end up on a next page. If this happens depends on how much room there is
+on the page. Solutions are possible (and the old \MKII\ column handler might
+behave better in some cases) but it's not worth the trouble to complicate the
+already complex code more than needed. Also, it will never be perfect anyway.
+
+\FirstPages{notnow-columns-and-notes}
+
+\stopchapter
+
+\startpagemakeup[pagestate=stop,page=left,doublesided=no]
+ \scale[width=\paperwidth,height=\paperheight] \bgroup
+ \bTABLE[strut=no,height=29.7pt,width=21pt,align={lohi,middle},foregroundcolor=white,framecolor=white,background=color]
+ \bTR
+ \bTD[backgroundcolor=darkblue] \eTD
+ \bTD[backgroundcolor=darkgray] \eTD
+ \bTD[backgroundcolor=darkblue] \eTD
+ \eTR
+ \bTR
+ \bTD[backgroundcolor=darkgray] \eTD
+ \bTD[backgroundcolor=darkblue] \eTD
+ \bTD[backgroundcolor=darkgray] \eTD
+ \eTR
+ \bTR
+ \bTD[backgroundcolor=darkblue] \eTD
+ \bTD[backgroundcolor=darkgray] \eTD
+ \bTD[backgroundcolor=darkblue,foregroundstyle=\NotNot]
+ Hans Hagen \vfilll PRAGMA ADE \vfilll Hasselt NL
+ \eTD
+ \eTR
+ \eTABLE
+ \egroup
+\stoppagemakeup
+
+\startchapter[title=Sidefloats]
+
+Support for side floats is non|-|trivial and no solution will serve all intended
+usage. Over the years we have improved on border cases but it is still not
+perfect. For that reason the implementation is (apart from solving bugs, mostly) frozen.
+Here is an example of a use case that we ran into. We manipulate the spacing with
+an offset parameter.
+
+\typefile{notnow-sidefloats.tex}
+
+You can best play with these parameters and see what they do. If you use this
+mechanism in a long term project, use a frozen instance of \CONTEXT !
+
+\TwoPages{notnow-sidefloats}
+
+The second pages has preceding and trailing whitespace outside the sidefloat
+flow.
+
+\stopchapter
+
+\stopdocument
diff --git a/doc/context/sources/general/manuals/onandon/m-fonts-plugins-timings-luajittex.lua b/doc/context/sources/general/manuals/onandon/m-fonts-plugins-timings-luajittex.lua
new file mode 100644
index 000000000..2bc4e0371
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/m-fonts-plugins-timings-luajittex.lua
@@ -0,0 +1,90 @@
+return {
+ ["engine"]="luajittex",
+ ["timings"]={
+ ["arabic"]={
+ ["list"]={ "arabtype", "husayni" },
+ ["results"]={
+ ["arabtype"]={
+ ["context base"]=0.32,
+ ["context node"]=7.167,
+ ["context none"]=0.322,
+ ["harfbuzz native"]=4.631,
+ ["harfbuzz uniscribe"]=4.67,
+ },
+ ["husayni"]={
+ ["context base"]=0.35,
+ ["context node"]=12.251,
+ ["context none"]=0.351,
+ ["harfbuzz native"]=15.279,
+ ["harfbuzz uniscribe"]=15.253,
+ },
+ },
+ },
+ ["latin"]={
+ ["list"]={ "modern", "pagella", "dejavu", "cambria", "ebgaramond", "lucidaot" },
+ ["results"]={
+ ["cambria"]={
+ ["context base"]=0.384,
+ ["context node"]=1.17,
+ ["context none"]=0.366,
+ ["harfbuzz native"]=2.907,
+ ["harfbuzz uniscribe"]=2.863,
+ },
+ ["dejavu"]={
+ ["context base"]=0.399,
+ ["context node"]=0.985,
+ ["context none"]=0.364,
+ ["harfbuzz native"]=3.02,
+ ["harfbuzz uniscribe"]=2.968,
+ },
+ ["ebgaramond"]={
+ ["context base"]=0.43,
+ ["context node"]=1.323,
+ ["context none"]=0.383,
+ ["harfbuzz native"]=2.999,
+ ["harfbuzz uniscribe"]=2.983,
+ },
+ ["lucidaot"]={
+ ["context base"]=0.414,
+ ["context node"]=0.626,
+ ["context none"]=0.422,
+ ["harfbuzz native"]=2.606,
+ ["harfbuzz uniscribe"]=2.594,
+ },
+ ["modern"]={
+ ["context base"]=0.418,
+ ["context node"]=0.773,
+ ["context none"]=0.383,
+ ["harfbuzz native"]=3.074,
+ ["harfbuzz uniscribe"]=3.049,
+ },
+ ["pagella"]={
+ ["context base"]=0.436,
+ ["context node"]=0.803,
+ ["context none"]=0.416,
+ ["harfbuzz native"]=3.024,
+ ["harfbuzz uniscribe"]=3.006,
+ },
+ },
+ },
+ ["mixed"]={
+ ["list"]={ "arabtype", "husayni" },
+ ["results"]={
+ ["arabtype"]={
+ ["context base"]=0.572,
+ ["context node"]=4.039,
+ ["context none"]=0.602,
+ ["harfbuzz native"]=3.69,
+ ["harfbuzz uniscribe"]=3.686,
+ },
+ ["husayni"]={
+ ["context base"]=0.617,
+ ["context node"]=5.943,
+ ["context none"]=0.575,
+ ["harfbuzz native"]=7.193,
+ ["harfbuzz uniscribe"]=7.109,
+ },
+ },
+ },
+ },
+} \ No newline at end of file
diff --git a/doc/context/sources/general/manuals/onandon/m-fonts-plugins-timings-luatex.lua b/doc/context/sources/general/manuals/onandon/m-fonts-plugins-timings-luatex.lua
new file mode 100644
index 000000000..59606554d
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/m-fonts-plugins-timings-luatex.lua
@@ -0,0 +1,90 @@
+return {
+ ["engine"]="luatex",
+ ["timings"]={
+ ["arabic"]={
+ ["list"]={ "arabtype", "husayni" },
+ ["results"]={
+ ["arabtype"]={
+ ["context base"]=0.416,
+ ["context node"]=15.168,
+ ["context none"]=0.412,
+ ["harfbuzz native"]=7.144,
+ ["harfbuzz uniscribe"]=7.679,
+ },
+ ["husayni"]={
+ ["context base"]=0.449,
+ ["context node"]=26.076,
+ ["context none"]=0.459,
+ ["harfbuzz native"]=10.498,
+ ["harfbuzz uniscribe"]=18.958,
+ },
+ },
+ },
+ ["latin"]={
+ ["list"]={ "modern", "pagella", "dejavu", "cambria", "ebgaramond", "lucidaot" },
+ ["results"]={
+ ["cambria"]={
+ ["context base"]=0.444,
+ ["context node"]=2.114,
+ ["context none"]=0.426,
+ ["harfbuzz native"]=4.587,
+ ["harfbuzz uniscribe"]=5.026,
+ },
+ ["dejavu"]={
+ ["context base"]=0.464,
+ ["context node"]=1.676,
+ ["context none"]=0.426,
+ ["harfbuzz native"]=4.495,
+ ["harfbuzz uniscribe"]=4.792,
+ },
+ ["ebgaramond"]={
+ ["context base"]=0.497,
+ ["context node"]=2.356,
+ ["context none"]=0.433,
+ ["harfbuzz native"]=4.957,
+ ["harfbuzz uniscribe"]=5.169,
+ },
+ ["lucidaot"]={
+ ["context base"]=0.481,
+ ["context node"]=0.926,
+ ["context none"]=0.474,
+ ["harfbuzz native"]=4.28,
+ ["harfbuzz uniscribe"]=4.685,
+ },
+ ["modern"]={
+ ["context base"]=0.477,
+ ["context node"]=1.227,
+ ["context none"]=0.439,
+ ["harfbuzz native"]=5.057,
+ ["harfbuzz uniscribe"]=5.243,
+ },
+ ["pagella"]={
+ ["context base"]=0.502,
+ ["context node"]=1.273,
+ ["context none"]=0.469,
+ ["harfbuzz native"]=4.958,
+ ["harfbuzz uniscribe"]=5.489,
+ },
+ },
+ },
+ ["mixed"]={
+ ["list"]={ "arabtype", "husayni" },
+ ["results"]={
+ ["arabtype"]={
+ ["context base"]=0.678,
+ ["context node"]=7.854,
+ ["context none"]=0.687,
+ ["harfbuzz native"]=5.822,
+ ["harfbuzz uniscribe"]=6.214,
+ },
+ ["husayni"]={
+ ["context base"]=0.724,
+ ["context node"]=11.922,
+ ["context none"]=0.674,
+ ["harfbuzz native"]=6.929,
+ ["harfbuzz uniscribe"]=9.851,
+ },
+ },
+ },
+ },
+} \ No newline at end of file
diff --git a/doc/context/sources/general/manuals/onandon/onandon-decade.tex b/doc/context/sources/general/manuals/onandon/onandon-decade.tex
new file mode 100644
index 000000000..890668a5c
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-decade.tex
@@ -0,0 +1,90 @@
+% language=uk
+
+\startcomponent onandon-decade
+
+\environment onandon-environment
+
+\startchapter[title=The first decade]
+
+When writing this it's hard to believe that we're already a decade working on
+\LUATEX\ and about the same time on \MKIV. The question is, did we achieve the
+objectives? The answer can easily be \quotation {yes} because we didn't start
+with objectives, just with some experiments with a \LUA\ extension interface.
+However, it quickly became clear that this was the way to go. Already in an early
+stage we took a stand in what direction we had to move.
+
+How did we end up with \LUA\ and not one of the other popular scripting
+languages? The \CONTEXT\ macro package always came with a runner. Not only did
+the runner manage the (often) multiple runs, it also took care of sorting the
+index and other inter|-|job activities. Additional helpers were written for
+installing fonts, managing (and converting) images, job control, etc. First they
+were binaries (written in \MODULA\ 2), but successive implementations used \PERL\
+and \RUBY. When I found out that the \SCITE\ editor I switched to had an
+extension mechanism using \LUA, I immediately liked that language. It's clean,
+not bloated, relatively stable, evolves in an academic environment and is not
+driven by commerce and|/|or short term success, and above all, the syntax makes
+the code look good. So, it was the most natural candidate for extending \TEX.
+
+Already for along time, \TEX\ is a stable program and whatever we do with it, we
+should not break it. There has been frontend extensions, like \ETEX, and backend
+extensions, like \PDFTEX, and experiments like \OMEGA\ and \ALEPH\ and we could
+start from there. So, basically we took \PDFTEX, after all, that was what we used
+for the first experiments, and merged some \ALEPH\ directional code in it. A
+tremendous effort was undertaken (thanks to funding by the Oriental \TEX\
+project) to convert the code base from \PASCAL\ to~\CCODE.
+
+It is hard to get an agreement over what needs to be added and it's a real waste
+of time to enter that route by endless discussions: every \TEX\ user has
+different demands and macro packages differ in philosophy . So, in the spirit of
+the extension language \LUA\ we stuck to concept of \quotation {If you want it
+better, write it in \LUA}. As a consequence we had to provide access to the
+internals with efficient and convenient methods, something that happened
+stepwise. We did extend the engine with a few features that make live easier but
+tried to limit ourselves. On the other hand, due to developments with fonts and
+languages we generalized these concepts so that extending and controlling them is
+easier. And, due to developments in math font technology we also added
+alternative code paths to the math renderer.
+
+All these matters have been presented and discussed at meetings, in user group
+journals and in documents that are part of the \CONTEXT\ suite. And during this
+decade the \CONTEXT\ users have been patient testers of whatever we threw at them
+in the \MKIV\ version of this macro package.
+
+It's kind of interesting to note that in the \TEX\ community it takes a while
+before version 1 of programs becomes available. Some programs never (seem to)
+reach that state. However, for us version 1.0 marks the moment that we consider
+the interfaces to be stable. Of course we move on so a version 2.0 can divert and
+provide more or even less interfaces, provide new functionality or drop obsolete
+features. The intermediate versions (up to version one) were always quite useable
+in production. In 2005 the first prototype of \LUATEX\ was demonstrated at the
+\TUG\ conference, and in 2007 at the \TUG\ conference we had a whole day on
+\LUATEX. At that time \CONTEXT\ \MKIV\ evolved fast and we already had decent
+\OPENTYPE\ support as part of the oriental \TEX\ project. It was in those years
+that the major reorganization of the code base took place but in successive years
+many subsystems were opened and cleaned up. There were some occasions where an
+interface was changed for the better but adapting was not that hard. It might
+have helped that much of \CONTEXT\ \MKIV\ is written in \LUA. What also helped is
+that most \CONTEXT\ users quickly switched to \MKIV, if only because \MKII\ was
+frozen. And, thanks to those users, we were able to root out bugs and
+bottlenecks. It was interesting to see that the approach of mixing \TEX,
+\METAPOST\ and \LUA\ catched on quite well.
+
+By the end of September 2016, at the 10\high{th} \CONTEXT\ meeting we released
+what we call the first long term stable version of \LUATEX. This version performs
+quite well but we might still add a few things here and there and the code will be
+further cleaned up and documented. In the meantime \LUATEX\ is also used in other
+macro packages. It will not replace \PDFTEX\ (at least not soon) because that
+engine does the job for most of the publications done in \TEX: articles. As they
+are mostly in English and use traditional fonts, there is no need to switch to
+the more flexible but somewhat slower \LUATEX. In a similar fashion \XETEX\
+serves those who want the benefits of \PDFTEX, hard|-|coded font support and
+token juggling at the \TEX\ level. We will support those engines with \MKII\ but
+as mentioned, we will not develop new code for. We strongly advice \CONTEXT\ users
+to use \LUATEX\ but there the advertisements stop. Personally I haven't used
+\PDFTEX\ (which made \TEX\ survive in the evolving world of electronic documents)
+for a decade and I never really used \XETEX\ (which opened up the \TEX\ world to
+modern fonts). At least for the coming decade I hope that \LUATEX\ can serve us well.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/onandon/onandon-editing.tex b/doc/context/sources/general/manuals/onandon/onandon-editing.tex
new file mode 100644
index 000000000..c8482397e
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-editing.tex
@@ -0,0 +1,393 @@
+% language=uk
+
+\startcomponent onandon-editing
+
+\environment onandon-environment
+
+\startchapter[title=Editing]
+
+\startsection[title=Introduction]
+
+% This introduction is similar to the workflows chapter.
+
+Some users like the synctex feature that is built in the \TEX\ engines.
+Personally I never use it because it doesn't work well with the kind of documents
+I maintain. If you have one document source, and don't shuffle around (reuse)
+text too much it probably works out okay but that is not our practice. Here I
+will describe how you can enable a more \CONTEXT\ specific synctex support so
+that aware \PDF\ viewers can bring you back to the source.
+
+\stopsection
+
+\startsection[title={The premise}]
+
+Most of the time we provide our customers with an authoring workflow consisting
+of:
+
+\startitemize[packed]
+ \startitem the typesetting engine \CONTEXT \stopitem
+ \startitem the styles to generate the desired \PDF\ files \stopitem
+ \startitem the text editor \SCITE \stopitem
+ \startitem the \SUMATRAPDF\ viewer \stopitem
+\stopitemize
+
+For the \MATHML\ we advice the \MATHTYPE\ editor and we provide them with a
+customized \MATHML\ translator for the copy & paste actions. When \ASCIIMATH\ is
+used to code math no special tools are needed.
+
+What people operate this workflow? Sometimes it's an author, but most of the time
+they are editors with a background in copy|-|editing. We call them \XML\ editors,
+because they are maintaining the large (sets of) \XML\ documents and edit
+directly in the \XML\ sources.
+
+Maybe you'll ask yourself \quotation {Can they do that? Can they edit directly in
+the \XML\ resource?} The answer is yes, because after they have hit the
+processing key they are rewarded with a publishable \PDF\ document in a demanding
+layout.
+
+The \XML\ sources have a dual purpose. They form the basis for:
+
+\startitemize[packed]
+ \startitem
+ all folio products that are generated in \XML\ to \PDF\ workflow(s)
+ \stopitem
+ \startitem
+ the digital web product(s)
+ \stopitem
+\stopitemize
+
+The \XML\ editors do their proofing chapter|-|wise. Sometimes a chapter is one
+big \XML\ file (10.000 lines is no exception when the chapter contains hundreds
+of bloated \MATHML\ snippets). In other projects they have to deal with chapters
+that are made up of hundreds (100 upto 500) of smaller \XML\ files.
+
+\stopsection
+
+\startsection[title={The problem}]
+
+Let's keep it simple: there's a typo. Here's what an \XML\ editor will do:
+
+\startitemize[packed]
+ \startitem
+ start \SCITE
+ \stopitem
+ \startitem
+ open a file
+ \stopitem
+ \startitem
+ correct the typo
+ \stopitem
+ \startitem
+ generate the \PDF
+ \stopitem
+ \startitem
+ proof the \PDF\ and see if his alteration has some undesired side
+ effects like text flow of image floating
+ \stopitem
+\stopitemize
+
+So far so good. When the editor dealing with one big \XML\ file there's no
+problem. Hopefully the filename will indicate the specific chapter. He or she
+opens the file and searches for the typo. And then correction happens. But what
+if there are hundreds of small \XML\ files. How does the editor know in which
+file the typo can be found?
+
+First, let's give a few statistics based on two projects that are in a revision
+stage.
+
+\starttabulate[|c|c|c|c|]
+\HL
+\NC
+ project \NC
+ chapters \NC
+ \# of files \NC
+ average \# of lines \NC \NR
+\HL
+\NC
+ A \NC
+ 16 \NC
+ 16 \NC
+ 11000 \NC \NR
+\NC
+ B \NC
+ 132 \NC
+ 16000\footnote{132 chapters consisting of $\pm 120$ files.} \NC
+ 100 \NC \NR
+\HL
+\stoptabulate
+
+The \XML\ resource passes three stages: a raw, a semi final and a final version.
+The raw \XML\ version originates from a web authoring tool that is used by the
+author. Then the \PDF\ is proofread and the \XML\ editor goes to work.
+
+\starttabulate[|l|c|c|]
+\HL
+\NC
+ workflow \NC
+ \# edit locations and adaptations \NC
+ \# runs\footnote {Maybe you can now see why we put quite some effort in
+ keeping \CONTEXT\ working at a comfortable speed.} \NC \NR
+\HL
+\NC
+ raw to semifinal \NC
+ 75 \NC
+ 105 \NC \NR
+\NC
+ semifinal to final \NC
+ 35 \NC
+ 55 \NC \NR
+\HL
+\stoptabulate
+
+Keep in mind that altering text may cause text to flow and images to float in a
+way that an \XML\ editor will have to finetune and needs multiple runs for one
+correction.
+
+Just to give an idea of the work involved. A typical semi final needs some 50
+runs where each run takes 20 seconds (assuming 3 runs to get all cross
+referencing right). The numbers of explicit pagebreaks is about 5, and (related
+to formulas) explicit linebreaks around 8. It takes some 2 hours to get
+everything right, which includes checking in detail, fixing some things and if
+needed moving content a bit around.
+
+Now we broaden the earlier question into: how can we make the work of an \XML\
+editor as easy and efficient as possible?
+
+\stopsection
+
+\startsection[title={Enhancing efficiency}]
+
+Since it is easier to proof content for folio and web via PDF documents we
+generate proof \PDF\ files in which the complete content is shown. The proof can
+be a massive document. A normal 40 page chapter can explode to 140 pages
+visualizing all the content that is coded in the \XML\ file(s).
+
+The content in the proof is shown in an effective way and a functional order.
+Let's give a few examples of how we enhance the \XML\ editors effectiveness:
+
+\startitemize[packed]
+
+\startitem
+ By default the proof \PDF\ file is interactive which serves testing the tocs
+ and the register.
+\stopitem
+\startitem
+ The web hyperlinks are active so their destinatation can be tested.
+\stopitem
+\startitem
+ The questions and their answers are displayed in eachothers proximity. This
+ sounds logical but in folio they are two seperate products (theory and
+ answer books).
+\stopitem
+\startitem
+ Medium specific content (web or folio) is typographically highligthed. For
+ example by colored backgrounds.
+\stopitem
+\startitem
+ When spelling mode is on the \XML\ editor can easily pick out the colored
+ misspelled words.
+\stopitem
+\startitem
+ Images can be active areas although this is of no interest to \XML\ editors.
+ Clicking the image results in opening the image file in its corresponding
+ application for maintenance.
+\stopitem
+\startitem
+ For practical reasons the filenames and paths of the \XML\ files are
+ displayed. The filenames are active links and clicking them results in
+ opening the destination \XML\ file in \SCITE.
+\stopitem
+\stopitemize
+
+Okay. The last option is a nice feature. However, the destination file is opened
+at the top of the file and you still have to find the typo or whatever
+incorrect issue you are looking for.
+
+So a further enhancement in efficiency would be to jump to the typo's
+corresponding line in the \XML\ source. This is where \SYNCTEX\ comes into view.
+This feature, present in the \TEX\ engines, provides a way to go from \PDF\ to
+source by using a secondary file with positions. Unfortunately that mechanism is
+hardly useable for \CONTEXT\ because it assumes a page and file handling model
+different from what we use. However, as \CONTEXT\ uses \LUATEX, it can also
+provide it's own alternative.
+
+\stopsection
+
+% The rest is similar to the workflows chapter.
+
+\startsection[title=What we want]
+
+The \SYNCTEX\ method roughly works as follows. Internally \TEX\ constricts linked
+lists of glyphs, kerns, glue, boxes, rules etc. These elements are called nodes.
+Some nodes carry information about the file and line where they were created. In
+the backend this information gets somehow translated in a (sort of) verbose tree
+that describes the makeup in terms of boxes, glue and kerns. From that
+information the \SYNCTEX\ parser library, hooked into a \PDF\ viewer, can go back
+from a position on the screen to a line in a file. One would expect this to be a
+relative simple rectangle based model, but as far as I can see it's way more
+complex than that. There are some comments that \CONTEXT\ is not supported well
+because it has a layered page model, which indicates that there are some
+assumptions about how macro packages are supposed to work. Also the used
+heuristics not only involve some specific spot (location) but also involve the
+corners and edges. It is therefore not so much a (simple) generic system but a
+mechanism geared for a macro package like \LATEX.
+
+Because we have a couple of users who need to edit complex sets of documents,
+coded in \TEX\ or \XML, I decided to come up with a variant that doesn't use the
+\SYNCTEX\ machinery but manipulates the few \SYNCTEX\ fields directly \footnote {This
+is something that in my opinion should have been possible right from the start
+but it's too late now to change the system and it would not be used beyond
+\CONTEXT\ anyway.} and eventually outputs a straightforward file for the editor.
+Of course we need to follow some rules so that the editor can deal with it. It
+took a bit of trial and error to get the right information in the support file
+needed by the viewer but we got there.
+
+The prerequisites of a decent \CONTEXT\ \quotation {click on preview and goto
+editor} are the following:
+
+\startitemize
+
+\startitem
+ It only makes sense to click on text in the text flow. Headers and footers
+ are often generated from structure, and special typographic elements can
+ originate in macros hooked into commands instead of in the source.
+\stopitem
+
+\startitem
+ Users should not be able to reach environments (styles) and other files
+ loaded from the (normally read|-|only) \TEX\ tree, like modules. We don't
+ want accidental changes in such files.
+\stopitem
+
+\startitem
+ We not only have \TEX\ files but also \XML\ files and these can normally
+ flush in rather arbitrary ways. Although the concept of lines is sort of
+ lost in such a file, there is still a relation between lines and the snippets
+ that make out the content of an \XML\ node.
+\stopitem
+
+\startitem
+ In the case of \XML\ files the overhead related to preserving line
+ numbers should be minimal and have no impact on loading and memory when
+ these features are not used.
+\stopitem
+
+\startitem
+ The overhead in terms of an auxiliary file size and complexity as well
+ as producing that file should be minimal. It should be easy to turn on and
+ off these features. (I'd never turn them on by default.)
+\stopitem
+
+\stopitemize
+
+It is unavoidable that we get more run time but I assume that for the average user
+that is no big deal. It pays off when you have a workflow when a book (or even a
+chapter in a book) is generated from hundreds of small \XML\ files. There is no
+overhead when \SYNCTEX\ is not used.
+
+In \CONTEXT\ we don't use the built|-|in \SYNCTEX\ features, that is: we let
+filename and line numbers be set but often these are overloaded explicitly. The
+output file is not compressed and constructed by \CONTEXT. There is no benefit in
+compression and the files are probably smaller than default \SYNCTEX\ anyway.
+
+\stopsection
+
+\startsection[title=Commands]
+
+Although you can enable this mechanism with directives it makes sense to do it
+using the following command.
+
+\starttyping
+\setupsynctex[state=start]
+\stoptyping
+
+The advantage of using an explicit command instead of some command line option is
+that in an editor it's easier to disable this trickery. Commenting that line will
+speed up processing when needed. This command can also be given in an environment
+(style). On the command line you can say
+
+\starttyping
+context --synctex somefile.tex
+\stoptyping
+
+A third method is to put this at the top of your file:
+
+\starttyping
+% synctex=yes
+\stoptyping
+
+Often an \XML\ files is very structured and although probably the main body of
+text is flushed as a stream, specific elements can be flushed out of order. In
+educational documents flushing for instance answers to exercises can happen out of
+order. In that case we still need to make sure that we go to the right spot in
+the file. It will never be 100\% perfect but it's better than nothing. The
+above command will also enable \XML\ support.
+
+If you don't want a file to be accessed, you can block it:
+
+\starttyping
+\blocksynctexfile[foo.tex]
+\stoptyping
+
+Of course you need to configure the viewer to respond to the request for
+editing. In Sumatra combined with SciTE the magic command is:
+
+\starttyping
+c:\data\system\scite\wscite\scite.exe "%f" "-goto:%l"
+\stoptyping
+
+Such a command is independent of the macro package so you can just consult the
+manual or help info that comes with a viewer, given that it supports this linking
+back to the source at all.
+
+If you enable tracing (see next section) you can what has become clickable.
+Instead of words you can also work with ranges, which not only gives less runtime
+but also much smaller \type {.synctex} files. Use
+
+\starttyping
+\setupsynctex[state=start,method=min]
+\stoptyping
+
+to get words clickable and
+
+\starttyping
+\setupsynctex[state=start,method=max]
+\stoptyping
+
+if you want somewhat more efficient ranges. The overhead for \type {min} is about
+10 percent while \type {max} slows down around 5 percent.
+
+\stopsection
+
+\startsection[title=Tracing]
+
+In case you want to see what gets synced you can enable a tracker:
+
+\starttyping
+\enabletrackers[system.synctex.visualize]
+\enabletrackers[system.synctex.visualize=real]
+\stoptyping
+
+The following tracker outputs some status information about \XML\ flushing. Such
+trackers only make sense for developers.
+
+\starttyping
+\enabletrackers[system.synctex.xml]
+\stoptyping
+
+\stopsection
+
+\startsection[title=Warning]
+
+Don't turn on this feature when you don't need it. This is one of those mechanism
+that hits performance badly.
+
+Depending on needs the functionality can be improved and|/|or extended. Of course
+you can always use the traditional \SYNCTEX\ method but don't expect it to behave
+as described here.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/onandon/onandon-emoji.tex b/doc/context/sources/general/manuals/onandon/onandon-emoji.tex
new file mode 100644
index 000000000..1f67cc528
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-emoji.tex
@@ -0,0 +1,457 @@
+% language=uk
+
+\usemodule[fonts-emoji]
+
+\environment onandon-environment
+
+% \definefont[MyEmoji][emojionecolor-svginot*default,svg]
+% \definefont[MyEmoji][seguiemj*seguiemj-bw]
+% \definefont[MyEmoji][emojionemozilla*default,overlay]
+% \definefont[MyEmoji][applecoloremoji*default,bitmap]
+
+\definefontfeature[seguiemj-cl][default][colr=yes,ccmp=yes,dist=yes]
+\definefontfeature[seguiemj-bw][default][ccmp=yes,dist=yes]
+
+\definefont[MyEmoji] [seguiemj*seguiemj-cl]
+\definefont[MyEmojiLarge][seguiemj*seguiemj-cl @ 100pt]
+
+\definefontsynonym[emoji][seguiemj*seguiemj-cl]
+
+\startcomponent onandon-emoji
+
+\startchapter[title=Emoji again]
+
+Because at the \CONTEXT\ 2016 meeting color fonts \footnote {For that occasion
+the cowfont, a practical joke concerning Dutch \quote {koeieletters}, were turned
+into a color font and presented at the meeting.} were on the agenda, some time
+was spent on emoji (these colorful small picture glyphs). When possible I bring
+kids to the Bacho\TEX\ conference so for the 2017 BachoTUG I decided to do
+something with emoji that, after all, are mostly used by those younger than I am.
+So, I had to take a look at the current state. Here are some observations.
+
+The \UNICODE\ standard defines a whole lot of emoji and if mankind manages to
+survive for a while one can assume that a lot more will be added. After all,
+icons as well as variants keep evolving. There are several ways to organize these
+symbols in groups but I will not give grouping a try. Just visit \type
+{emojipedia.org} and you get served well. For this story I only mention that:
+
+\startitemize
+ \startitem
+ There are quite some shapes and nearly all of them are in color. The
+ yellow ones, smilies and such, are quite prominently present but there
+ are many more.
+ \stopitem
+ \startitem
+ A special subset is fulled by persons: man, woman, girl, boy and recently
+ a baby.
+ \stopitem
+ \startitem
+ The grown ups can be combined in loving couples (either or not kissing)
+ and then can form families, but only upto 2 young kids or gender neutral
+ babies.
+ \stopitem
+ \startitem
+ All persons can be flagged with one of five skin tones so that not all
+ persons (or heads) look bright yellow.
+ \stopitem
+ \startitem
+ Interesting is that girls and boys are still fond of magenta (pinkish)
+ and cyan (blueish) cloths and ornaments. Also haircuts are rather
+ specific to the gender.
+ \stopitem
+\stopitemize
+
+For rendering color emojis we have a few color related \OPENTYPE\ font properties
+available: bitmaps, \SVG\, and stacked glyphs. Now, if you think of the
+combinations that can be made with skin tones, you realize that fonts can become
+pretty large if each combination results in a glyph. In the first half of 2017
+\MICROSOFT\ released an update for its emoji font and the company took the
+challenge to provide not only mixed skin tone couples, but also supported skin
+tones for the kids, including a baby.
+
+This recent addition already adds over 25.000 additional glyphs \footnote {That
+is the amount I counted when I added all combinations runtime but the emojipedia
+mentions twice that amount. Currently in \CONTEXT\ we resolve such combinations
+when requested.} so imagine what will happen in the future. But, instead of
+making a picture for each variant, a different solution has been chosen. For
+coloring this seguiemj font uses the (very flexible) stacking technology: a color
+shape is an overlay of colored symbols. The colors are organized in pallets and
+it's no big deal to add additional pallets if needed. Instead of adding
+pre|-|composed shapes (as is needed with bitmaps and \SVG) snippets are used to
+build alternative glyphs and these can be combined into new shapes by
+substitution and positioning (for that kerns, mark anchoring and distance
+compensation is used).
+
+So, a family can be constructed of composed shapes (man, woman, etc) that each
+are composed of snippets (skull, hair, mouth, eyes). So, effectively a family of
+four is a bunch of maybe 25 small glyphs overlayed and colored. In \in {figure}
+[fig:emojisnippets] we see how a shape is constructed out of separate glyphs. \in
+{Figure} [fig:emojisnippetsoverlay] shows how they can be overlayed with colors
+(we use a dedicated color set).
+
+\startplacefigure[title={Emoji snippets.},reference=fig:emojisnippets]
+ \scale[width=\textwidth]{\framed[frame=off,offset=overlay,align=normal]\bgroup
+ \forgetall
+ \MyEmoji
+ \ShowEmojiSnippets
+ [family man light skin tone
+ woman dark skin tone
+ girl medium skin tone
+ boy medium skin tone]
+ \egroup}
+\stopplacefigure
+
+\startplacefigure[title={Emoji snippets overlayed.},reference=fig:emojisnippetsoverlay]
+ \scale[width=\textwidth]{\framed[frame=off,offset=overlay,align=normal]\bgroup
+ \forgetall
+ \MyEmoji
+ \ShowEmojiSnippetsOverlay
+ [family man light skin tone
+ woman dark skin tone
+ girl medium skin tone
+ boy medium skin tone]
+ \egroup}
+\stopplacefigure
+
+When a font supports it, a sequence of emoji can be turned into a more compact
+representation. In \in {figure} [fig:emojiskintones] we see how skin tones are
+applied in such combinations. \in {Figure} [fig:emojiglyphs] shows the small
+snippets.
+
+\startplacefigure[title={Emoji families and such with skin tones.},reference=fig:emojiskintones,location=page]
+ \startcombination[2*4]
+ {\ruledhbox{\MyEmojiLarge\resolvedemoji
+ {family man woman girl boy}}}
+ {family man woman girl boy}
+ {\ruledhbox{\MyEmojiLarge\resolvedemoji
+ {family woman girl boy}}}
+ {family woman girl boy}
+ {\ruledhbox{\MyEmojiLarge\resolvedemoji
+ {family woman woman girl boy}}}
+ {family woman woman girl boy}
+ {\ruledhbox{\MyEmojiLarge\resolvedemoji
+ {family man girl boy}}}
+ {family man girl boy}
+ {\ruledhbox{\MyEmojiLarge\resolvedemoji
+ {family
+ man dark skin tone
+ woman girl baby}}}
+ {family
+ man dark skin tone
+ woman girl baby}
+ {\ruledhbox{\MyEmojiLarge\resolvedemoji
+ {family
+ man light skin tone
+ woman light skin tone
+ girl dark skin tone}}}
+ {family
+ man light skin tone
+ woman light skin tone
+ girl dark skin tone}
+ {\ruledhbox{\MyEmojiLarge\resolvedemoji
+ {family woman girl boy}}}
+ {family woman girl boy}
+ {\ruledhbox{\MyEmojiLarge\resolvedemoji
+ {family
+ man light skin tone
+ woman dark skin tone
+ girl medium skin tone
+ boy medium skin tone}}}
+ {family
+ man light skin tone
+ woman dark skin tone
+ girl medium skin tone
+ boy medium skin tone}
+ \stopcombination
+\stopplacefigure
+
+\startplacefigure[title={Emoji glyphs.},reference=fig:emojiglyphs]
+ \scale[width=\textwidth]{\framed[frame=off,offset=overlay,align=normal]\bgroup
+ \forgetall
+ \MyEmoji
+ \ShowEmojiGlyphs
+ [family man light skin tone
+ woman dark skin tone
+ girl medium skin tone
+ boy medium skin tone]
+ \egroup}
+\stopplacefigure
+
+When we have to choose a font we need to take the following criteria into
+account:
+
+\startitemize
+\startitem
+ What is the quality of the shapes? For sure, outlines are best if you want to
+ scale too.
+\stopitem
+\startitem
+ How efficient is a shape constructed. In that respect a bitmap or \SVG\ image
+ is just one entity.
+\stopitem
+\startitem
+ How well can (semi) arbitrary combinations of emoji be provided. Here the
+ glyph approach wins.
+\stopitem
+\startitem
+ Are all skin colors for all human relates shapes supported? Actually it opens
+ the possibility for racist fonts.
+\stopitem
+\startitem
+ Are all reasonable combinations of persons supported? It looks like (depending
+ on time and version) kissing men or women can be missing, maybe because of
+ social political reasons.
+\stopitem
+\startitem
+ Are black and white shapes provided alongside color shapes.
+\stopitem
+\stopitemize
+
+Maybe an \SVG\ or bitmap image can have a lot of detail compared to a stacked
+glyph but, when we're just using pictographic representations, the later is the
+best choice.
+
+When I was playing a bit with the skin tone variants and other combinations that
+should result in some composed shape, I used the \UNICODE\ test files but I got
+the impression that there are some errors in the test suite, for instance with
+respect to modifiers. Maybe the fonts are just doing the wrong thing or maybe
+some implement these sequences a bit inconsistent. This will probably improve
+over time but the question is if we should intercept issues. I'm not in favour of
+this because it adds more and more fuzzy code that not only wastes cycles
+(energy) but is also a conceptual horror. So, when testing, imperfection has to
+be accepted for now. This is no big deal as until now no one ever asked for emoji
+support in \CONTEXT.
+
+When no combined shape is provided, the original sequence shows up. A side effect
+can be that zero|-|width|-| joiners and modifiers become visible. This depends on
+the fonts. Users probably don't care that much about it. Now how do we suppose
+that users enter these emoji (sequences) in a document source? One can imagine a
+pop up in the editor but \TEX ies are often using commands for special cases.
+
+We already showed some combined shapes. The reader might appreciate the outcome
+but getting there from the input takes a bit of work. For instance a two person
+\typ {man light skin tone woman medium skin tone girl medium-light skin tone baby
+medium-light skin tone} involves this:
+
+\blank
+\start
+ \setupalign[verytolerant]
+ \showotfcomposition
+ {seguiemj*seguiemj-cl}
+ {1}
+ {\resolvedemoji{family
+ man light skin tone
+ woman medium skin tone
+ girl medium-light skin tone
+ baby medium-light skin tone}}
+\stop
+\blank
+
+A black and white example is the following \type {family woman girl}:
+
+\blank
+\start
+ \setupalign[verytolerant]
+ \showotfcomposition
+ {seguiemj*seguiemj-bw}
+ {1}
+ {\resolvedemoji{family woman girl}}
+\stop
+\blank
+
+I will not show all emoji, just the subset that contains the word \type {woman}
+in the description. As you can see the persons in the sequences are separated by
+a zero|-|width|-|joiner. There are some curious ones, for instance a \typ {woman
+wearing turban} which in terms of \UNICODE\ input is a female combine with a
+turban wearing man becomes a beardless woman wearing a turban. Woman vampires and
+zombies are not supported so these are male properties.
+
+\startpacked
+ \MyEmoji
+ \ShowEmoji[woman]
+\stoppacked
+
+So what if you don't like these colors? Because we're dealing with \TEX\ you can
+assume that if there is some way around the fixed color sets, then it will be
+provided. So, when you use \CONTEXT, here is away to overload them:
+
+\startbuffer
+\definecolor[emoji-red] [r=.4]
+\definecolor[emoji-green] [g=.4]
+\definecolor[emoji-blue] [b=.4]
+\definecolor[emoji-yellow][r=.4,g=.4]
+\definecolor[emoji-gray] [s=1,t=.5,a=1]
+
+\definefontcolorpalette
+ [emoji-s]
+ [black,emoji-gray]
+
+\definefontcolorpalette
+ [emoji-r]
+ [emoji-red,emoji-gray]
+
+\definefontcolorpalette
+ [emoji-g]
+ [emoji-green,emoji-gray]
+
+\definefontcolorpalette
+ [emoji-b]
+ [emoji-blue,emoji-gray]
+
+\definefontcolorpalette
+ [emoji-y]
+ [emoji-yellow,emoji-gray]
+
+\definefontfeature[seguiemj-s][ccmp=yes,dist=yes,colr=emoji-s]
+\definefontfeature[seguiemj-r][ccmp=yes,dist=yes,colr=emoji-r]
+\definefontfeature[seguiemj-g][ccmp=yes,dist=yes,colr=emoji-g]
+\definefontfeature[seguiemj-b][ccmp=yes,dist=yes,colr=emoji-b]
+\definefontfeature[seguiemj-y][ccmp=yes,dist=yes,colr=emoji-y]
+
+\definefont[MyEmojiS][seguiemj*seguiemj-s]
+\definefont[MyEmojiR][seguiemj*seguiemj-r]
+\definefont[MyEmojiG][seguiemj*seguiemj-g]
+\definefont[MyEmojiB][seguiemj*seguiemj-b]
+\definefont[MyEmojiY][seguiemj*seguiemj-y]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startplacefigure[title={Overloading colors by plugging in a sequence of alternate colors.},reference=fig:emojioverload,location=page]
+\startcombination[4*6]
+ {\scale[height=.1\textheight]{\MyEmoji \resolvedemoji{triangular ruler}}} {}
+ {\scale[height=.1\textheight]{\MyEmoji \resolvedemoji{rabbit face}}} {}
+ {\scale[height=.1\textheight]{\MyEmoji \resolvedemoji{man}}} {}
+ {\scale[height=.1\textheight]{\MyEmoji \resolvedemoji{woman}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiR\resolvedemoji{triangular ruler}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiR\resolvedemoji{rabbit face}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiR\resolvedemoji{man}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiR\resolvedemoji{woman}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiG\resolvedemoji{triangular ruler}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiG\resolvedemoji{rabbit face}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiG\resolvedemoji{man}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiG\resolvedemoji{woman}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiB\resolvedemoji{triangular ruler}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiB\resolvedemoji{rabbit face}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiB\resolvedemoji{man}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiB\resolvedemoji{woman}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiY\resolvedemoji{triangular ruler}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiY\resolvedemoji{rabbit face}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiY\resolvedemoji{man}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiY\resolvedemoji{woman}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiS\resolvedemoji{triangular ruler}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiS\resolvedemoji{rabbit face}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiS\resolvedemoji{man}}} {}
+ {\scale[height=.1\textheight]{\MyEmojiS\resolvedemoji{woman}}} {}
+\stopcombination
+\vskip2ex % looks nicer
+\stopplacefigure
+
+In \in {figure} [fig:emojioverload] we see how this is applied. You can provide
+as many colors as needed but when you don't provide enough the last one is used.
+This way we get the overlayed transparent colors in the examples. By using
+transparency we don't obscure shapes.
+
+The emojipedia mentions \quotation {Asked about the design, \MICROSOFT\ told
+emojipedia that one of the reasons for the thick stroke was to allow each emoji
+to be easily read on any background color.} The first glyph in the stack seems to
+do the trick, so just make sure that it doesn't become white. And, before I read
+that remark, while preparing a presentation with a colored background, I had
+already noticed that using a background was no problem. This font definitely sets
+the standard.
+
+How do we know what colors are used? The next table shows the first color palette
+of seguiemj. There are quite some colors so defining your own definitely involved
+some studying.
+
+{\MyEmoji\ShowEmojiPalettes[1]}
+
+Normally special symbols are accessed in \CONTEXT\ with the \type {symbol}
+command where symbols are organized in symbol sets. This is a rather old
+mechanism and dates from the time that fonts were limited in coverage and symbols
+were collected in special fonts. The emoji are accessed by their own command:
+\type {\emoji}. The font used has the font synonym \type {emoji} so you need to
+set that one first:
+
+\starttyping
+\definefontsynonym[emoji][seguiemj*seguiemj-cl]
+\stoptyping
+
+Here is an example:
+
+\startbuffer
+\emoji{woman light skin tone}\quad
+\emoji{woman scientist}\quad
+{\bfd bigger \emoji{man health worker}}
+\stopbuffer
+
+\typebuffer
+
+or typeset: \getbuffer
+
+The emoji symbol scales with the normal running font. When you ask for a family
+with skin toned members the lookup can result in another match (or no match)
+because one never knows to what extend a font supports it.
+
+\starttabulate[|l|p|]
+\NC \type{\expandedemoji} \NC the sequence constructed from the given string \NC \NR
+\NC \type{\resolvedemoji} \NC a protected sequence constructed from the given string \NC \NR
+\NC \type{\checkedemoji } \NC an typeset sequence with unresolved modifiers and joiners removed \NC \NR
+\NC \type{\emoji} \NC a typeset resolved sequence using the \type {emoji} font synonym \NC \NR
+\NC \type{\robustemoji} \NC a typeset checked sequence using the \type {emoji} font synonym \NC \NR
+\stoptabulate
+
+In case you wonder how some of the details above were typeset, there is a module
+\type {fonts-emoji} that provides some helpers for introspection.
+
+\starttabulate[|l|p|]
+\NC \type {\ShowEmoji} \NC show all the emoji in the current font \NC \NR
+\NC \type {\ShowEmojiSnippets} \NC show the snippets of a given emoji \NC \NR
+\NC \type {\ShowEmojiSnippetsOverlay} \NC show the overlayed snippets of a given emoji \NC \NR
+\NC \type {\ShowEmojiGlyphs} \NC show the snippets of a typeset emoji \NC \NR
+\NC \type {\ShowEmojiPalettes} \NC show the color pallets in the current font \NC \NR
+\stoptabulate
+
+Examples of usage are:
+
+\starttyping
+\ShowEmojiSnippets[family man woman girl boy]
+\ShowEmojiGlyphs [family man woman baby girl]
+\ShowEmoji [^man]
+\ShowEmoji
+\ShowEmojiPalettes
+\ShowEmojiPalettes[1]
+\stoptyping
+
+A good source of information about emoji is the mentioned \type {emojipedia.org}
+website. There you find not only details about all these symbols but also has
+some history. It compares updates in fonts too. It mentions for instance that in
+the creative update of Windows 10, some persons grew beards in the seguiemj font
+and others lost an eye. Now, if you look at the snippets shown before, you can
+wonder if that eye is really gone. Maybe the color is wrong or the order of
+stacking is not right. I decided not to waste time looking into that.
+
+Another quote: \quotation {Support for color emoji presentation on \MSWINDOWS\ is
+limited. Many applications on \MSWINDOWS\ display emojis with a black and white
+text presentation instead of their color version.} Well, we can do better with
+\TEX, but as usual not that many people really cares about that. But it's fun
+anyway.
+
+We end with a warning. When you use \quote {ligatures} like this, you really need
+to check the outcome. For instance, when \MICROSOFT\ updated the font end 2017,
+same gender couples got different hair style for the individuals so that one can
+still distinguish them. However, kissing couples and couples in love (indicated
+by a heart) seem to be removed. Who knows how and when politics creep into fonts:
+is public mixed couple kissing permitted, do we support families with any mix of
+gender, is associating pink with girls okay or not, how do we distinguish male
+and female anyway? In \in {figure} [fig:old-and-new] we see the same combination
+twice, the early 2017 rendering versus the late 2017 rendering. Can you notice
+the differences?
+
+\startplacefigure[title={Incompatible updates.},reference=fig:old-and-new]
+ \externalfigure[onandon-seguiemj.pdf][width=\textwidth]
+\stopplacefigure
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/onandon/onandon-ffi.tex b/doc/context/sources/general/manuals/onandon/onandon-ffi.tex
new file mode 100644
index 000000000..01c1bb4c5
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-ffi.tex
@@ -0,0 +1,554 @@
+% language=uk
+
+\startcomponent onandon-ffi
+
+\environment onandon-environment
+
+\startchapter[title={Plug mode, an application of ffi}]
+
+A while ago, at an NTG meeting, Kai Eigner and Ivo Geradts demonstrated how to
+use the Harfbuzz (hb) library for processing \OPENTYPE\ fonts. The main
+motivation for them playing with that was that it provides a way to compare the
+\LUA\ based font machinery with other methods. They also assumed that it would
+give a better performance for complex fonts and|/|or scripts.
+
+One of the guiding principles of \LUATEX\ development is that we don't provide
+hard coded solutions. For that reason we opened up the internals so that one can
+provide solutions written in pure \LUA, but, of course, one can cooperate with
+libraries via \LUA\ code as well. Hard coding solutions makes no sense as there
+are often several solutions possible, depending on one's need. Although
+development is closely related to \CONTEXT, the development of the \LUATEX\
+engine is generic. We try to be macro package agnostic. Already in an early stage
+we made sure that the \CONTEXT\ font handler could be used in other packages as
+well, but one can easily dream up light weight variants for specific purposes.
+The standard \TEX\ font handling was kept and is called \type {base} mode in
+\CONTEXT. The \LUA\ variant is tagged \type {node} mode because it operates on
+the node list. Later we will refer to these modes.
+
+With the output of \XETEX\ for comparison, the first motive mentioned for looking
+into support for such a library is not that strong. And when we want to test
+against the standard, we can use MS-Word. A minimal \CONTEXT\ \MKIV\ installation
+one only has the \LUATEX\ engine. Maintaining several renderers simultaneously
+might give rise to unwanted dependencies.
+
+The second motive could be more valid for users because, for complex fonts, there
+is|=|or at least was|=|a performance hit with the \LUA\ variant. Some fonts use
+many lookup steps or are inefficient even in using their own features. It must be
+said that till now I haven't heard \CONTEXT\ users complain about speed. In fact,
+the font handling became many times faster the last few years, and probably no
+one even noticed. Also, when using alternatives to the built in methods, in the
+end, you will loose functionality and|/|or interactions with other mechanisms
+that are built into the current font system. Any possible gain in speed is lost,
+or even becomes negative, when a user wants to use additional functionality that
+requires additional processing. \footnote {In general we try to stay away from
+libraries. For instance, graphics can be manipulated with external programs, and
+caching the result is much more efficient than recreating it. Apart from \SQL\
+support, where integration makes sense, I never felt the need for libraries. And
+even \SQL\ can efficiently be dealt with via intermediate files.}
+
+Just kicking in some alternative machinery is not the whole story. We still need
+to deal with the way \TEX\ sees text, and that, in practice, is as a sequence of
+glyph nodes|=|mixed with discretionaries for languages that hyphenate, glue,
+kern, boxes, math, and more. It's the discretionary part that makes it a bit
+complex. In contextual analysis as well as positioning one needs to process up to
+three additional cases: the pre, post and replace texts|=|either or not linked
+backward and forward. And as applied features accumulate one ends up winding and
+unwinding these snippets. In the process one also needs to keep an eye on spaces
+as they can be involved in lookups. Also, when injecting or removing glyphs one
+needs to deal with attributes associated with nodes. Of course something hard
+codes in the engine might help a little, but then one ends up with the situation
+where macro packages have different demands (and possible interactions) and no
+solution is the right one. Using \LUA\ as glue is a way to avoid that problem. In
+fact, once we go along that route, it starts making sense to come up with a
+stripped down \LUATEX\ that might suit \CONTEXT\ better, but it's not a route we
+are eager to follow right now.
+
+Kai and Ivo are plain \TEX\ users so they use a font definition and switching
+environment that is quite different from \CONTEXT. In an average \CONTEXT\ run
+the time spent on font processing is measurable but not the main bottleneck
+because other time consuming things happen. Sometimes the load on the font
+subsystem can be higher because we provide additional features normally not found
+in \OPENTYPE. Add to that a more dynamic font model and it will be clear that
+comparing performance between situations that use different macro packages is not
+that trivial (or relevant).
+
+More reasons why we follow a \LUA\ route are that we: support (run time
+generated) virtual fonts, are able to kick in additional features, can let the
+font mechanism cooperate with other functionality, and so on. In the upcoming
+years more trickery will be provided in the current mechanisms. Because we had to
+figure out a lot of these \OPENTYPE\ things a decade ago when standards were
+fuzzy quite some tracing and visualization is available. Below we will see some
+timings, It's important to keep in mind that in \CONTEXT\ the \OPENTYPE\ font
+handler can do a bit more if requested to do so, which comes with a bit of
+overhead when the handler is used in \CONTEXT|=|something we can live with.
+
+Some time after Kai's presentation he produced an article, and that was the
+moment I looked into the code and tried to replicate his experiments. Because
+we're talking libraries, one can understand that this is not entirely trivial,
+especially because I'm on another platform than he is|=|Windows instead of OSX.
+The first thing that I did was rewrite the code that glues the library to \TEX\
+in a way that is more suitable for \CONTEXT. Mixing with existing modes (\type
+{base} or \type {node} mode) makes no sense and is asking for unwanted
+interferences, so instead a new \type {plug} mode was introduced. A sort of
+general text filtering mechanism was derived from the original code so that we
+can plug in whatever we want. After all, stability is not the strongest point of
+today's software development, so when we depend on a library, we need to be
+prepared for other (library based) solutions|=|for instance, if I understood
+correctly, \XETEX\ switched a few times.
+
+After redoing the code the next step was to get the library running and I decided
+that the \type {ffi} route made most sense. \footnote {One can think of a
+intermediate layer but I'm pretty sure that I have different demands than others,
+but \type {ffi} sort of frees us from endless discussions.} Due to some expected
+functions not being supported, my efforts in using the library failed. At that
+time I thought it was a matter of interfacing, but I could get around it by
+piping into the command line tools that come with the library, and that was good
+enough for testing. Of course it was dead slow, but the main objective was
+comparison of rendering so it doesn't matter that much. After that I just quit
+and moved on to something else.
+
+At some point Kai's article came close to publishing, and I tried the old code
+again, and, surprise, after some messing around, the library worked. On my system
+the one shipped with Inkscape is used, which is okay as it frees me from bothering
+about installations. As already mentioned, we have no real reason in \CONTEXT\
+for using fonts libraries, but the interesting part was that it permitted me to
+play with this so called \type {ffi}. At that moment it was only available in
+\LUAJITTEX\. Because that creates a nasty dependency, after a while, Luigi
+Scarso and I managed to get a similar library working in stock \LUATEX\, which is
+of course the reference. So, I decided to give it a second try, and in the process
+I rewrote the interfacing code. After all, there is no reason not to be nice for
+libraries and optimize the interface where possible.
+
+Now, after a decade of writing \LUA\ code, I dare to claim that I know a bit
+about how to write relatively fast code. I was surprised to see that where Kai
+claimed that the library was faster than the \LUA\ code.I saw that it really
+depends on the font. Sometimes the library approach is actually slower, which is
+not what one expects. But remember that one argument for using a library is for
+complex fonts and scripts. So what is meant with complex?
+
+Most Latin fonts are not complex|=|ligatures and kerns and maybe a little bit of
+contextual analysis. Here the \LUA\ variant is the clear winner. It runs upto ten
+times faster. For more complex Latin fonts, like EBgaramond, that resolves
+ligatures in a different way, the library catches up, but still the \LUA\ handler
+is faster. Keep in mind that we need to juggle discretionary nodes in any case.
+One difference between both methods is that the \LUA\ handler runs over all the
+lists (although it has to jump over fonts not being processed then), while the
+library gets snippets. However, tests show that the overhead involved in that is
+close to zero and can be neglected. Already long ago we saw that when we compared
+\MKIV\ \LUATEX\ and \MKII\ \XETEX, the \LUA\ based font handler is not that slow
+at all. This makes sense because the problem doesn't change, and maybe more
+importantly because \LUA\ is a pretty fast language. If one or the other approach
+is less that two times faster the gain will probably go unnoticed in real runs.
+In my experience a few bad choices in macro or style writing is more harmful than
+a bit slower font machinery. Kick in some additional node processing and it might
+make comparison of a run even harder. By the way, one reason why font handling
+has been sped up over the years is because our workflows sometimes have a high
+load, and, for instance, processing a set of 5 documents remotely has to be fast.
+Also, in an edit workflow you want the runtime to be a bit comfortable.
+
+Contrary to Latin, a pure Arabic text (normally) has no discretionary nodes, and
+the library profits most of this. Some day I have to pick up the thread with
+Idris about the potential use of discretionary nodes in Arabic typesetting.
+Contrary to Arabic, Latin text has not many replacements and positioning, and,
+therefore, the \LUA\ variant gets the advantage. Some of the additional features
+that the \LUA\ variant provides can, of course, be provided for the library
+variant by adding some pre- and postprocessing of the list, but then you quickly
+loose any gain a library provides. So, Arabic has less complex node lists with no
+branches into discretinaries, but it definitely has more replacements,
+positioning and contextual lookups due to the many calls to helpers in the \LUA\
+code. Here the library should win because it can (I assume) use more optimized
+datastructures.
+
+In Kai's prototype there are some cheats for right|-|to|-|left rendering and
+special scripts like Devanagari. As these tweaks mostly involve discretionary
+nodes; there is no real need for them. When we don't hyphenate no time is wasted
+anyway. I didn't test Devanagari, but there is some preprocessing needed in the
+\LUA\ variant (provided by Kai and Ivo) that I might rewrite from scratch once I
+understand what happens there. But still, I expect the library to perform
+somewhat better there but I didn't test it. Eventually I might add support for
+some more scripts that demand special treatments, but so far there has not been
+any request for it.
+
+So what is the processing speed of non|-|Latin scripts? An experiment with Arabic
+using the frequently used Arabtype font showed that the library performs faster,
+but when we use a mixed Latin and Arabic document the differences become less
+significant. On pure Latin documents the \LUA\ variant will probably win. On pure
+Arabic the library might be on top. On average there is little difference in
+processing speed between the \LUA\ and library engines when processing mixed
+documents. The main question is, does one want to loose functionality provided by
+the \LUA\ variant? Of course one can depend on functionality provided by the
+library but not by the \LUA\ variant. In the end the user decides.
+
+How did we measure? The baseline measurement is the so called \type {none} mode:
+nothing is done there. It's fast but still takes a bit of time as it is triggered
+by a general mode identifying pass. That pass determines what font processing
+modes are needed for a list. \type {Base} mode only makes sense for Latin and has
+some limitations. It's fast and, basically, its run time can be neglected. That's
+why, for instance, \PDFTEX\ is faster than the other engines, but it doesn't do
+\UNICODE\ well. \type {Node} mode is the fancy name for the \LUA\ font handler.
+So, in order of increasing run time we have: \type {none}, \type {base} and \type
+{node}. If we compare \type{node} mode with \type {plug} mode (in our case using
+the hb library), we can subtract \type {none} mode. This gives a cleaner (more
+distinctive) comparison but not a real honest one because the identifying pass
+always happens.
+
+We also tested with and without hyphenation, but in practice that makes no sense.
+Only verbatim is typeset that way, and normally we typeset that in \type {none}
+mode anyway. On the other hand mixing fonts does happen. All the tests start with
+forced garbage collection in order to get rid of that variance. We also pack into
+horizontal boxes so that the par builder (with all kind of associated callbacks)
+doesn't kick in, although the \type {node} mode should compensate that.
+
+Keep in mind that the tests are somewhat dumb. There is no overhead in handling
+structure, building pages, adding color or whatever. I never process raw text. As
+a reference it's no problem to let \CONTEXT\ process hundreds of pages per
+second. In practice a moderate complex document like the metafun manual does some
+20 pages per second. In other words, only a fraction of the time is spent on
+fonts. The timings for \LUATEX\ are as follows:
+
+\usemodule[m-fonts-plugins]
+
+\startluacode
+ local process = moduledata.plugins.processlist
+ local data = table.load("m-fonts-plugins-timings-luatex.lua")
+ or table.load("t:/sources/m-fonts-plugins-timings-luatex.lua")
+
+ context.testpage { 6 }
+ context.subsubject("luatex latin")
+ process(data.timings.latin)
+ context.testpage { 6 }
+ context.subsubject("luatex arabic")
+ process(data.timings.arabic)
+ context.testpage { 6 }
+ context.subsubject("luatex mixed")
+ process(data.timings.mixed)
+\stopluacode
+
+The timings for \LUAJITTEX\ are, of course, overall better. This is because the
+virtual machine is faster, but at the cost of some limitations. We seldom run
+into these limitations, but fonts with large tables can't be cached unless we
+rewrite some code and sacrifice clean solutions. Instead, we perform a runtime
+conversion which is not that noticeable when it's just a few fonts. The numbers
+below are not influenced by this as the test stays away from these rare cases.
+
+\startluacode
+ local process = moduledata.plugins.processlist
+ local data = table.load("m-fonts-plugins-timings-luajittex.lua")
+ or table.load("t:/sources/m-fonts-plugins-timings-luajittex.lua")
+
+ context.testpage { 6 }
+ context.subsubject("luajittex latin")
+ process(data.timings.latin)
+ context.testpage { 6 }
+ context.subsubject("luajittex arabic")
+ process(data.timings.arabic)
+ context.testpage { 6 }
+ context.subsubject("luajittex mixed")
+ process(data.timings.mixed)
+\stopluacode
+
+A few side notes. Since a library is an abstraction, one has to live with what
+one gets. In my case that was a crash in \UTF-32 mode. I could get around it, but
+one advantage of using \LUA\ is that it's hard to crash|=|if only because as a
+scripting language it manages its memory well without user interference. My
+policy with libraries is just to wait till things get fixed and not bother with
+the why and how of the internals.
+
+Although \CONTEXT\ will officially support the \type {plug} model, it will not be
+actively used by me, or in documentation, so for support users are on their own.
+I didn't test the \type {plug} mode in real documents. Most documents that I
+process are Latin (or a mix), and redefining feature sets or adapting styles for
+testing makes no sense. So, can one just switch engines without looking at the
+way a font is defined? The answer is|=|not really, because (even without the user
+knowing about it) virtual fonts might be used, additional features kicked in and
+other mechanisms can make assumptions about how fonts are dealt with too.
+
+The useability of \type {plug} mode probably depends on the workflow one has. We
+use \CONTEXT\ in a few very specific workflows where, interestingly, we only use a
+small subset of its functionality. Most of which is driven by users, and tweaking
+fonts is popular and has resulted in all kind of mechanisms. So, for us it's
+unlikely that we will use it. If you process (in bursts) many documents in
+succession, each demanding a few runs, you don't want to sacrifice speed.
+
+Of course timing can (and likely will) be different for plain \TEX\ and \LATEX\
+usage. It depends on how mechanisms are hooked into the callbacks, what extra
+work is done or not done compared to \CONTEXT. This means that my timings for
+\CONTEXT\ for sure will differ from those of other packages. Timings are a
+snapshot anyway. And as said, font processing is just one of the many things that
+goes on. If you are not using \CONTEXT\ you probably will use Kai's version
+because it is adapted to his use case and well tested.
+
+A fundamental difference between the two approaches is that|=|whereas the \LUA\
+variant operates on node lists only, the \type {plug} variant generates strings
+that get passed to a library where, in the \CONTEXT\ variant of hb support, we
+use \UTF-32 strings. Interesting, a couple of years ago I considered using a
+similar method for \LUA\ but eventually decided against it, first of all for
+performance reasons, but mostly because one still has to use some linked list
+model. I might pick up that idea as a variant, but because all this \TEX\ related
+development doesn't really pay off and costs a lot of free time it will probably
+never happen.
+
+I finish with a few words on how to use the plug model. Because the library
+initializes a default set of features,\footnote {Somehow passing features to the
+library fails for Arabic. So when you don't get the desired result, just try with
+the defaults.} all you need to do is load the plugin mechanism:
+
+\starttyping
+\usemodule[fonts-plugins]
+\stoptyping
+
+Next you define features that use this extension:
+
+\starttyping
+\definefontfeature
+ [hb-native]
+ [mode=plug,
+ features=harfbuzz,
+ shaper=native]
+\stoptyping
+
+After this you can use this feature set when you define fonts. Here is a complete
+example:
+
+\starttyping
+\usemodule[fonts-plugins]
+
+\starttext
+
+ \definefontfeature
+ [hb-library]
+ [mode=plug,
+ features=harfbuzz,
+ shaper=native]
+
+ \definedfont[Serif*hb-library]
+
+ \input ward \par
+
+ \definefontfeature
+ [hb-binary]
+ [mode=plug,
+ features=harfbuzz,
+ method=binary,
+ shaper=uniscribe]
+
+ \definedfont[Serif*hb-binary]
+
+ \input ward \par
+
+\stoptext
+\stoptyping
+
+The second variant uses the \type {hb-shape} binary which is, of course, pretty
+slow, but does the job and is okay for testing.
+
+There are a few trackers available too:
+
+\starttyping
+\enabletrackers[fonts.plugins.hb.colors]
+\enabletrackers[fonts.plugins.hb.details]
+\stoptyping
+
+The first one colors replaced glyphs while the second gives lot of information
+about what is going on. If you want to know what gets passed to the library you
+can use the \type {text} plugin:
+
+\starttyping
+\definefontfeature[test][mode=plug,features=text]
+\start
+ \definedfont[Serif*test]
+ \input ward \par
+\stop
+\stoptyping
+
+This produces something:
+
+\starttyping[style=\ttx]
+otf plugin > text > start run 3
+otf plugin > text > 001 : [-] The [+]-> U+00054 U+00068 U+00065
+otf plugin > text > 002 : [+] Earth, [+]-> U+00045 U+00061 U+00072 ...
+otf plugin > text > 003 : [+] as [+]-> U+00061 U+00073
+otf plugin > text > 004 : [+] a [+]-> U+00061
+otf plugin > text > 005 : [+] habi- [-]-> U+00068 U+00061 U+00062 ...
+otf plugin > text > 006 : [-] tat [+]-> U+00074 U+00061 U+00074
+otf plugin > text > 007 : [+] habitat [+]-> U+00068 U+00061 U+00062 ...
+otf plugin > text > 008 : [+] for [+]-> U+00066 U+0006F U+00072
+otf plugin > text > 009 : [+] an- [-]-> U+00061 U+0006E U+0002D
+\stoptyping
+
+You can see how hyphenation of \type {habi-tat} results in two snippets and a
+whole word. The font engine can decide to turn this word
+into a disc node with a pre, post and replace text. Of course the machinery will
+try to retain as many hyphenation points as possible. Among the tricky parts of
+this are lookups across and inside discretionary nodes resulting in (optional)
+replacements and kerning. You can imagine that there is some trade off between
+performance and quality here. The results are normally acceptable, especially
+because \TEX\ is so clever in breaking paragraphs into lines.
+
+Using this mechanism (there might be variants in the future) permits the user to
+cook up special solutions. After all, that is what \LUATEX\ is about|=|the
+traditional core engine with the ability to plug in your own code using \LUA.
+This is just an example of it.
+
+I'm not sure yet when the plugin mechanism will be in the \CONTEXT\ distribution,
+but it might happen once the \type {ffi} library is supported in \LUATEX. At the
+end of this document the basics of the test setup are shown, just in case you
+wonder what the numbers apply to.
+
+Just to put things in perspective, the current (February 2017) \METAFUN\ manual
+has 424 pages. It takes \LUATEX\ 18.3 seconds and \LUAJITTEX\ 14.4 seconds on my
+Dell 7600 laptop with 3840QM mobile i7 processor. Of this 6.1 (4.5) seconds is
+used for processing 2170 \METAPOST\ graphics. Loading the 15 fonts used takes
+0.25 (0.3) seconds, which includes also loading the outline of some. Font
+handling is part of the, so called, hlist processing and takes around 1 (0.5)
+second, and attribute backend processing takes 0.7 (0.3) seconds. One problem in
+these timings is that font processing often goes too fast for timing, especially
+when we have lots of small snippets. For example, short runs like titles and such
+take no time at all, and verbatim needs no font processing. The difference in
+runtime between \LUATEX\ and \LUAJITTEX\ is significant so we can safely assume
+that we spend some more time on fonts than reported. Even if we add a few
+seconds, in this rather complete document, the time spent on fonts is still not
+that impressive. A five fold increase in processing (we use mostly Pagella and
+Dejavu) is a significant addition to the total run time, especially if you need a
+few runs to get cross referencing etc.\ right.
+
+The test files are the familiar ones present in the distribution. The \type
+{tufte} example is a good torture test for discretionary processing. We preload
+the files so that we don't have the overhead of \type {\input}.
+
+\starttyping
+\edef\tufte{\cldloadfile{tufte.tex}}
+\edef\khatt{\cldloadfile{khatt-ar.tex}}
+\stoptyping
+
+We use six buffers for the tests. The Latin test uses three fonts and also
+has a paragraph with mixed font usage. Loading the fonts happens once before
+the test, and the local (re)definition takes no time. Also, we compensate
+for general overhead by subtracting the \type {none} timings.
+
+\starttyping
+\startbuffer[latin-definitions]
+\definefont[TestA][Serif*test]
+\definefont[TestB][SerifItalic*test]
+\definefont[TestC][SerifBold*test]
+\stopbuffer
+
+\startbuffer[latin-text]
+\TestA \tufte \par
+\TestB \tufte \par
+\TestC \tufte \par
+\dorecurse {10} {%
+ \TestA Fluffy Test Font A
+ \TestB Fluffy Test Font B
+ \TestC Fluffy Test Font C
+}\par
+\stopbuffer
+\stoptyping
+
+The Arabic tests are a bit simpler. Of course we do need to make sure that we go
+from right to left.
+
+\starttyping
+\startbuffer[arabic-definitions]
+\definedfont[Arabic*test at 14pt]
+\setupinterlinespace[line=18pt]
+\setupalign[r2l]
+\stopbuffer
+
+\startbuffer[arabic-text]
+\dorecurse {10} {
+ \khatt\space
+ \khatt\space
+ \khatt\blank
+}
+\stopbuffer
+\stoptyping
+
+The mixed case use a Latin and an Arabic font and also processes a mixed script
+paragraph.
+
+\starttyping
+\startbuffer[mixed-definitions]
+\definefont[TestL][Serif*test]
+\definefont[TestA][Arabic*test at 14pt]
+\setupinterlinespace[line=18pt]
+\setupalign[r2l]
+\stopbuffer
+
+\startbuffer[mixed-text]
+\dorecurse {2} {
+ {\TestA\khatt\space\khatt\space\khatt}
+ {\TestL\lefttoright\tufte}
+ \blank
+ \dorecurse{10}{%
+ {\TestA وَ قَرْمِطْ بَيْنَ الْحُرُوفِ؛ فَإِنَّ}
+ {\TestL\lefttoright A snippet text that makes no sense.}
+ }
+}
+\stopbuffer
+\stoptyping
+
+The related font features are defined as follows:
+
+\starttyping
+\definefontfeature
+ [test-none]
+ [mode=none]
+
+\definefontfeature
+ [test-base]
+ [mode=base,
+ liga=yes,
+ kern=yes]
+
+\definefontfeature
+ [test-node]
+ [mode=node,
+ script=auto,
+ autoscript=position,
+ autolanguage=position,
+ ccmp=yes,liga=yes,clig=yes,
+ kern=yes,mark=yes,mkmk=yes,
+ curs=yes]
+
+\definefontfeature
+ [test-text]
+ [mode=plug,
+ features=text]
+
+\definefontfeature
+ [test-native]
+ [mode=plug,
+ features=harfbuzz,
+ shaper=native]
+
+\definefontfeature
+ [arabic-node]
+ [arabic]
+
+\definefontfeature
+ [arabic-native]
+ [mode=plug,
+ features=harfbuzz,
+ script=arab,language=dflt,
+ shaper=native]
+\stoptyping
+
+The timings are collected in \LUA\ tables and typeset afterwards, so there is no
+interference there either.
+
+{\em The timings are as usual a snapshot and just indications. The relative times
+can differ over time depending on how binaries are compiled, libraries are
+improved and \LUA\ code evolves. In node mode we can have experimental trickery
+that is not yet optimized. Also, especially with complex fonts like Husayni, not
+all shapers give the same result, although node mode and Uniscribe should be the
+same in most cases. A future (public) version of Husayni will play more safe and
+use less complex sequences of features.}
+
+% And for the record: when I finished it, this 12 page documents processes in
+% roughly 1~second with \LUATEX\ and 0.8 second with \LUAJITTEX\ which is okay for
+% a edit|-|preview cycle.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/onandon/onandon-performance.tex b/doc/context/sources/general/manuals/onandon/onandon-performance.tex
new file mode 100644
index 000000000..279383a8c
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-performance.tex
@@ -0,0 +1,785 @@
+% language=uk
+
+% no zero timing compensation, just simple tests
+% m4all book
+
+\startcomponent onandon-performance
+
+\environment onandon-environment
+
+\startchapter[title=Performance]
+
+\startsection[title=Introduction]
+
+This chapter is about performance. Although it concerns \LUATEX\ this text is
+only meant for \CONTEXT\ users. This is not because they ever complain about
+performance, on the contrary, I never received a complain from them. No, it's
+because it gives them some ammunition against the occasionally occurring nagging
+about the speed of \LUATEX\ (somewhere on the web or at some meeting). My
+experience is that in most such cases those complaining have no clue what they're
+talking about, so effectively we could just ignore them, but let's, for the sake
+of our users, waste some words on the issue.
+
+\stopsection
+
+\startsection[title=What performance]
+
+So what exactly does performance refer to? If you use \CONTEXT\ there are
+probably only two things that matter:
+
+\startitemize[packed]
+\startitem How long does one run take. \stopitem
+\startitem How many runs do I need. \stopitem
+\stopitemize
+
+Processing speed is reported at the end of a run in terms of seconds spent on the
+run, but also in pages per second. The runtime is made up out of three
+components:
+
+\startitemize[packed]
+\startitem start-up time \stopitem
+\startitem processing pages \stopitem
+\startitem finishing the document \stopitem
+\stopitemize
+
+The startup time is rather constant. Let's take my 2013 Dell Precision with
+i7-3840QM as reference. A simple
+
+\starttyping
+\starttext
+\stoptext
+\stoptyping
+
+document reports 0.4 seconds but as we wrap the run in an \type {mtxrun}
+management run we have an additional 0.3 overhead (auxiliary file handling, \PDF\
+viewer management, etc). This includes loading the Latin Modern font. With
+\LUAJITTEX\ these times are below 0.3 and 0.2 seconds. It might look like much
+overhead but in an edit|-|preview runs it feels snappy. One can try this:
+
+\starttyping
+\stoptext
+\stoptyping
+
+which bring down the time to about 0.2 seconds for both engines but as it doesn't
+do anything useful that is is no practice.
+
+Finishing a document is not that demanding because most gets flushed as we go.
+The more (large) fonts we use, the longer it takes to finish a document but on
+the average that time is not worth noticing. The main runtime contribution comes
+from processing the pages.
+
+Okay, this is not always true. For instance, if we process a 400 page book from
+2500 small \XML\ files with multiple graphics per page, there is a little
+overhead in loading the files and constructing the \XML\ tree as well as in
+inserting the graphics but in such cases one expects a few seconds more runtime. The
+\METAFUN\ manual has some 450 pages with over 2500 runtime generated \METAPOST\
+graphics. It has color, uses quite some fonts, has lots of font switches
+(verbatim too) but still one run takes only 18 seconds in stock \LUATEX\ and less
+that 15 seconds with \LUAJITTEX. Keep these numbers in mind if a non|-|\CONTEXT\
+users barks against the performance tree that his few page mediocre document
+takes 10 seconds to compile: the content, styling, quality of macros and whatever
+one can come up with all plays a role. Personally I find any rate between 10 and
+30 pages per second acceptable, and if I get the lower rate then I normally know
+pretty well that the job is demanding in all kind of aspects.
+
+Over time the \CONTEXT||\LUATEX\ combination, in spite of the fact that more
+functionality has been added, has not become slower. In fact, some subsystems
+have been sped up. For instance font handling is very sensitive for adding
+functionality. However, each version so far performed a bit better. Whenever some
+neat new trickery was added, at the same time improvements were made thanks to
+more insight in the matter. In practice we're not talking of changes in speed by
+large factors but more by small percentages. I'm pretty sure that most \CONTEXT\
+users never noticed. Recently a 15\endash30\% speed up (in font handling) was
+realized (for more complex fonts) but only when you use such complex fonts and
+pages full of text you will see a positive impact on the whole run.
+
+There is one important factor I didn't mention yet: the efficiency of the
+console. You can best check that by making a format (\typ {context --make en}).
+When that is done by piping the messages to a file, it takes 3.2 seconds on my
+laptop and about the same when done from the editor (\SCITE), maybe because the
+\LUATEX\ run and the log pane run on a different thread. When I use the standard
+console it takes 3.8 seconds in Windows 10 Creative update (in older versions it
+took 4.3 and slightly less when using a console wrapper). The powershell takes
+3.2 seconds which is the same as piping to a file. Interesting is that in Bash on
+Windows it takes 2.8 seconds and 2.6 seconds when piped to a file. Normal runs
+are somewhat slower, but it looks like the 64 bit Linux binary is somewhat faster
+than the 64 bit mingw version. \footnote {Long ago we found that \LUATEX\ is very
+sensitive to for instance the \CPU\ cache so maybe there are some differences due
+to optimization flags and|/|or the fact that bash runs in one thread and all file
+\IO\ in the main windows instance. Who knows.} Anyway, it demonstrates that when
+someone yells a number you need to ask what the conditions where.
+
+At a \CONTEXT\ meeting there has been a presentation about possible speed|-|up of
+a run for instance by using a separate syntax checker to prevent a useless run.
+However, the use case concerned a document that took a minute on the machine
+used, while the same document took a few seconds on mine. At the same meeting we
+also did a comparison of speed for a \LATEX\ run using \PDFTEX\ and the same
+document migrated to \CONTEXT\ \MKIV\ using \LUATEX\ (Harald K\"onigs \XML\
+torture and compatibility test). Contrary to what one might expect, the
+\CONTEXT\ run was significantly faster; the resulting document was a few
+gigabytes in size.
+
+\stopsection
+
+\startsection[title=Bottlenecks]
+
+I will discuss a few potential bottlenecks next. A complex integrated system like
+\CONTEXT\ has lots of components and some can be quite demanding. However, when
+something is not used, it has no (or hardly any) impact on performance. Even when
+we spend a lot of time in \LUA\ that is not the reason for a slow|-|down.
+Sometimes using \LUA\ results in a speedup, sometimes it doesn't matter. Complex
+mechanisms like natural tables for instance will not suddenly become less
+complex. So, let's focus on the \quotation {aspects} that come up in those
+complaints: fonts and \LUA. Because I only use \CONTEXT\ and occasionally test
+with the plain \TEX\ version that we provide, I will not explore the potential
+impact of using truckloads of packages, styles and such, which I'm sure of plays
+a role, but one neglected in the discussion.
+
+\startsubsubject[title=Fonts]
+
+According to the principles of \LUATEX\ we process (\OPENTYPE) fonts using \LUA.
+That way we have complete control over any aspect of font handling, and can, as
+to be expected in \TEX\ systems, provide users what they need, now and in the
+future. In fact, if we didn't had that freedom in \CONTEXT\ I'd probably already
+quit using \TEX\ a decade ago and found myself some other (programming) niche.
+
+After a font is loaded, part of the data gets passed to the \TEX\ engine so that
+it can do its work. For instance, in order to be able to typeset a paragraph,
+\TEX\ needs to know the dimensions of glyphs. Once a font has been loaded
+(that is, the binary blob) the next time it's fetched from a cache. Initial
+loading (and preparation) takes some time, depending on the complexity or size of
+the font. Loading from cache is close to instantaneous. After loading the
+dimensions are passed to \TEX\ but all data remains accessible for any desired
+usage. The \OPENTYPE\ feature processor for instance uses that data and \CONTEXT\
+for sure needs that data (fast accessible) for different purposes too.
+
+When a font is used in so called base mode, we let \TEX\ do the ligaturing and
+kerning. This is possible with simple fonts and features. If you have a critical
+workflow you might enable base mode, which can be done per font instance.
+Processing in node mode takes some time but how much depends on the font and
+script. Normally there is no difference between \CONTEXT\ and generic usage. In
+\CONTEXT\ we also have dynamic features, and the impact on performance depends on
+usage. In addition to base and node we also have plug mode but that is only used
+for testing and therefore not advertised.
+
+Every \type {\hbox} and every paragraph goes through the font handler. Because
+we support mixed modes, some analysis takes place, and because we do more in
+\CONTEXT, the generic analyzer is more light weight, which again can mean that a
+generic run is not slower than a similar \CONTEXT\ one.
+
+Interesting is that added functionality for variable and|/|or color fonts had no
+impact on performance. Runtime added user features can have some impact but when
+defined well it can be neglected. I bet that when you add additional node list
+handling yourself, its impact on performance is larger. But in the end what
+counts is that the job gets done and the more you demand the higher the price you
+pay.
+
+\stopsubsubject
+
+\startsubsubject[title=\LUA]
+
+The second possible bottleneck when using \LUATEX\ can be in using \LUA\ code.
+However, using that as argument for slow runs is laughable. For instance
+\CONTEXT\ \MKIV\ can easily spend half its time in \LUA\ and that is not making
+it any slower than \MKII\ using \PDFTEX\ doing equally complex things. For
+instance the embedded \METAPOST\ library makes \MKIV\ way faster than \MKII, and
+the built|-|in \XML\ processing capabilities in \MKIV\ can easily beat \MKII\
+\XML\ handling, apart from the fact that it can do more, like filtering by path
+and expression. In fact, files that take, say, half a minute in \MKIV, could as
+well have taken 15 minutes or more in \MKII\ (and imagine multiple runs then).
+
+So, for \CONTEXT\ using \LUA\ to achieve its objectives is mandate. The
+combination of \TEX, \METAPOST\ and \LUA\ is pretty powerful! Each of these
+components is really fast. If \TEX\ is your bottleneck, review your macros! When
+\LUA\ seems to be the bad, go over your code and make it better. Much of the
+\LUA\ code I see flying around doesn't look that efficient, which is okay because
+the interpreter is really fast, but don't blame \LUA\ beforehand, blame your
+coding (style) first. When \METAPOST\ is the bottleneck, well, sometimes not much
+can be done about it, but when you know that language well enough you can often
+make it perform better.
+
+For the record: every additional mechanism that kicks in, like character spacing
+(the ugly one), case treatments, special word and line trickery, marginal stuff,
+graphics, line numbering, underlining, referencing, and a few dozen more will add
+a bit to the processing time. In that case, in \CONTEXT, the font related runtime
+gets pretty well obscured by other things happening, just that you know.
+
+\stopsubsubject
+
+\stopsection
+
+\startsection[title=Some timing]
+
+Next I will show some timings related to fonts. For this I use stock \LUATEX\
+(second column) as well as \LUAJITTEX\ (last column) which of course performs
+much better. The timings are given in 3 decimals but often (within a set of runs)
+and as the system load is normally consistent in a set of test runs the last two
+decimals only matter in relative comparison. So, for comparing runs over time
+round to the first decimal. Let's start with loading a bodyfont. This happens
+once per document and normally one has only one bodyfont active. Loading involves
+definitions as well as setting up math so a couple of fonts are actually loaded,
+even if they're not used later on. A setup normally involves a serif, sans, mono,
+and math setup (in \CONTEXT). \footnote {The timing for Latin Modern is so low
+because that font is loaded already.}
+
+\environment onandon-speed-000
+
+\ShowSample{onandon-speed-000} % bodyfont
+
+There is a bit difference between the font sets but a safe average is 150 milli
+seconds and this is rather constant over runs.
+
+An actual font switch can result in loading a font but this is a one time overhead.
+Loading four variants (regular, bold, italic and bold italic) roughly takes the
+following time:
+
+\ShowSample{onandon-speed-001} % four variants
+
+Using them again later on takes no time:
+
+\ShowSample{onandon-speed-002} % four variants
+
+Before we start timing the font handler, first a few baseline benchmarks are
+shown. When no font is applied and nothing else is done with the node list we
+get:
+
+\ShowSample{onandon-speed-009}
+
+A simple monospaced, no features applied, run takes a bit more:
+
+\ShowSample{onandon-speed-010}
+
+Now we show a one font typesetting run. As the two benchmarks before, we just
+typeset a text in a \type {\hbox}, so no par builder interference happens. We use
+the \type {sapolsky} sample text and typeset it 100 times 4 (either of not with
+font switches).
+
+\ShowSample{onandon-speed-003}
+
+Much more runtime is needed when we typeset with four font switches. The garamond
+is most demanding. Actually we're not doing 4 fonts there because it has no bold,
+so the numbers are a bit lower than expected for this example. One reason for it
+being demanding is that it has lots of (contextual) lookups. The only comment I
+can make about that is that it also depends on the strategies of the font
+designer. Combining lookups saves space and time so complexity of a font is not
+always a good predictor for performance hits.
+
+% \ShowSample{onandon-speed-004}
+
+If we typeset paragraphs we get this:
+
+\ShowSample{onandon-speed-005}
+
+We're talking of some 275 pages here.
+
+\ShowSample{onandon-speed-006}
+
+There is of course overhead in handling paragraphs and pages:
+
+\ShowSample{onandon-speed-011}
+
+Before I discuss these numbers in more details two more benchmarks are
+shown. The next table concerns a paragraph with only a few (bold) words.
+
+\ShowSample{onandon-speed-007}
+
+The following table has paragraphs with a few mono spaced words
+typeset using \type{\type}.
+
+\ShowSample{onandon-speed-008}
+
+When a node list (hbox or paragraph) is processed, each glyph is looked at. One
+important property of \LUATEX\ (compared to \PDFTEX) is that it hyphenates the
+whole text, not only the most feasible spots. For the \type {sapolsky} snippet
+this results in 200 potential breakpoints, registered in an equal number of
+discretionary nodes. The snippet has 688 characters grouped into 125 words and
+because it's an English quote we're not hampered with composed characters or
+complex script handling. And, when we mention 100 runs then we actually mean
+400 ones when font switching and bodyfonts are compared
+
+\startnarrower
+ \showglyphs \showfontkerns
+ \input sapolsky \wordright{Robert M. Sapolsky}
+\stopnarrower
+
+In order to get substitutions and positioning right we need not only to consult
+streams of glyphs but also combinations with preceding pre or replace, or
+trailing post and replace texts. When a font has a bit more complex substitutions,
+as ebgaramond has, multiple (sometimes hundreds of) passes over the list are made.
+This is why the more complex a font is, the more runtime is involved.
+
+Another factor, one you could easily deduce from the benchmarks, is intermediate
+font switches. Even a few such switches (in the last benchmarks) already result
+in a runtime penalty. The four switch benchmarks show an impressive increase of
+runtime, but it's good to know that such a situation seldom happens. It's also
+important not to confuse for instance a verbatim snippet with a bold one. The
+bold one is indeed leading to a pass over the list, but verbatim is normally
+skipped because it uses a font that needs no processing. That verbatim or bold
+have the same penalty is mainly due to the fact that verbatim itself is costly:
+the text is picked up using a different catcode regime and travels through \TEX\
+and \LUA\ before it finally gets typeset. This relates to special treatments of
+spacing and syntax highlighting and such.
+
+Also keep in mind that the page examples are quite unreal. We use a layout with
+no margins, just text from edge to edge.
+
+\placefigure
+ {\SampleTitle{onandon-speed-005}}
+ {\externalfigure[onandon-speed-005][frame=on,orientation=90,width=.45\textheight]}
+
+\placefigure
+ {\SampleTitle{onandon-speed-006}}
+ {\externalfigure[onandon-speed-006][frame=on,orientation=90,maxwidth=.45\textheight,maxheight=\textwidth]}
+
+\placefigure
+ {\SampleTitle{onandon-speed-007}}
+ {\externalfigure[onandon-speed-007][frame=on,orientation=90,width=.45\textheight]}
+
+\placefigure
+ {\SampleTitle{onandon-speed-008}}
+ {\externalfigure[onandon-speed-008][frame=on,orientation=90,width=.45\textheight]}
+
+\placefigure
+ {\SampleTitle{onandon-speed-011}}
+ {\externalfigure[onandon-speed-011][frame=on,orientation=90,width=.45\textheight]}
+
+So what is a realistic example? That is hard to say. Unfortunately no one ever
+asked us to typeset novels. They are rather brain dead products for a machinery
+so they process fast. On the mentioned laptop 350 word pages in Dejavu fonts can
+be processed at a rate of 75 pages per second with \LUATEX\ and over 100 pages
+per second with \LUAJITTEX . On a more modern laptop or professional server
+performance is of course better. And for automated flows batch mode is your
+friend. The rate is not much worse for a document in a language with a bit more
+complex character handling, take accents or ligatures. Of course \PDFTEX\ is
+faster on such a dumb document but kick in some more functionality and the
+advantage quickly disappears. So, if someone complains that \LUATEX\ needs 10 or
+more seconds for a simple few page document \unknown\ you can bet that when the
+fonts are seen as reason, that the setup is pretty bad. Personally I'd not waste
+time on such a complaint.
+
+\stopsection
+
+\startsection[title=Valid questions]
+
+Here are some reasonable questions that you can ask when someone complains to you
+about the slowness of \LUATEX:
+
+\startsubsubject[title={What engines do you compare?}]
+
+If you come from \PDFTEX\ you come from an 8~bit world: input and font handling
+are based on bytes and hyphenation is integrated into the par builder. If you use
+\UTF-8\ in \PDFTEX, the input is decoded by \TEX\ macros which carries a speed
+penalty. Because in the wide engines macro names can also be \UTF\ sequences,
+construction of macro names is less efficient too.
+
+When you try to use wide fonts, again there is a penalty. Now, if you use \XETEX\
+or \LUATEX\ your input is \UTF-8 which becomes something 32 bit internally. Fonts
+are wide so more resources are needed, apart from these fonts being larger and in
+need of more processing due to feature handling. Where \XETEX\ uses a library,
+\LUATEX\ uses its own handler. Does that have a consequence for performance? Yes
+and no. First of all it depends on how much time is spent on fonts at all, but
+even then the difference is not that large. Sometimes \XETEX\ wins, sometimes
+\LUATEX. One thing is clear: \LUATEX\ is more flexible as we can roll out our own
+solutions and therefore do more advanced font magic. For \CONTEXT\ it doesn't
+matter as we use \LUATEX\ exclusively and rely on the flexible font handler, also
+for future extensions. If really needed you can kick in a library based handler
+but it's (currently) not distributed as we loose other functionality which in
+turn would result in complaints about that fact (apart from conflicting with the
+strive for independence).
+
+There is no doubt that \PDFTEX\ is faster but for \CONTEXT\ it's an obsolete
+engine. The hard coded solutions engine \XETEX\ is also not feasible for
+\CONTEXT\ either. So, in practice \CONTEXT\ users have no choice: \LUATEX\ is
+used, but users of other macro packages can use the alternatives if they are not
+satisfied with performance. The fact that \CONTEXT\ users don't complain about
+speed is a clear signal that this is no issue. And, if you want more speed you
+can use \LUAJITTEX. \footnote {In plug mode we can actually test a library and
+experiments have shown that performance on the average is much worse but it can
+be a bit better for complex scripts, although a gain gets unnoticed in normal
+documents. So, one can decide to use a library but at the cost of much other
+functionality that \CONTEXT\ offers, so we don't support it.} In the last section
+the different engines will be compared in more detail.
+
+Just that you know, when we do the four switches example in plain \TEX\ on my
+laptop I get a rate of 40 pages per second, and for one font 180 pages per
+second. There is of course a bit more going on in \CONTEXT\ in page building and
+so, but the difference between plain and \CONTEXT\ is not that large.
+
+\stopsubsubject
+
+\startsubsubject[title={What macro package is used?}]
+
+If the answer is that when plain \TEX\ is used, a follow up question is: what
+variant? The \CONTEXT\ distribution ships with \type {luatex-plain} and that is
+our benchmark. If there really is a bottleneck it is worth exploring. But keep in
+mind that in order to be plain, not that much can be done. The \LUATEX\ part is
+just an example of an implementation. We already discussed \CONTEXT, and for
+\LATEX\ I don't want to speculate where performance hits might come from. When
+we're talking fonts, \CONTEXT\ can actually a bit slower than the generic (or
+\LATEX) variant because we can kick in more functionality. Also, when you compare
+macro packages, keep in mind that when node list processing code is added in that
+package the impact depends on interaction with other functionality and depends on
+the efficiency of the code. You can't compare mechanisms or draw general
+conclusions when you don't know what else is done!
+
+\stopsubsubject
+
+\startsubsubject[title={What do you load?}]
+
+Most \CONTEXT\ modules are small and load fast. Of course there can be exceptions
+when we rely on third party code; for instance loading tikz takes a a bit of
+time. It makes no sense to look for ways to speed that system up because it is
+maintained elsewhere. There can probably be gained a bit but again, no user
+complained so far.
+
+If \CONTEXT\ is not used, one probably also uses a large \TEX\ installations.
+File lookup in \CONTEXT\ is done differently and can can be faster. Even loading
+can be more efficient in \CONTEXT, but it's hard to generalize that conclusion.
+If one complains about loading fonts being an issue, just try to measure how much
+time is spent on loading other code.
+
+\stopsubsubject
+
+\startsubsubject[title={Did you patch macros?}]
+
+Not everyone is a \TEX pert. So, coming up with macros that are expanded many
+times and|/|or have inefficient user interfacing can have some impact. If someone
+complains about one subsystem being slow, then honestly demands to complain about
+other subsystems as well. You get what you ask for.
+
+\stopsubsubject
+
+\startsubsubject[title={How efficient is the code that you use?}]
+
+Writing super efficient code only makes sense when it's used frequently. In
+\CONTEXT\ most code is reasonable efficient. It can be that in one document fonts
+are responsible for most runtime, but in another document table construction can
+be more demanding while yet another document puts some stress on interactive
+features. When hz or protrusion is enabled then you run substantially slower
+anyway so when you are willing to sacrifice 10\% or more runtime don't complain
+about other components. The same is true for enabling \SYNCTEX: if you are
+willing to add more than 10\% runtime for that, don't wither about the same
+amount for font handling. \footnote {In \CONTEXT\ we use a \SYNCTEX\ alternative
+that is somewhat faster but it remains a fact that enabling more and more
+functionality will make the penalty of for instance font processing relatively
+small.}
+
+\stopsubsubject
+
+\startsubsubject[title={How efficient is the styling that you use?}]
+
+Probably the most easily overseen optimization is in switching fonts and color.
+Although in \CONTEXT\ font switching is fast, I have no clue about it in other
+macro packages. But in a style you can decide to use inefficient (massive) font
+switches. The effects can easily be tested by commenting bit and pieces. For
+instance sometimes you need to do a full bodyfont switch when changing a style,
+like assigning \type {\small\bf} to the \type {style} key in \type {\setuphead},
+but often using e.g.\ \type {\tfd} is much more efficient and works quite as
+well. Just try it.
+
+\stopsubsubject
+
+\startsubsubject[title={Are fonts really the bottleneck?}]
+
+We already mentioned that one can look in the wrong direction. Maybe once someone
+is convinced that fonts are the culprit, it gets hard to look at the real issue.
+If a similar job in different macro packages has a significant different runtime
+one can wonder what happens indeed.
+
+It is good to keep in mind that the amount of text is often not as large as you
+think. It's easy to do a test with hundreds of paragraphs of text but in practice
+we have whitespace, section titles, half empty pages, floats, itemize and similar
+constructs, etc. Often we don't mix many fonts in the running text either. So, in
+the end a real document is the best test.
+
+\stopsubsubject
+
+\startsubsubject[title={If you use \LUA, is that code any good?}]
+
+You can gain from the faster virtual machine of \LUAJITTEX. Don't expect wonders
+from the jitting as that only pays of for long runs with the same code used over
+and over again. If the gain is high you can even wonder how well written your
+\LUA\ code is anyway.
+
+\stopsubsubject
+
+\startsubsubject[title={What if they don't believe you?}]
+
+So, say that someone finds \LUATEX\ slow, what can be done about it? Just advice
+him or her to stick to tool used previously. Then, if arguments come that one
+also wants to use \UTF-8, \OPENTYPE\ fonts, a bit of \METAPOST, and is looking
+forward to using \LUA\ runtime, the only answer is: take it or leave it. You pay
+a price for progress, but if you do your job well, the price is not that large.
+Tell them to spend time on learning and maybe adapting and bark against their own
+tree before barking against those who took that step a decade ago. Most \CONTEXT\
+users took that step and someone still using \LUATEX\ after a decade can't be
+that stupid. It's always best to first wonder what one actually asks from \LUATEX,
+and if the benefit of having \LUA\ on board has an advantage. If not, one can
+just use another engine.
+
+Also think of this. When a job is slow, for me it's no problem to identify where
+the problem is. The question then is: can something be done about it? Well, I
+happily keep the answer for myself. After all, some people always need room to
+complain, maybe if only to hide their ignorance or incompetence. Who knows.
+
+\stopsubsubject
+
+\stopsection
+
+\startsection[title={Comparing engines}]
+
+The next comparison is to be taken with a grain of salt and concerns the state of
+affairs mid 2017. First of all, you cannot really compare \MKII\ with \MKIV: the
+later has more functionality (or a more advanced implementation of
+functionality). And as mentioned you can also not really compare \PDFTEX\ and the
+wide engines. Anyway, here are some (useless) tests. First a bunch of loads. Keep
+in mind that different engines also deal differently with reading files. For
+instance \MKIV\ uses \LUATEX\ callbacks to normalize the input and has its own
+readers. There is a bit more overhead in starting up a \LUATEX\ run and some
+functionality is enabled that is not present in \MKII. The format is also larger,
+if only because we preload a lot of useful font, character and script related
+data.
+
+\starttyping
+\starttext
+ \dorecurse {#1} {
+ \input knuth
+ \par
+ }
+\stoptext
+\stoptyping
+
+When looking at the numbers one should realize that the times include startup and
+job management by the runner scripts. We also run in batchmode to avoid logging
+to influence runtime. The average is calculated from 5 runs.
+
+% sample 1, number of runs: 5
+
+\starttabulate[||r|r|r|]
+\HL
+\BC engine \BC 50 \BC 500 \BC 2500 \NC \NR
+\HL
+\BC pdftex \NC 0.43 \NC 0.77 \NC 2.33 \NC \NR
+\BC xetex \NC 0.85 \NC 2.66 \NC 10.79 \NC \NR
+\BC luatex \NC 0.94 \NC 2.50 \NC 9.44 \NC \NR
+\BC luajittex \NC 0.68 \NC 1.69 \NC 6.34 \NC \NR
+\HL
+\stoptabulate
+
+The second example does a few switches in a paragraph:
+
+\starttyping
+\starttext
+ \dorecurse {#1} {
+ \tf \input knuth
+ \bf \input knuth
+ \it \input knuth
+ \bs \input knuth
+ \par
+ }
+\stoptext
+\stoptyping
+
+% sample 2, number of runs: 5
+
+\starttabulate[||r|r|r|]
+\HL
+\BC engine \BC 50 \BC 500 \BC 2500 \NC \NR
+\HL
+\BC pdftex \NC 0.58 \NC 2.10 \NC 8.97 \NC \NR
+\BC xetex \NC 1.47 \NC 8.66 \NC 42.50 \NC \NR
+\BC luatex \NC 1.59 \NC 8.26 \NC 38.11 \NC \NR
+\BC luajittex \NC 1.12 \NC 5.57 \NC 25.48 \NC \NR
+\HL
+\stoptabulate
+
+The third examples does a few more, resulting in multiple subranges
+per style:
+
+\starttyping
+\starttext
+ \dorecurse {#1} {
+ \tf \input knuth \it knuth
+ \bf \input knuth \bs knuth
+ \it \input knuth \tf knuth
+ \bs \input knuth \bf knuth
+ \par
+ }
+\stoptext
+\stoptyping
+
+% sample 3, number of runs: 5
+
+\starttabulate[||r|r|r|]
+\HL
+\BC engine \BC 50 \BC 500 \BC 2500 \NC \NR
+\HL
+\BC pdftex \NC 0.59 \NC 2.20 \NC 9.52 \NC \NR
+\BC xetex \NC 1.49 \NC 8.88 \NC 43.85 \NC \NR
+\BC luatex \NC 1.64 \NC 8.91 \NC 41.26 \NC \NR
+\BC luajittex \NC 1.15 \NC 5.91 \NC 27.15 \NC \NR
+\HL
+\stoptabulate
+
+The last example adds some color. Enabling more functionality can have an impact
+on performance. In fact, as \MKIV\ uses a lot of \LUA\ and is also more advanced
+that \MKII, one can expect a performance hit but in practice the opposite
+happens, which can also be due to some fundamental differences deep down at the
+macro level.
+
+\starttyping
+\setupcolors[state=start] % default in MkIV
+
+\starttext
+ \dorecurse {#1} {
+ {\red \tf \input knuth \green \it knuth}
+ {\red \bf \input knuth \green \bs knuth}
+ {\red \it \input knuth \green \tf knuth}
+ {\red \bs \input knuth \green \bf knuth}
+ \par
+ }
+\stoptext
+\stoptyping
+
+% sample 4, number of runs: 5
+
+\starttabulate[||r|r|r|]
+\HL
+\BC engine \BC 50 \BC 500 \BC 2500 \NC \NR
+\HL
+\BC pdftex \NC 0.61 \NC 2.36 \NC 10.33 \NC \NR
+\BC xetex \NC 1.53 \NC 9.25 \NC 45.59 \NC \NR
+\BC luatex \NC 1.65 \NC 8.91 \NC 41.32 \NC \NR
+\BC luajittex \NC 1.15 \NC 5.93 \NC 27.34 \NC \NR
+\HL
+\stoptabulate
+
+In these measurements the accuracy is a few decimals but a pattern is visible. As
+expected \PDFTEX\ wins on simple documents but starts loosing when things get
+more complex. For these tests I used 64 bit binaries. A 32 bit \XETEX\ with
+\MKII\ performs the same as \LUAJITTEX\ with \MKIV, but a 64 bit \XETEX\ is
+actually quite a bit slower. In that case the mingw cross compiled \LUATEX\
+version does pretty well. A 64 bit \PDFTEX\ is also slower (it looks) that a 32
+bit version. So in the end, there are more factors that play a role. Choosing
+between \LUATEX\ and \LUAJITTEX\ depends on how well the memory limited
+\LUAJITTEX\ variant can handle your documents and fonts.
+
+Because in most of our recent styles we use \OPENTYPE\ fonts and (structural)
+features as well as recent \METAFUN\ extensions only present in \MKIV\ we cannot
+compare engines using such documents. The mentioned performance of \LUATEX\ (or
+\LUAJITTEX) and \MKIV\ on the \METAFUN\ manual illustrate that in most cases this
+combination is a clear winner.
+
+\starttyping
+\starttext
+ \dorecurse {#1} {
+ \null \page
+ }
+\stoptext
+\stoptyping
+
+This gives:
+
+% sample 5, number of runs: 5
+
+\starttabulate[||r|r|r|]
+\HL
+\BC engine \BC 50 \BC 500 \BC 2500 \NC \NR
+\HL
+\BC pdftex \NC 0.46 \NC 1.05 \NC 3.72 \NC \NR
+\BC xetex \NC 0.73 \NC 1.80 \NC 6.56 \NC \NR
+\BC luatex \NC 0.84 \NC 1.44 \NC 4.07 \NC \NR
+\BC luajittex \NC 0.61 \NC 1.10 \NC 3.33 \NC \NR
+\HL
+\stoptabulate
+
+That leaves the zero run:
+
+\starttyping
+\starttext
+ \dorecurse {#1} {
+ % nothing
+ }
+\stoptext
+\stoptyping
+
+This gives the following numbers. In longer runs the difference in overhead is
+neglectable.
+
+% sample 6, number of runs: 5
+
+\starttabulate[||r|r|r|]
+\HL
+\BC engine \BC 50 \BC 500 \BC 2500 \NC \NR
+\HL
+\BC pdftex \NC 0.36 \NC 0.36 \NC 0.36 \NC \NR
+\BC xetex \NC 0.57 \NC 0.57 \NC 0.59 \NC \NR
+\BC luatex \NC 0.74 \NC 0.74 \NC 0.74 \NC \NR
+\BC luajittex \NC 0.53 \NC 0.53 \NC 0.54 \NC \NR
+\HL
+\stoptabulate
+
+It will be clear that when we use different fonts the numbers will also be
+different. And if you use a lot of runtime \METAPOST\ graphics (for instance for
+backgrounds), the \MKIV\ runs end up at the top. And when we process \XML\ it
+will be clear that going back to \MKII\ is no longer a realistic option. It must
+be noted that I occasionally manage to improve performance but we've now reached
+a state where there is not that much to gain. Some functionality is hard to
+compare. For instance in \CONTEXT\ we don't use much of the \PDF\ backend
+features because we implement them all in \LUA. In fact, even in \MKII\ already a
+done in \TEX, so in the end the speed difference there is not large and often in
+favour of \MKIV.
+
+For the record I mention that shipping out the about 1250 pages has some overhead
+too: about 2 seconds. Here \LUAJITTEX\ is 20\% more efficient which is an
+indication of quite some \LUA\ involvement. Loading the input files has an
+overhead of about half a second. Starting up \LUATEX\ takes more time that
+\PDFTEX\ and \XETEX, but that disadvantage disappears with more pages. So, in the
+end there are quite some factors that blur the measurements. In practice what
+matters is convenience: does the runtime feel reasonable and in most cases it
+does.
+
+If I would replace my laptop with a reasonable comparable alternative that one
+would be some 35\% faster (single threads on processors don't gain much per year).
+I guess that this is about the same increase in performance that \CONTEXT\
+\MKIV\ got in that period. I don't expect such a gain in the coming years so
+at some point we're stuck with what we have.
+
+\stopsection
+
+\startsection[title=Summary]
+
+So, how \quotation {slow} is \LUATEX\ really compared to the other engines? If we
+go back in time to when the first wide engines showed up, \OMEGA\ was considered
+to be slow, although I never tested that myself. Then, when \XETEX\ showed up,
+there was not much talk about speed, just about the fact that we could use
+\OPENTYPE\ fonts and native \UTF\ input. If you look at the numbers, for sure you
+can say that it was much slower than \PDFTEX. So how come that some people
+complain about \LUATEX\ being so slow, especially when we take into account that
+it's not that much slower than \XETEX, and that \LUAJITTEX\ is often faster that
+\XETEX. Also, computers have become faster. With the wide engines you get more
+functionality and that comes at a price. This was accepted for \XETEX\ and is
+also acceptable for \LUATEX. But the price is nto that high if you take into
+account that hardware performs better: you just need to compare \LUATEX\ (and
+\XETEX) runtime with \PDFTEX\ runtime 15 years ago.
+
+As a comparison, look at games and video. Resolution became much higher as did
+color depth. Higher frame rates were in demand. Therefore the hardware had to
+become faster and it did, and as a result the user experience kept up. No user
+will say that a modern game is slower than an old one, because the old one does
+500 frames per second compared to some 50 for the new game on the modern
+hardware. In a similar fashion, the demands for typesetting became higher:
+\UNICODE, \OPENTYPE, graphics, \XML, advanced \PDF, more complex (niche)
+typesetting, etc. This happened more or less in parallel with computers becoming
+more powerful. So, as with games, the user experience didn't degrade with
+demands. Comparing \LUATEX\ with \PDFTEX\ is like comparing a low res, low frame
+rate, low color game with a modern one. You need to have up to date hardware and
+even then, the writer of such programs need to make sure it runs efficient,
+simply because hardware no longer scales like it did decades ago. You need to
+look at the larger picture.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/onandon/onandon-seguiemj.pdf b/doc/context/sources/general/manuals/onandon/onandon-seguiemj.pdf
new file mode 100644
index 000000000..02b2bd271
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-seguiemj.pdf
Binary files differ
diff --git a/doc/context/sources/general/manuals/onandon/onandon-seguiemj.tex b/doc/context/sources/general/manuals/onandon/onandon-seguiemj.tex
new file mode 100644
index 000000000..eff8a6acb
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-seguiemj.tex
@@ -0,0 +1,54 @@
+% language=uk
+
+\environment onandon-environment
+
+\setuppagenumbering[alternative=singlesided]
+
+\definefontfeature[seguiemj-cl][default][colr=yes,ccmp=yes,dist=yes]
+
+\definefont[MyEmojiLargeOld][seguiemj-old*seguiemj-cl @ 100pt]
+\definefont[MyEmojiLargeNew][seguiemj*seguiemj-cl @ 100pt]
+
+\def\ShowThem#1%
+ {\ruledhbox{\MyEmojiLargeOld\resolvedemoji{#1}}%
+ \quad
+ \ruledhbox{\MyEmojiLargeNew\resolvedemoji{#1}}}
+
+\def\ShowGone#1%
+ {\setbox\scratchbox\ruledhbox{\MyEmojiLargeOld\resolvedemoji{#1}}%
+ \copy\scratchbox
+ \quad
+ \ruledhbox to \wd\scratchbox
+ {\lower\dp\scratchbox\vbox to \htdp\scratchbox
+ {\vss
+ \hbox to \wd\scratchbox{\hss no longer supported\hss}%
+ \vss}}}
+
+\starttext
+
+\startTEXpage[offset=.5pt]
+\startcombination[2*5]
+ {\ShowThem{family woman woman girl boy}}%
+ {family woman woman girl boy}
+ {\ShowThem{family woman woman boy boy}}%
+ {family woman woman boy boy}
+ {\ShowThem{family woman girl boy}}
+ {family woman girl boy}
+ {\ShowThem{family man dark skin tone woman girl baby}}
+ {family man dark skin tone woman girl baby}
+ {\ShowThem{family man light skin tone woman light skin tone girl dark skin tone}}
+ {family man light skin tone woman light skin tone girl dark skin tone}
+ {\ShowThem{family man girl boy}}
+ {family man girl boy}
+ {\ShowThem{family man man girl boy}}%
+ {family man man girl boy}
+ {\ShowThem{family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone}}
+ {family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone}
+ {\ShowGone{couple with heart man light skin tone man medium-dark skin tone}}
+ {couple with heart man light skin tone man medium-dark skin tone}
+ {\ShowGone{kiss man medium-light skin tone man dark skin tone}}
+ {kiss man medium-light skin tone man dark skin tone}
+\stopcombination
+\stopTEXpage
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/onandon/onandon-speed-000.tex b/doc/context/sources/general/manuals/onandon/onandon-speed-000.tex
new file mode 100644
index 000000000..f48af866d
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-speed-000.tex
@@ -0,0 +1,116 @@
+% \startenvironment onandon-speed-000
+
+% \dontcomplain
+
+\edef\sapolsky{\ignorespaces\cldloadfile{sapolsky}\removeunwantedspaces}
+
+\startluacode
+
+ function document.ResetSample(title)
+ document.elapsed = {
+ title = title,
+ times = { },
+ }
+ end
+
+ function document.RegisterSample(bodyfont,elapsed)
+ table.insert(document.elapsed.times, {
+ bodyfont = bodyfont,
+ elapsed = elapsed
+ })
+ end
+
+ function document.SaveSample()
+ if LUATEXENGINE == "luajittex" then
+ table.save(tex.jobname.."-jit.lua",document.elapsed)
+ else
+ table.save(tex.jobname..".lua",document.elapsed)
+ end
+ end
+
+ function document.ShowSample(filename)
+ -- context.typefile(filename..".tex")
+ local elapsed = table.load(file.nameonly(filename)..".lua")
+ local elapsedjit = table.load(file.nameonly(filename).."-jit.lua")
+ if elapsed and elapsedjit then
+ context.testpage { 6 }
+ context.starttabulate { "|l|l|lp|" }
+ context.HL()
+ context.NC() context.formatted.rlap("\\bf %s",elapsed.title)
+ context.NC()
+ context.NC()
+ context.NC() context.NR()
+ context.HL()
+ local times = elapsed.times
+ local timesjit = elapsedjit.times
+ for j=1,#times do
+ local t = times[j]
+ local tjit = timesjit[j]
+ context.NC() context(t.bodyfont)
+ context.NC() context(t.elapsed)
+ context.NC() context(tjit.elapsed)
+ context.NC() context.NR()
+ end
+ context.HL()
+ context.stoptabulate()
+ end
+ end
+
+ function document.SampleTitle(filename)
+ local elapsed = table.load(filename..".lua")
+ if elapsed then
+ context(elapsed.title)
+ end
+ end
+\stopluacode
+
+\appendtoks
+ \ctxlua{document.SaveSample()}%
+\to \everystoptext
+
+\def\SampleCount{1000}
+\def\SampleCount{100}
+
+\unexpanded\def\RegisterSample#1%
+ {\ctxlua{document.RegisterSample("#1","\elapsedtime")}}
+
+\unexpanded\def\ProcessSample#1%
+ {\page
+ \ctxlua{document.ResetSample("#1")}%
+ \resettimer \Sample {modern} \RegisterSample {modern}
+ \resettimer \Sample {pagella} \RegisterSample {pagella}
+ \resettimer \Sample {termes} \RegisterSample {termes}
+ \resettimer \Sample {cambria} \RegisterSample {cambria}
+ \resettimer \Sample {dejavu} \RegisterSample {dejavu}
+ \resettimer \Sample {ebgaramond} \RegisterSample {ebgaramond}
+ \resettimer \Sample {lucidaot} \RegisterSample {lucidaot}
+ \page }
+
+\unexpanded\def\ProcessBaselineSample#1%
+ {\page
+ \ctxlua{document.ResetSample("#1")}%
+ \resettimer \Sample {baseline} \RegisterSample {baseline}
+ \page }
+
+\unexpanded\def\Sample#1%
+ {\setupbodyfont[#1]}
+
+\unexpanded\def\ShowSample#1%
+ {\ctxlua{document.ShowSample("#1")}}
+
+\unexpanded\def\SampleTitle#1%
+ {\ctxlua{document.SampleTitle("#1.lua")}}
+
+\continueifinputfile{onandon-speed-000.tex}
+
+\starttext
+
+\ProcessSample{bodyfont}
+
+\setbox\scratchbox\vbox{\hsize1pt\tttf\sapolsky} \getnoflines{\htdp\scratchbox}
+
+\writestatus{!!!!!!}{noflines : \the\noflines}
+
+\stoptext
+
+% \stopenvironment
diff --git a/doc/context/sources/general/manuals/onandon/onandon-speed-001.tex b/doc/context/sources/general/manuals/onandon/onandon-speed-001.tex
new file mode 100644
index 000000000..b6c241752
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-speed-001.tex
@@ -0,0 +1,15 @@
+\environment onandon-speed-000
+
+\ProcessSample{bodyfont} \setupbodyfont[dejavu]
+
+\starttext
+
+\def\Sample#1%
+ {\start
+ \switchtobodyfont[#1]
+ \setbox\scratchbox\hbox{\tf\bf\it\bi}%
+ \stop}
+
+\ProcessSample{bodyfont switch and 4 style changes (first time)}
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/onandon/onandon-speed-002.tex b/doc/context/sources/general/manuals/onandon/onandon-speed-002.tex
new file mode 100644
index 000000000..edd6dd0f7
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-speed-002.tex
@@ -0,0 +1,16 @@
+\environment onandon-speed-000
+
+\ProcessSample{bodyfont} \setupbodyfont[dejavu]
+
+\starttext
+
+\def\Sample#1%
+ {\start
+ \switchtobodyfont[#1]
+ \setbox\scratchbox\hbox{\tf\bf\it\bi}%
+ \stop}
+
+\ProcessSample{bodyfont switch and 4 style changes (first time)}
+\ProcessSample{bodyfont switch and 4 style changes (follow up)}
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/onandon/onandon-speed-003.tex b/doc/context/sources/general/manuals/onandon/onandon-speed-003.tex
new file mode 100644
index 000000000..4362ccb4f
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-speed-003.tex
@@ -0,0 +1,15 @@
+\environment onandon-speed-000
+
+\ProcessSample{bodyfont} \setupbodyfont[dejavu]
+
+\starttext
+
+\def\Sample#1%
+ {\start
+ \switchtobodyfont[#1]
+ \dorecurse\SampleCount{\setbox\scratchbox\hbox{\sapolsky\space\sapolsky\space\sapolsky\space\sapolsky}}%
+ \stop}
+
+\ProcessSample{\SampleCount\space hboxes with 4 texts using one font}
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/onandon/onandon-speed-005.tex b/doc/context/sources/general/manuals/onandon/onandon-speed-005.tex
new file mode 100644
index 000000000..7aeb53b4b
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-speed-005.tex
@@ -0,0 +1,17 @@
+\environment onandon-speed-000
+
+\ProcessSample{bodyfont} \setupbodyfont[dejavu]
+
+\starttext
+
+\def\Sample#1%
+ {\start
+ \switchtobodyfont[#1]
+ \dorecurse\SampleCount{\sapolsky\space\sapolsky\space\sapolsky\space\sapolsky\par}%
+ \stop}
+
+\startlayout[page]
+ \ProcessSample{\SampleCount\space times 4 texts on pages}
+\stoplayout
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/onandon/onandon-speed-006.tex b/doc/context/sources/general/manuals/onandon/onandon-speed-006.tex
new file mode 100644
index 000000000..d15ef428e
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-speed-006.tex
@@ -0,0 +1,17 @@
+\environment onandon-speed-000
+
+\ProcessSample{bodyfont} \setupbodyfont[dejavu]
+
+\starttext
+
+\def\Sample#1%
+ {\start
+ \switchtobodyfont[#1]
+ \dorecurse\SampleCount{\tf\sapolsky\space\bf\sapolsky\space\it\sapolsky\space\bi\sapolsky\space\par}%
+ \stop}
+
+\startlayout[page]
+ \ProcessSample{\SampleCount\space times 4 texts on pages using 4 styles}
+\stoplayout
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/onandon/onandon-speed-007.tex b/doc/context/sources/general/manuals/onandon/onandon-speed-007.tex
new file mode 100644
index 000000000..7a4eed497
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-speed-007.tex
@@ -0,0 +1,31 @@
+\environment onandon-speed-000
+
+\ProcessSample{bodyfont} \setupbodyfont[dejavu]
+
+\starttext
+
+\def\sapolsky{%
+ Agriculture is a fairly recent human invention, and in many ways it was one of
+ the great {\bf stupid} moves of all time. Hunter|-|gatherers have thousands of wild
+ sources of food to subsist on. Agriculture changed that all, generating an
+ overwhelming reliance on a few dozen domesticated food sources, making you
+ extremely vulnerable to the next famine, the next locust infestation, the next
+ potato blight. Agriculture allowed for stockpiling of surplus resources and thus,
+ {\bf inevitably}, the unequal stockpiling of them --- stratification of society and
+ the invention of classes. Thus, it allowed for the invention of poverty. I think
+ that the punch line of the primate|-|human difference is that when humans
+ invented poverty, they came up with a way of subjugating the low|-|ranking like
+ {\bf nothing ever seen before} in the primate world.
+}%
+
+\def\Sample#1%
+ {\start
+ \switchtobodyfont[#1]
+ \dorecurse\SampleCount{\sapolsky\par}%
+ \stop}
+
+\startlayout[page]
+ \ProcessSample{\SampleCount\space texts on pages with [1,2,4] bold font switches}
+\stoplayout
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/onandon/onandon-speed-008.tex b/doc/context/sources/general/manuals/onandon/onandon-speed-008.tex
new file mode 100644
index 000000000..ae968bc10
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-speed-008.tex
@@ -0,0 +1,32 @@
+\environment onandon-speed-000
+
+\ProcessSample{bodyfont} \setupbodyfont[dejavu]
+
+\starttext
+
+\def\sapolsky{%
+ Agriculture is a fairly recent human invention, and in many ways it was one
+ of the great \type {stupid} moves of all time. Hunter|-|gatherers have
+ thousands of wild sources of food to subsist on. Agriculture changed that
+ all, generating an overwhelming reliance on a few dozen domesticated food
+ sources, making you extremely vulnerable to the next famine, the next locust
+ infestation, the next potato blight. Agriculture allowed for stockpiling of
+ surplus resources and thus, \type {inevitably}, the unequal stockpiling of
+ them --- stratification of society and the invention of classes. Thus, it
+ allowed for the invention of poverty. I think that the punch line of the
+ primate|-|human difference is that when humans invented poverty, they came up
+ with a way of subjugating the low|-|ranking like \type {nothing ever seen
+ before} in the primate world.
+}%
+
+\def\Sample#1%
+ {\start
+ \switchtobodyfont[#1]
+ \dorecurse\SampleCount{\sapolsky\par}%
+ \stop}
+
+\startlayout[page]
+ \ProcessSample{\SampleCount\space texts on pages with [1,2,4] word verbatim switches}
+\stoplayout
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/onandon/onandon-speed-009.tex b/doc/context/sources/general/manuals/onandon/onandon-speed-009.tex
new file mode 100644
index 000000000..61116e652
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-speed-009.tex
@@ -0,0 +1,15 @@
+\environment onandon-speed-000
+
+\ProcessSample{bodyfont} \setupbodyfont[dejavu]
+
+\starttext
+
+\def\Sample#1%
+ {\start
+ \infofont
+ \dorecurse\SampleCount{\setbox\scratchbox\hpack{\sapolsky\space\sapolsky\space\sapolsky\space\sapolsky}}%
+ \stop}
+
+\ProcessBaselineSample{\SampleCount\space hboxes with 4 texts and no font handling}
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/onandon/onandon-speed-010.tex b/doc/context/sources/general/manuals/onandon/onandon-speed-010.tex
new file mode 100644
index 000000000..673c2b1e5
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-speed-010.tex
@@ -0,0 +1,15 @@
+\environment onandon-speed-000
+
+\ProcessSample{bodyfont} \setupbodyfont[dejavu]
+
+\starttext
+
+\def\Sample#1%
+ {\start
+ \infofont
+ \dorecurse\SampleCount{\setbox\scratchbox\hbox{\sapolsky\space\sapolsky\space\sapolsky\space\sapolsky}}%
+ \stop}
+
+\ProcessBaselineSample{\SampleCount\space hboxes with 4 texts and no features}
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/onandon/onandon-speed-011.tex b/doc/context/sources/general/manuals/onandon/onandon-speed-011.tex
new file mode 100644
index 000000000..90d924c00
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-speed-011.tex
@@ -0,0 +1,20 @@
+\environment onandon-speed-000
+
+\ProcessSample{bodyfont} \setupbodyfont[dejavu]
+
+\dontcomplain
+
+\starttext
+
+\def\Sample#1%
+ {\start
+ \tttf\tx
+ \dorecurse\SampleCount{\sapolsky\space\sapolsky\space\sapolsky\space\sapolsky\par}%
+ \stop}
+
+\startlayout[page]
+ \ProcessBaselineSample {\SampleCount\space paragraphs with 4 texts and no features}
+\stoplayout
+
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/onandon/onandon-speed-012.tex b/doc/context/sources/general/manuals/onandon/onandon-speed-012.tex
new file mode 100644
index 000000000..e2d51e195
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-speed-012.tex
@@ -0,0 +1,20 @@
+\environment onandon-speed-000
+
+\ProcessSample{bodyfont} \setupbodyfont[dejavu]
+
+\dontcomplain
+
+\starttext
+
+\def\SampleCount{1000}
+
+\def\Sample#1%
+ {\start
+% \switchtobodyfont[#1]
+ \dorecurse\SampleCount{\sapolsky\par}
+ \stop}
+
+% \ProcessSample{\SampleCount\space pages no features}
+\ProcessBaselineSample{\SampleCount\space paragraphs text}
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/onandon/onandon-variable.tex b/doc/context/sources/general/manuals/onandon/onandon-variable.tex
new file mode 100644
index 000000000..c73196cef
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-variable.tex
@@ -0,0 +1,557 @@
+% language=uk
+
+% todo: callback: stream, llx, lly, urx, ury, wd, lsb
+% add glyphs runtime
+% create whole cff so that we can go from mp
+
+\startcomponent onandon-variable
+
+\environment onandon-environment
+
+\startchapter[title=Variable fonts]
+
+\startsubject[title=Introduction]
+
+History shows the tendency to recycle ideas. Often quite some effort is made by
+historians to figure out what really happened, not just long ago, when nothing
+was written down and we have to do with stories or pictures at most, but also in
+recent times. Descriptions can be conflicting, puzzling, incomplete, partially
+lost, biased, \unknown
+
+Just as language was invented (or evolved) several times, so were scripts. The
+same might be true for rendering scripts on a medium. Semaphores came and went
+within decades and how many people know now that they existed and that encryption
+was involved? Are the old printing presses truly the old ones, or are older
+examples simply gone? One of the nice aspects of the internet is that one can now
+more easily discover similar solutions for the same problem, but with a different
+(and independent) origin.
+
+So, how about this \quotation {new big thing} in font technology: variable fonts.
+In this case, history shows that it's not that new. For most \TEX\ users the
+names \METAFONT\ and \METAPOST\ will ring bells. They have a very well documented
+history so there is not much left to speculation. There are articles, books,
+pictures, examples, sources, and more around for decades. So, the ability to
+change the appearance of a glyph in a font depending on some parameters is not
+new. What probably {\em is} new is that creating variable fonts is done in the
+natural environment where fonts are designed: an interactive program. The
+\METAFONT\ toolkit demands quite some insight in programming shapes in such a way
+that one can change look and feel depending on parameters. There are not that
+many meta fonts made and one reason is that making them requires a certain mind-
+and skill set. On the other hand, faster computers, interactive programs,
+evolving web technologies, where rea|l|-time rendering and therefore more or less
+real-time tweaking of fonts is a realistic option, all play a role in acceptance.
+
+But do interactive font design programs make this easier? You still need to be
+able to translate ideas into usable beautiful fonts. Taking the common shapes of
+glyphs, defining extremes and letting a program calculate some interpolations
+will not always bring good results. It's like morphing a picture of your baby's
+face into yours of old age (or that of your grandparent): not all intermediate
+results will look great. It's good to notice that variable fonts are a revival of
+existing techniques and ideas used in, for instance, multiple master fonts. The
+details might matter even more as they can now be exaggerated when some
+transformation is applied.
+
+There is currently (March 2017) not much information about these fonts so what I
+say next may be partially wrong or at least different from what is intended. The
+perspective will be one from a \TEX\ user and coder. Whatever you think of them,
+these fonts will be out there and for sure there will be nice examples
+circulating soon. And so, when I ran into a few experimental fonts, with
+\POSTSCRIPT\ and \TRUETYPE\ outlines, I decided to have a look at what is inside.
+After all, because it's visual, it's also fun to play with. Let's stress that at
+the moment of this writing I only have a few simple fonts available, fonts that
+are designed for testing and not usage. Some recommended tables were missing and
+no complex \OPENTYPE\ features are used in these fonts.
+
+\stopsubject
+
+\startsubject[title=The specification]
+
+I'm not that good at reading specifications, first of all because I quickly fall
+asleep with such documents, but most of all because I prefer reading other stuff
+(I do have lots of books waiting to be read). I'm also someone who has to play
+with something in order to understand it: trial and error is my modus operandi.
+Eventually it's my intended usage that drives the interface and that is when
+everything comes together.
+
+Exploring this technology comes down to: locate a font, get the \OPENTYPE\ 1.8
+specification from the \MICROSOFT\ website, and try to figure out what is in the
+font. When I had a rough idea the next step was to get to the shapes and see if I
+could manipulate them. Of course it helped that in \CONTEXT\ we already can load
+fonts and play with shapes (using \METAPOST). I didn't have to install and learn
+other programs. Once I could render them, in this case by creating a virtual font
+with inline \PDF\ literals, a next step was to apply variation. Then came the
+first experiments with a possible user interface. Seeing more variation then
+drove the exploration of additional properties needed for typesetting, like
+features.
+
+The main extension to the data packaged in a font file concerns the (to be
+discussed) axis along which variable fonts operate and deltas to be applied to
+coordinates. The \type {gdef} table has been extended and contains information
+that is used in \type {gpos} features. There are new \type {hvar}, \type {vvar}
+and \type {mvar} tables that influence the horizontal, vertical and general font
+dimensions. The \type {gvar} table is used for \TRUETYPE\ variants, while the
+\type {cff2} table replaces the \type {cff} table for \OPENTYPE\ \POSTSCRIPT\
+outlines. The \type {avar} and \type {stat} tables contain some
+meta|-|information about the axes of variations.
+
+It must be said that because this is new technology the information in the
+standard is not always easy to understand. The fact that we have two rendering
+techniques, \POSTSCRIPT\ \type {cff} and \TRUETYPE\ \type {ttf}, also means that
+we have different information and perspectives. But this situation is not much
+different from \OPENTYPE\ standards a few years ago: it takes time but in the end
+I will get there. And, after all, users also complain about the lack of
+documentation for \CONTEXT, so who am I to complain? In fact, it will be those
+\CONTEXT\ users who will provide feedback and make the implementation better in
+the~end.
+
+\stopsubject
+
+\startsubject[title=Loading]
+
+Before we discuss some details, it will be useful to summarize what the font
+loader does when a user requests a font at a certain size and with specific
+features enabled. When a font is used the first time, its binary format is
+converted into a form that makes it suitable for use within \CONTEXT\ and
+therefore \LUATEX. This conversion involves collecting properties of the font as
+a whole (official names, general dimensions like x-height and em-width, etc.), of
+glyphs (dimensions, \UNICODE\ properties, optional math properties), and all
+kinds of information that relates to (contextual) replacements of glyphs (small
+caps, oldstyle, scripts like Arabic) and positioning (kerning, anchoring marks,
+etc.). In the \CONTEXT\ font loader this conversion is done in \LUA.
+
+The result is stored in a condensed format in a cache and the next time the font
+is needed it loads in an instant. In the cached version the dimensions are
+untouched, so a font at different sizes has just one copy in the cache. Often a
+font is needed at several sizes and for each size we create a copy with scaled
+glyph dimensions. The feature-related dimensions (kerning, anchoring, etc.)\ are
+shared and scaled when needed. This happens when sequences of characters in the
+node list get converted into sequences of glyphs. We could do the same with glyph
+dimensions but one reason for having a scaled copy is that this copy can also
+contain virtual glyphs and these have to be scaled beforehand. In practice there
+are several layers of caching in order to keep the memory footprint within
+reasonable bounds. \footnote {In retrospect one can wonder if that makes sense;
+just look at how much memory a browser uses when it has been open for some time.
+In the beginning of \LUATEX\ users wondered about caching fonts, but again, just
+look at what amounts browsers cache: it gets pretty close to the average amount
+of writes that a \SSD\ can handle per day within its guarantee.}
+
+When the font is actually used, interaction between characters is resolved using
+the feature|-|related information. When for instance two characters need to be
+kerned, a lookup results in the injection of a kern, scaled from general
+dimensions to the current size of the font.
+
+When the outlines of glyphs are needed in \METAFUN\ the font is also converted
+from its binary form to something in \LUA, but this time we filter the shapes.
+For a \type {cff} this comes down to interpreting the \type {charstrings} and
+reducing the complexity to \type {moveto}, \type {lineto} and \type {curveto}
+operators. In the process subroutines are inlined. The result is something that
+\METAPOST\ is happy with but that also can be turned into a piece of a \PDF.
+
+We now come to what a variable font actually is: a basic design which is
+transformed along one or more axes. A simple example is wider shapes:
+
+\startlinecorrection
+\startMPcode
+for i=1 upto 4 :
+ fill fullsquare xyscaled (i*.5cm,1cm) shifted (i*2.5*cm,0) withcolor "darkgray";
+ fill fullcircle xyscaled (2.5mm,2.5mm) shifted (i*2.5*cm,0) withcolor "lightgray" ;
+endfor ;
+\stopMPcode
+\stoplinecorrection
+
+We can also go taller and retain the width:
+
+\startlinecorrection
+\startMPcode
+for i=1 upto 4 :
+ fill fullsquare xyscaled (1cm,i*.5cm) shifted (i*2.5*cm,0) withcolor "darkgray";
+ fill fullcircle xyscaled (2.5mm,2.5mm) shifted (i*2.5*cm,0) withcolor "lightgray" ;
+endfor ;
+\stopMPcode
+\stoplinecorrection
+
+Here we have a linear scaling but glyphs are not normally done that way. There
+are font collections out there with lots of intermediate variants (say from light
+to heavy) and it's more profitable to sell each variant independently. However,
+there is often some logic behind it, probably supported by programs that
+designers use, so why not build that logic into the font and have one file that
+represents many intermediate forms. In fact, once we have multiple axes, even
+when the designer has clear ideas of the intended usage, nothing will prevent
+users from tinkering with the axis properties in ways that will fulfil their
+demands but hurt the designers eyes. We will not discuss that dilemma here.
+
+When a variable font follows the route described above, we face a problem. When
+you load a \TRUETYPE\ font it will just work. The glyphs are packaged in the same
+format as static fonts. However, a variable font has axes and on each axis a
+value can be set. Each axis has a minimum, maximum and default. It can be that
+the default instance also assumes some transformations are applied. The standard
+recommends adding tables to describe these things but the fonts that I played
+with each lacked such tables. So that leaves some guesswork. But still, just
+loading a \TRUETYPE\ font gives some sort of outcome, although the dimensions
+(widths) might be weird due to lack of a (default) axis being applied.
+
+An \OPENTYPE\ font with \POSTSCRIPT\ outlines is different: the internal \type
+{cff} format has been upgraded to \type {cff2} which on the one hand is less
+complicated but on the other hand has a few new operators \emdash\ which results
+in programs that have not been adapted complaining or simply quitting on them.
+
+One could argue that a font is just a resource and that one only has to pass it
+along but that's not what works well in practice. Take \LUATEX. We can of course
+load the font and apply axis vales so that we can process the document as we
+normally do. But at some point we have to create a \PDF. We can simply embed the
+\TRUETYPE\ files but no axis values are applied. This is because, even if we add
+the relevant information, there is no way in current \PDF\ formats to deal with
+it. For that, we should be able to pass all relevant axis|-|related information
+as well as specify what values to use along these axes. And for \TRUETYPE\ fonts
+this information is not part of the shape description so then we in fact need to
+filter and pass more. An \OPENTYPE\ \POSTSCRIPT\ font is much cleaner because
+there we have the information needed to transform the shape mostly in the glyph
+description. There we only need to carry some extra information on how to apply
+these so|-|called blend values. The region|/|axis model used there only demands
+passing a relatively simple table (stripped down to what we need). But, as said
+above, \type {cff2} is not backward-compatible so a viewer will (currently)
+simply not show anything.
+
+Recalling how we load fonts, how does that translate with variable changes? If we
+have two characters with glyphs that get transformed and that have a kern between
+them, the kern may or may not transform. So, when we choose values on an axis,
+then not only glyph properties change but also relations. We no longer can share
+positional information and scale afterwards because each instance can have
+different values to start with. We could carry all that information around and
+apply it at runtime but because we're typesetting documents with a static design
+it's more convenient to just apply it once and create an instance. We can use the
+same caching as mentioned before but each chosen instance (provided by the font
+or made up by user specifications) is kept in the cache. As a consequence, using
+a variable font has no overhead, apart from initial caching.
+
+So, having dealt with that, how do we proceed? Processing a font is not different
+from what we already had. However, I would not be surprised if users are not
+always satisfied with, for instance, kerning, because in such fonts a lot of care
+has to be given to this by the designer. Of course I can imagine that programs
+used to create fonts deal with this, but even then, there is a visual aspect to
+it too. The good news is that in \CONTEXT\ we can manipulate features so in
+theory one can create a so|-|called font goodie file for a specific instance.
+
+\stopsubject
+
+\startsubject[title=Shapes]
+
+For \OPENTYPE\ \POSTSCRIPT\ shapes we always have to do a dummy rendering in
+order to get the right bounding box information. For \TRUETYPE\ this information
+is already present but not when we use a variable instance, so I had to do a bit
+of coding for that. Here we face a problem. For \TEX\ we need the width, height
+and depth of a glyph. Consider the following case:
+
+\startlinecorrection
+\startMPcode
+path p ; p := fullcircle xysized (3cm,2cm) ;
+fill p
+ withcolor "lightgray" ;
+draw boundingbox currentpicture
+ withpen pencircle scaled .5mm
+ withcolor "darkgray" ;
+setbounds currentpicture to p ;
+draw boundingbox currentpicture
+ leftenlarged 2mm rightenlarged 5mm ;
+\stopMPcode
+\stoplinecorrection
+
+The shape has a bounding box that fits the shape. However, its left corner is not
+at the origin. So, when we calculate a tight bounding box, we cannot use it for
+actually positioning the glyph. We do use it (for horizontal scripts) to get the
+height and depth but for the width we depend on an explicit value. In \OPENTYPE\
+\POSTSCRIPT\ we have the width available and how the shape is positioned relative
+to the origin doesn't much matter. In a \TRUETYPE\ shape a bounding box is part
+of the specification, as is the width, but for a variable font one has to use
+so-called phantom points to recalculate the width and the test fonts I had were
+not suitable for investigating this.
+
+At any rate, once I could generate documents with typeset text using variable
+fonts it became time to start thinking about a user interface. A variable font
+can have predefined instances but of course a user also wants to mess with axis
+values. Take one of the test fonts: Adobe Variable Font Prototype. It has several
+instances:
+
+\unexpanded\def\SampleFont#1#2#3%
+ {\NC #2
+ \NC \definedfont[name:#1#3*default]It looks like this!
+ \normalexpanded{\noexpand\NC\currentfontinstancespec}
+ \NC \NR}
+
+\starttabulate[|||T|]
+\SampleFont {adobevariablefontprototype} {extralight} {extralight}
+\SampleFont {adobevariablefontprototype} {light} {light}
+\SampleFont {adobevariablefontprototype} {regular} {regular}
+\SampleFont {adobevariablefontprototype} {semibold} {semibold}
+\SampleFont {adobevariablefontprototype} {bold} {bold}
+\SampleFont {adobevariablefontprototype} {black high contrast} {blackhighcontrast}
+\SampleFont {adobevariablefontprototype} {black medium contrast} {blackmediumcontrast}
+\SampleFont {adobevariablefontprototype} {black} {black}
+\stoptabulate
+
+Such an instance is accessed with:
+
+\starttyping
+\definefont
+ [MyLightFont]
+ [name:adobevariablefontprototypelight*default]
+\stoptyping
+
+The Avenir Next variable demo font (currently) provides:
+
+\starttabulate[|||T|]
+\SampleFont {avenirnextvariable} {regular} {regular}
+\SampleFont {avenirnextvariable} {medium} {medium}
+\SampleFont {avenirnextvariable} {bold} {bold}
+\SampleFont {avenirnextvariable} {heavy} {heavy}
+\SampleFont {avenirnextvariable} {condensed} {condensed}
+\SampleFont {avenirnextvariable} {medium condensed} {mediumcondensed}
+\SampleFont {avenirnextvariable} {bold condensed} {boldcondensed}
+\SampleFont {avenirnextvariable} {heavy condensed} {heavycondensed}
+\stoptabulate
+
+Before we continue I will show a few examples of variable shapes. Here we use some
+\METAFUN\ magic. Just take these definitions for granted.
+
+\startbuffer[a]
+\startMPcode
+ draw outlinetext.b
+ ("\definedfont[name:adobevariablefontprototypeextralight]foo@bar")
+ (withcolor "gray")
+ (withcolor red withpen pencircle scaled 1/10)
+ xsized .45TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[b]
+\startMPcode
+ draw outlinetext.b
+ ("\definedfont[name:adobevariablefontprototypelight]foo@bar")
+ (withcolor "gray")
+ (withcolor red withpen pencircle scaled 1/10)
+ xsized .45TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[c]
+\startMPcode
+ draw outlinetext.b
+ ("\definedfont[name:adobevariablefontprototypebold]foo@bar")
+ (withcolor "gray")
+ (withcolor red withpen pencircle scaled 1/10)
+ xsized .45TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\startbuffer[d]
+\startMPcode
+ draw outlinetext.b
+ ("\definefontfeature[whatever][axis={weight:350}]%
+ \definedfont[name:adobevariablefontprototype*whatever]foo@bar")
+ (withcolor "gray")
+ (withcolor red withpen pencircle scaled 1/10)
+ xsized .45TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[a,b,c,d]
+
+The results are shown in \in {figure} [fig:whatever:1]. What we see here is that
+as long as we fill the shape everything will look as expected but using an
+outline only won't. The crucial (control) points are moved to different locations
+and as a result they can end up inside the shape. Giving up outlines is the price
+we evidently need to pay. Of course this is not unique for variable fonts
+although in practice static fonts behave better. To some extent we're back to
+where we were with \METAFONT\ and (for instance) Computer Modern: because these
+originate in bitmaps (and probably use similar design logic) we also can have
+overlap and bits and pieces pasted together and no one will notice that. The
+first outline variants of Computer Modern also had such artifacts while in the
+static Latin Modern successors, outlines were cleaned up.
+
+\startplacefigure[title=Four variants,reference=fig:whatever:1]
+ \startcombination[2*2]
+ {\getbuffer[a]} {a}
+ {\getbuffer[b]} {b}
+ {\getbuffer[c]} {d}
+ {\getbuffer[d]} {c}
+ \stopcombination
+\stopplacefigure
+
+The fact that we need to preprocess an instance but only know how to do that when
+we have gotten the information about axis values from the font means that the
+font handler has to be adapted to keep caching correct. Another definition is:
+
+\starttyping
+\definefontfeature
+ [lightdefault]
+ [default]
+ [axis={weight:230,contrast:50}]
+
+\definefont
+ [MyLightFont]
+ [name:adobevariablefontprototype*lightdefault]
+\stoptyping
+
+Here the complication is that where normally features are dealt with after
+loading, the axis feature is part of the preparation (and caching). If you want
+the virtual font solution you can do this:
+
+\starttyping
+\definefontfeature
+ [inlinelightdefault]
+ [default]
+ [axis={weight:230,contrast:50},
+ variableshapes=yes]
+
+\definefont
+ [MyLightFont]
+ [name:adobevariablefontprototype*inlinelightdefault]
+\stoptyping
+
+When playing with these fonts it was hard to see if loading was done right. For
+instance not all values make sense. It is beyond the scope of this article, but
+axes like weight, width, contrast and italic values get applied differently to
+so|-|called regions (subspaces). So say that we have an $x$ coordinate with value
+$50$. This value can be adapted in, for instance, four subspaces (regions), so we
+actually get:
+
+\startformula
+ x^\prime = x
+ + s_1 \times x_1
+ + s_2 \times x_2
+ + s_3 \times x_3
+ + s_4 \times x_4
+\stopformula
+
+The (here) four scale factors $s_n$ are determined by the axis value. Each axis
+has some rules about how to map the values $230$ for weight and $50$ for contrast
+to such a factor. And each region has its own translation from axis values to
+these factors. The deltas $x_1,\dots,x_4$ are provided by the font. For a
+\POSTSCRIPT|-|based font we find sequences like:
+
+\starttyping
+1 <setvstore>
+120 [10 -30 40 -60] 1 <blend> ... <operator>
+100 120 [10 -30 40 -60] [30 -10 -30 20] 2 <blend> .. <operator>
+\stoptyping
+
+A store refers to a region specification. From there the factors are calculated
+using the chosen values on the axis. The deltas are part of the glyphs
+specification. Officially there can be multiple region specifications, but how
+likely it is that they will be used in real fonts is an open question.
+
+For \TRUETYPE\ fonts the deltas are not in the glyph specification but in a
+dedicated \type {gvar} table.
+
+\starttyping
+apply x deltas [10 -30 40 -60] to x 120
+apply y deltas [30 -10 -30 20] to y 100
+\stoptyping
+
+Here the deltas come from tables outside the glyph specification and their
+application is triggered by a combination of axis values and regions.
+
+The following two examples use Avenir Next Variable and demonstrate that kerning
+is adapted to the variant.
+
+\startbuffer
+\definefontfeature
+ [default:shaped]
+ [default]
+ [axis={width:10}]
+
+\definefont
+ [SomeFont]
+ [file:avenirnextvariable*default:shaped]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\start \showglyphs \showfontkerns \SomeFont \input zapf \wordright{Hermann Zapf}\par \stop
+
+\startbuffer
+\definefontfeature
+ [default:shaped]
+ [default]
+ [axis={width:100}]
+
+\definefont
+ [SomeFont]
+ [file:avenirnextvariable*default:shaped]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\start \showglyphs \showfontkerns \SomeFont \input zapf \wordright{Hermann Zapf}\par \stop
+
+\stopsubject
+
+\startsubject[title=Embedding]
+
+Once we're done typesetting and a \PDF\ file has to be created there are three
+possible routes:
+
+\startitemize
+ \startitem
+ We can embed the shapes as \PDF\ images (inline literal) using virtual
+ font technology. We cannot use so|-|called xforms here because we want to
+ support color selectively in text.
+ \stopitem
+ \startitem
+ We can wait till the \PDF\ format supports such fonts, which might happen
+ but even then we might be stuck for years with viewers getting there. Also
+ documents need to get printed, and when printer support might
+ arrive is another unknown.
+ \stopitem
+ \startitem
+ We can embed a regular font with shapes that match the chosen values on the
+ axis. This solution is way more efficient than the first.
+ \stopitem
+\stopitemize
+
+Once I could interpret the right information in the font, the first route was the
+way to go. A side effect of having a converter for both outline types meant that
+it was trivial to create a virtual font at runtime. This option will stay in
+\CONTEXT\ as pseudo|-|feature \type {variableshapes}.
+
+When trying to support variable fonts I tried to limit the impact on the backend
+code. Also, processing features and such was not touched. The inclusion of the
+right shapes is done via a callback that requests the blob to be injected in the
+\type {cff} or \type {glyf} table. When implementing this I actually found out
+that the \LUATEX\ backend also does some juggling of charstrings, to serve the
+purpose of inlining subroutines. In retrospect I could have learned a few tricks
+faster by looking at that code but I never realized that it was there. Looking at
+the code again, it strikes me that the whole inclusion could be done with \LUA\
+code and some day I will give that a try.
+
+\stopsubject
+
+\startsubject[title=Conclusion]
+
+When I first heard about variable fonts I was confident that when they showed up
+they could be supported. Of course a specimen was needed to prove this. A first
+implementation demonstrates that indeed it's no big deal to let \CONTEXT\ with
+\LUATEX\ handle such fonts. Of course we need to fill in some gaps which can be
+done once we have complete fonts. And then of course users will demand more
+control. In the meantime the helper script that deals with identifying fonts by
+name has been extended and the relevant code has been added to the distribution.
+At some point the \CONTEXT\ Garden will provide the \LUATEX\ binary that has the
+callback.
+
+I end with a warning. On the one hand this technology looks promising but on the
+other hand one can easily get lost. Probably most such fonts operate over a
+well|-|defined domain of values but even then one should be aware of complex
+interactions with features like positioning or replacements. Not all combinations
+can be tested. It's probably best to stick to fonts that have all the relevant
+tables and don't depend on properties of a specific rendering technology.
+
+Although support is now present in the core of \CONTEXT\ the official release
+will happen at the \CONTEXT\ meeting in 2017. By then I hope to have tested more
+fonts. Maybe the interface has also been extended by then because after all,
+\TEX\ is about control.
+
+\stopsubject
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/onandon/onandon.tex b/doc/context/sources/general/manuals/onandon/onandon.tex
new file mode 100644
index 000000000..4929a0e95
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon.tex
@@ -0,0 +1,54 @@
+% author : Hans Hagen
+% copyright : PRAGMA ADE & ConTeXt Development Team
+% license : Creative Commons Attribution ShareAlike 4.0 International
+% reference : pragma-ade.nl | contextgarden.net | texlive (related) distributions
+% origin : the ConTeXt distribution
+%
+% comment : Because this manual is distributed with TeX distributions it comes with a rather
+% liberal license. We try to adapt these documents to upgrades in the (sub)systems
+% that they describe. Using parts of the content otherwise can therefore conflict
+% with existing functionality and we cannot be held responsible for that. Many of
+% the manuals contain characteristic graphics and personal notes or examples that
+% make no sense when used out-of-context.
+%
+% comment : Some chapters have been published in TugBoat, the NTG Maps, the ConTeXt Group
+% journal or otherwise. Thanks to the editors for corrections.
+
+% Timestamp: I started this document in the week https://www.youtube.com/watch?v=PFWz_6hnAEI
+% showed up --- and there's more of this bbc performance --- it's this kind of the stuff that
+% keeps me going 'on and on' .. Jacob C, Cory H, Snarky P, Jules B with orchestra ... it can't
+% get any better I guess (although .. what would happen if we add Gavin H to that equation).
+% And when looking at https://www.youtube.com/watch?v=c5FqpddnJmc ... it's the kind of innovation
+% in music that reminds me of first hearing Kate Bush (equally young when she showed up).
+
+\environment onandon-environment
+
+\startproduct onandon
+
+\component onandon-titlepage
+
+\startfrontmatter
+ \component onandon-contents
+ \component onandon-introduction
+\stopfrontmatter
+
+\startbodymatter
+ \component onandon-decade
+ \component onandon-ffi
+ % \startchapter[title=Variable fonts] First published in user group magazines. \stopchapter
+ \component onandon-variable
+ \component onandon-emoji
+ \startchapter[title={Children of \TEX}] First published in user group magazines. \stopchapter
+ % \component onandon-children
+ \component onandon-performance
+ \component onandon-editing
+ \startchapter[title={Advertising \TEX}] First published in user group magazines. \stopchapter
+ % \component onandon-perception
+ \startchapter[title={Tricky fences}] First published in user group magazines. \stopchapter
+ % \component onandon-fences
+ % \component onandon-media
+ \startchapter[title={From 5.2 to 5.3}] Maybe first published in user group magazines. \stopchapter
+ % \component onandon-53
+\stopbodymatter
+
+\stopproduct
diff --git a/doc/context/sources/general/manuals/publications/publications-database.tex b/doc/context/sources/general/manuals/publications/publications-database.tex
index ec47e3c32..656ace56d 100644
--- a/doc/context/sources/general/manuals/publications/publications-database.tex
+++ b/doc/context/sources/general/manuals/publications/publications-database.tex
@@ -124,10 +124,10 @@ the form:
Firstname(s) Lastname
\stopNameSyntax
-\seeindex {vons} {particle}
+\seeindex {vons} {particule}
where \type {Lastname} is a single word but may include an optional (nobility)
-\Index {particle}: lower|-|case word(s) such as \quotation {von}, \quotation
+\Index {particule}: lower|-|case word(s) such as \quotation {von}, \quotation
{de}, \quotation {de la}, etc.) \emphasis {unless} specifically in the two- or
three|-|token form:
@@ -161,7 +161,7 @@ we may (or may not) support this in the future, so don't use this!
We extend \BIBTEX\ by optionally parsing each name in terms of four or five
tokens:
-\index {particle} \index {suffix} \index {initial}
+\index {particule} \index {suffix} \index {initial}
\startNameSyntax
Particule(s), Lastname(s), Suffix(es), Firstname(s)
@@ -174,7 +174,7 @@ thus avoiding the need to resort to any sort of \TEX\ trickery \cite [num]
whose meaning is presently reserved for future directives describing how the name
is to be interpreted:
-\index {particle} \index {suffix} \index {initial}
+\index {particule} \index {suffix} \index {initial}
\startNameSyntax
Particule(s), Lastname(s), Suffix(es), Firstname(s), Initial(s), directives
@@ -186,6 +186,21 @@ specifications will handle the truncation of long author lists in a systematic
fashion. The \index [others] {\tt and others}\BTXcode {and others} construction
finds its use when the complete author list is not well known or ill|-|defined.
+Sometimes, or even often, the database might contain variants of an author's
+name that we would like to identify as a single, unique author. Indeed, certain
+bibliographic styles (as will be seen later) as well as an index of authors, for
+example, will depend on this identification. A command \Cindex {btxremapauthor}
+allows establishing this identity:
+
+\startbuffer
+\btxremapauthor [Donald Knuth] [Donald E. Knuth]
+\btxremapauthor [Don Knuth] [Donald E. Knuth]
+\stopbuffer
+\getbuffer
+
+\cindex {btxremapauthor}
+\typebuffer [option=TEX]
+
Fields other than \Tindex {author} and \Tindex {editor}, for example \Tindex
{artist} or \Tindex {director} if one desires, can be declared to be of type
\quote {author} and thus interpreted as names, but this is a subject for
diff --git a/doc/context/sources/general/manuals/spacing/spacing-mkiv.tex b/doc/context/sources/general/manuals/spacing/spacing-mkiv.tex
index 375f4e2a8..0f32e4d30 100644
--- a/doc/context/sources/general/manuals/spacing/spacing-mkiv.tex
+++ b/doc/context/sources/general/manuals/spacing/spacing-mkiv.tex
@@ -28,6 +28,8 @@
\startbodymatter
\component spacing-linecorrection
+ \component spacing-spaces
+ \component spacing-periods
\stopbodymatter
\stopdocument
diff --git a/doc/context/sources/general/manuals/spacing/spacing-periods.tex b/doc/context/sources/general/manuals/spacing/spacing-periods.tex
new file mode 100644
index 000000000..8d493b9a9
--- /dev/null
+++ b/doc/context/sources/general/manuals/spacing/spacing-periods.tex
@@ -0,0 +1,79 @@
+% language=uk
+
+\environment spacing-style
+
+\startcomponent spacing-periods
+
+\startchapter[title=Periods in abbreviations]
+
+% \enabletrackers[typesetters.periodkerns]
+
+When you use so called non french spacing you get more spacing after punctuation
+(as determined by the \type {sfcode} of the punctuation character) . However,
+when you use periods as delimiters for abbreviations, that period is not the end
+of a sentence and you want normal interword spacing instead. One way to achieve
+this is to add a backslash after the period but in an automated workflow where
+the source is not coming from \TEX\ but for instance in \XML\ format, you can't
+do that. The \type {\setupspacing} command can be used to set one of:
+
+\starttabulate[|T|p|]
+\NC fixed \NC \showglyphs \frenchspacing bla bla e.g. some more \NC \NR
+\NC packed \NC \showglyphs \newfrenchspacing bla bla e.g. some more \NC \NR
+\NC broad \NC \showglyphs \nonfrenchspacing bla bla e.g. some more \NC \NR
+\stoptabulate
+
+The \type {packed} case is similar to \type {fixed} but has slightly larger (some
+5\percent) spacing after punctuation which (at least historically) avoids some
+side effects with hyphenation and dashes. We default to \type {broad} anyway.
+
+The next examples demonstrate what the \type {\setperiodkerning} does when it gets
+an option passed. Its counterpart is \type {\resetperiodkerning}.
+
+\starttabulate[|T|Tr|p|]
+ \HL
+ \NC \NC \NC \showglyphs \nonfrenchspacing \resetperiodkerning bla bla e.g. some more \NC \NR
+ \NC \NC \NC \showglyphs \nonfrenchspacing \resetperiodkerning bla bla e.g. Some more \NC \NR
+ \HL
+ \NC zerospaceperiods \NC 0 \NC \showglyphs \nonfrenchspacing \setperiodkerning [zerospaceperiods]bla bla e.g. some more \NC \NR
+ \NC \NC \NC \showglyphs \nonfrenchspacing \setperiodkerning [zerospaceperiods]bla bla e.g. Some more \NC \NR
+ \HL
+ \NC smallspaceperiods \NC .25\NC \showglyphs \nonfrenchspacing \setperiodkerning [smallspaceperiods]bla bla e.g. some more \NC \NR
+ \NC \NC \NC \showglyphs \nonfrenchspacing \setperiodkerning [smallspaceperiods]bla bla e.g. Some more \NC \NR
+ \HL
+ \NC halfspaceperiods \NC .50 \NC \showglyphs \nonfrenchspacing \setperiodkerning [halfspaceperiods]bla bla e.g. some more \NC \NR
+ \NC \NC \NC \showglyphs \nonfrenchspacing \setperiodkerning [halfspaceperiods]bla bla e.g. Some more \NC \NR
+ \HL
+\stoptabulate
+
+Next we enlarge the affected bit of text so that you can see that the last two
+options also affects the space after the periods that bind the characters.
+
+\startlinecorrection
+\startcombination[4*2]
+ {\scale[scale=3500]{\ruledhbox{\showglyphs \nonfrenchspacing \resetperiodkerning e.g. s}}} {}
+ {\scale[scale=3500]{\ruledhbox{\showglyphs \nonfrenchspacing \setperiodkerning [zerospaceperiods]e.g. s}}} {}
+ {\scale[scale=3500]{\ruledhbox{\showglyphs \nonfrenchspacing \setperiodkerning [smallspaceperiods]e.g. s}}} {}
+ {\scale[scale=3500]{\ruledhbox{\showglyphs \nonfrenchspacing \setperiodkerning [halfspaceperiods]e.g. s}}} {}
+ {\scale[scale=3500]{\ruledhbox{\showglyphs \nonfrenchspacing \resetperiodkerning e.g. S}}} {}
+ {\scale[scale=3500]{\ruledhbox{\showglyphs \nonfrenchspacing \setperiodkerning [zerospaceperiods]e.g. S}}} {\ttxx zerospaceperiods}
+ {\scale[scale=3500]{\ruledhbox{\showglyphs \nonfrenchspacing \setperiodkerning [smallspaceperiods]e.g. S}}} {\ttxx smallspaceperiods}
+ {\scale[scale=3500]{\ruledhbox{\showglyphs \nonfrenchspacing \setperiodkerning [halfspaceperiods]e.g. S}}} {\ttxx halfspaceperiods}
+\stopcombination
+\stoplinecorrection
+
+Defining more options is easy, we only specify the factor that determines mid
+periods. When \type {factor} is zero, only the final period is looked at.
+
+\starttyping
+\defineperiodkerning [zerospaceperiods] [factor=0]
+\defineperiodkerning [smallspaceperiods] [factor=.25]
+\defineperiodkerning [halfspaceperiods] [factor=.5]
+\stoptyping
+
+This mechanism has been present for a while but I forgot about it. When cleaning
+up code it was decided to add it to the core. Maybe more options and features are
+needed but so far there has never been demand for this so \unknown
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/spacing/spacing-spaces.tex b/doc/context/sources/general/manuals/spacing/spacing-spaces.tex
new file mode 100644
index 000000000..defa833c3
--- /dev/null
+++ b/doc/context/sources/general/manuals/spacing/spacing-spaces.tex
@@ -0,0 +1,236 @@
+% language=uk
+
+\environment spacing-style
+
+\startcomponent spacing-periods
+
+\startchapter[title=Spacing]
+
+\startsection[title=Spaces]
+
+When \TEX\ reads its input and transforms content it into a node list spaces are
+turned into glue nodes of subtype \quote {spaceskip} or \quote {xspaceskip}. In
+pseudo code, this is what happens:
+
+\starttyping
+if spacefactor >= 2000 and xspaceskip ~= 0 then
+ space = xspaceskip_space
+ stretch = xspaceskip_stretch
+ shrink = xspaceskip_shrink
+ subtype = xspaceskip
+else
+ if spaceskip == 0 then
+ space = font_space
+ stretch = font_stretch
+ shrink = font_shrink
+ else
+ space = spaceskip_space
+ stretch = spaceskip_stretch
+ shrink = spaceskip_shrink
+ end
+ if space_factor >= 2000
+ space = space + font_extraspace
+ end
+ stretch = stretch * space_factor
+ shrink = shrink * space_factor
+ subtype = spaceskip
+end
+insert_glue(space,stretch,shrink,subtype)
+\stoptyping
+
+We demonstrate the effects in a few examples. You can use \typ {\showmakeup [space]} to
+visualize spaces.
+
+\def\ShowSpaces#1#2#3%
+ {\blank
+ \start
+ \startsubsubsubject[title={case #1: \type{#2} and \type {#3}}]
+ \dontleavehmode
+ #2\relax
+ #3\relax
+ \showmakeup[space]%
+ % \definedfont[Serif*default]%
+ \nonfrenchspacing
+ \strut x\space x.\space x\crlf
+ \frenchspacing
+ \strut x\space x.\space x\par
+ \stop
+ \stopsubsubject
+ \blank}
+
+\ShowSpaces{1}{\spacefactor2000}{\xspaceskip100pt}
+
+\starttabulate[|l|l|]
+\HL
+\NC \type {\spacefactor} \NC $\geq 2000$ \NC \NR
+\NC \type {\xspaceskip} \NC $\neq 0$ \NC \NR
+\HL
+\NC space \NC xspaceskip_space \NC \NR
+\NC stretch \NC xspaceskip_stretch \NC \NR
+\NC shrink \NC xspaceskip_shrink \NC \NR
+\NC subtype \NC xspaceskip \NC \NR
+\HL
+\stoptabulate
+
+\ShowSpaces{2}{\spacefactor1000}{\spaceskip0pt}
+
+\starttabulate[|l|l|]
+\HL
+\NC \type {\spacefactor} \NC $\lt 2000$ \NC \NR
+\NC \type {\spaceskip} \NC $\eq 0$ \NC \NR
+\HL
+\NC space \NC font_space \NC \NR
+\NC stretch \NC font_stretch \NC \NR
+\NC shrink \NC font_shrink \NC \NR
+\NC subtype \NC spaceskip \NC \NR
+\HL
+\stoptabulate
+
+\ShowSpaces{3}{\spacefactor2000}{\spaceskip0pt}
+
+\starttabulate[|l|l|]
+\HL
+\NC \type {\spacefactor} \NC $\geq 2000$ \NC \NR
+\NC \type {\spaceskip} \NC $\eq 0$ \NC \NR
+\HL
+\NC space \NC font_space $+$ extraspace_font \NC \NR
+\NC stretch \NC font_stretch \NC \NR
+\NC shrink \NC font_shrink \NC \NR
+\NC subtype \NC spaceskip \NC \NR
+\HL
+\stoptabulate
+
+\ShowSpaces{4}{\spacefactor1000}{\spaceskip100pt}
+
+\starttabulate[|l|l|]
+\HL
+\NC \type {\spacefactor} \NC $\lt 2000$ \NC \NR
+\NC \type {\spaceskip} \NC $\neq 0$ \NC \NR
+\HL
+\NC space \NC font_space \NC \NR
+\NC stretch \NC font_stretch $\times$ space_factor \NC \NR
+\NC shrink \NC font_shrink $\times$ space_factor \NC \NR
+\NC subtype \NC spaceskip \NC \NR
+\HL
+\stoptabulate
+
+\ShowSpaces{5}{\spacefactor2000}{\spaceskip100pt}
+
+\starttabulate[|l|l|]
+\HL
+\NC \type {\spacefactor} \NC $\geq 2000$ \NC \NR
+\NC \type {\spaceskip} \NC $\neq 0$ \NC \NR
+\HL
+\NC space \NC font_space $+$ extraspace_font \NC \NR
+\NC stretch \NC font_stretch $\times$ space_factor \NC \NR
+\NC shrink \NC font_shrink $\times$ space_factor \NC \NR
+\NC subtype \NC spaceskip \NC \NR
+\HL
+\stoptabulate
+
+The width of a space relates to the design of a font and therefore the t width of
+the space, its stretch and its shrink are taken from the font and scaled
+accordingly. Normally we take the space character in the font as reference.
+Traditional \TEX\ fonts don't have that character but \OPENTYPE\ fonts have. When
+there is no space character, in the case of a monospaced font we take the
+emwidth, otherwise we take half the emwidth. As a last resort we can take the
+average width of characters. And of even that fails we take half of the font
+units. But, as mentioned, modern fonts have a space.
+
+In the \CONTEXT\ font loader we use a stretch that is 1/2 of the width of a space
+and the shrink is 1/3 the width of a space. These values are familiar for those
+who come from traditional \TEX.
+
+As with many variables, you can overload these values when a font is loaded by
+setting the \type {spacing} feature. Here is how this is done:
+
+\startbuffer
+\definefontfeature
+ [morespace]
+ [spacing=0.50 plus 0.50 minus 0.250]
+\definefontfeature
+ [lessspace]
+ [spacing=0.25 plus 0.25 minus 0.125]
+\definefontfeature
+ [extramorespace]
+ [spacing=0.50 plus 0.50 minus 0.250 extra 2.00]
+\definefontfeature
+ [extralessspace]
+ [spacing=0.25 plus 0.25 minus 0.125 extra 2.00]
+
+\definedfont[Serif*default]
+ \inleft{\infofont default}
+ \samplefile{klein}\par
+ \blank
+\definedfont[Serif*default,morespace]
+ \inleft{\infofont morespace}
+ \samplefile{klein}\par
+ \blank
+\definedfont[Serif*default,extramorespace]
+ \inleft{\infofont extramorespace}
+ \samplefile{klein}\par
+ \blank
+\definedfont[Serif*default,lessspace]
+ \inleft{\infofont lessspace}
+ \samplefile{klein}\par
+ \blank
+\definedfont[Serif*default,extralessspace]
+ \inleft{\infofont extralessspace}
+ \samplefile{klein}\par
+ \blank
+\stopbuffer
+
+\typebuffer
+
+For demonstration purposes we use a somewhat excessive \type {extra}
+specification. By default the extra space is equal to the shrink.
+
+\blank \start
+ \showmakeup[space]
+ \getbuffer
+\stop \blank
+
+\stopsection
+
+\startsection[title=Expansion]
+
+Spaces become glue that can shrink or stretch. In the worst case words will come
+too close, or the gap will be large. Even worse is that this can lead to
+successive lines in a paragraph looking different with respect to spacing. A solution
+for this is to use font expansion, although the benefits are often less than
+some users want (you) to believe.
+
+This mechanism is enabled with \type {\setupalign}. There are two variants (\type
+{hz} and \type {fullhz}) and a reset (\type {nohz}). In \in {figure} [fig:expansion]
+we use the following font definition:
+
+\startbuffer
+\definefont[testfont][Normal*default,quality @ 9pt]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We use \type {\showfontexpansion} to view the effective expansion factors of each
+glyph. When \type {fullhz} is used fontkerns also can get expanded. Zero values
+are not shown. The font kern factors are shown below the character factors. They
+can be neglected and one can even wonder if they need a treatment especially
+because kerns are also used for relative positioning, accent anchoring and
+cursive attachments.
+
+\startplacefigure[reference=fig:expansion,title={The two expansion methods in action.}]
+ \startcombination[nx=3,ny=2,location=top]
+ {\framed[foregroundstyle=\testfont,width=.3\textwidth,align={normal,tolerant,nohz}] {\showfontexpansion\samplefile{ward}}} {}
+ {\framed[foregroundstyle=\testfont,width=.3\textwidth,align={normal,tolerant,fullhz}]{\showfontexpansion\samplefile{ward}}} {}
+ {\framed[foregroundstyle=\testfont,width=.3\textwidth,align={normal,tolerant,hz}] {\showfontexpansion\samplefile{ward}}} {}
+ {\scale[width=.3\textwidth]{\clip[nx=2,ny=4,x=2,y=3]{\framed[foregroundstyle=\testfont,width=.3\textwidth,align={normal,tolerant,nohz}] {\showfontexpansion\samplefile{ward}}}}} {\tttf{nohz}}
+ {\scale[width=.3\textwidth]{\clip[nx=2,ny=4,x=2,y=3]{\framed[foregroundstyle=\testfont,width=.3\textwidth,align={normal,tolerant,fullhz}]{\showfontexpansion\samplefile{ward}}}}} {\tttf{fullhz}}
+ {\scale[width=.3\textwidth]{\clip[nx=2,ny=4,x=2,y=3]{\framed[foregroundstyle=\testfont,width=.3\textwidth,align={normal,tolerant,hz}] {\showfontexpansion\samplefile{ward}}}}} {\tttf{hz}}
+ \stopcombination
+\stopplacefigure
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
+
diff --git a/doc/context/sources/general/manuals/spacing/spacing-style.tex b/doc/context/sources/general/manuals/spacing/spacing-style.tex
index cf0bae7bf..c9d168f1c 100644
--- a/doc/context/sources/general/manuals/spacing/spacing-style.tex
+++ b/doc/context/sources/general/manuals/spacing/spacing-style.tex
@@ -1,5 +1,7 @@
\startenvironment spacing-style
+\usemodule[abr-03]
+
\setupbodyfont
[pagella]
@@ -52,4 +54,11 @@
[style=\bfc,
color=maincolor]
+\setuphead
+ [subsubsection]
+ [style=bold,
+ color=maincolor,
+ before=\blank,
+ after=\blank]
+
\stopenvironment
diff --git a/doc/context/sources/general/manuals/xtables/xtables-mkiv.tex b/doc/context/sources/general/manuals/xtables/xtables-mkiv.tex
index d4316b479..827ad3fcc 100644
--- a/doc/context/sources/general/manuals/xtables/xtables-mkiv.tex
+++ b/doc/context/sources/general/manuals/xtables/xtables-mkiv.tex
@@ -1013,14 +1013,240 @@ similar.
\stopsection
-\startsection[title={Colofon}]
+\startsection[title={Alignment}]
-\starttabulate[|B|p|]
-\NC author \NC \getvariable{document}{author}, \getvariable{document}{affiliation}, \getvariable{document}{location} \NC \NR
-\NC version \NC \currentdate \NC \NR
-\NC website \NC \getvariable{document}{website} \endash\ \getvariable{document}{support} \NC \NR
-\NC copyright \NC \symbol[cc][cc-by-sa-nc] \NC \NR
-\stoptabulate
+\enabletrackers[typesetters.characteralign]
+
+There is limited support for aligning numbers in columns. When you flush right
+and have a fixed number of digits it's not a problem, but otherwise it might come
+in handy. In any case, you might want to use the following as part of your style:
+
+\starttyping
+\addfeature[tabularnumbers]
+\stoptyping
+
+\start \addfeature[tabularnumbers]
+
+The basic alignment mechanism can be demonstrated with the following examples:
+
+\startbuffer
+\startcharacteralign[,] % or [character={,}]
+ \checkcharacteralign{123.456,78} \par
+ \checkcharacteralign {456} \par
+ \checkcharacteralign {23.456} \par
+ \checkcharacteralign {78,9} \par
+ \checkcharacteralign {78} \par
+\stopcharacteralign
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startcharacteralign[leftsample=123.456,rightsample=00,character={,}]
+ \checkcharacteralign{123.456,78} \par
+ \checkcharacteralign {456} \par
+ \checkcharacteralign {23.456} \par
+ \checkcharacteralign {78,9} \par
+ \checkcharacteralign {78} \par
+\stopcharacteralign
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startcharacteralign[leftwidth=100pt,rightwidth=30pt]
+ \checkcharacteralign{123.456,78} \par
+ \checkcharacteralign {456} \par
+ \checkcharacteralign {23.456} \par
+ \checkcharacteralign {78,9} \par
+ \checkcharacteralign {78} \par
+\stopcharacteralign
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Samples win over width settings. When no sample or width is given a two pass
+analyzer kicks in. This is not the case in the following examples.
+
+\startbuffer
+\startxtable
+ [align={flushright,lohi},
+ aligncharacter=yes,
+ alignmentleftsample=100,
+ alignmentrightsample=00,
+ alignmentcharacter={.}]
+ \startxrow \startxcell 1 \stopxcell \stopxrow
+ \startxrow \startxcell 1.1 \stopxcell \stopxrow
+ \startxrow \startxcell 11.11 \stopxcell \stopxrow
+\stopxtable
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startxtable
+ [align={flushright,lohi},
+ aligncharacter=yes,
+ alignmentleftsample=000.000,
+ alignmentrightsample=00,
+ alignmentcharacter={,}]
+ \startxrow \startxcell 123.456,78 x \stopxcell \stopxrow
+ \startxrow \startxcell 456 x \stopxcell \stopxrow
+ \startxrow \startxcell 23.456 x \stopxcell \stopxrow
+ \startxrow \startxcell 78,9 x \stopxcell \stopxrow
+ \startxrow \startxcell 78 x \stopxcell \stopxrow
+\stopxtable
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startxtable[align={flushright,lohi}]
+ \startxrow
+ \startxcell
+ [aligncharacter=yes,
+ alignmentcharacter={,},
+ alignmentleftsample=000.000,
+ alignmentrightsample=00]
+ 123.456,78
+ \stopxcell
+ \stopxrow
+ \startxrow
+ \startxcell
+ [aligncharacter=yes]
+ 456
+ \stopxcell
+ \stopxrow
+ \startxrow
+ \startxcell
+ [aligncharacter=yes]
+ 23.456
+ \stopxcell
+ \stopxrow
+ \startxrow
+ \startxcell
+ [aligncharacter=yes]
+ 78,9
+ \stopxcell
+ \stopxrow
+ \startxrow
+ \startxcell
+ [aligncharacter=yes]
+ 78
+ \stopxcell
+ \stopxrow
+\stopxtable
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\setupxtable
+ [aligned]
+ [aligncharacter=yes,
+ alignmentleftsample=000.000,
+ alignmentrightsample=00,
+ alignmentcharacter={,}]
+
+\startxtable[align={flushright,lohi}]
+ \startxrow \startxcell[aligned] 123.456,78 \stopxcell \stopxrow
+ \startxrow \startxcell[aligned] 456 \stopxcell \stopxrow
+ \startxrow \startxcell[aligned] 23.456 \stopxcell \stopxrow
+ \startxrow \startxcell[aligned] 78,9 \stopxcell \stopxrow
+ \startxrow \startxcell[aligned] 78 \stopxcell \stopxrow
+\stopxtable
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stop
+
+\disabletrackers[typesetters.characteralign]
+
+\stopsection
+
+\startsection[title={Depth}]
+
+Take the following example. Here we have some text that, when typeset narrow,
+will have a last line with no (or, depending on the font, hardly) depth.
+
+\startbuffer
+\startxtable[frame=on]
+
+ \startxrow
+ \startxcell[width=3cm]
+ here filled with some words to force a rather long line
+ \stopxcell
+ \stopxrow
+
+ \startxrow
+ \startxcell
+ here filled with some words to force a rather long line
+ \stopxcell
+ \stopxrow
+
+ \startxrow
+ \startxcell
+ here filled with some words to force a rather long line
+
+ \stopxcell
+ \stopxrow
+
+\stopxtable
+\stopbuffer
+
+\typebuffer
+
+The problem is that \TEX\ doesn't add depth that that last line and adding it
+automatically can be done in grid mode but one doesn't always want that. Some mechanisms
+add so called struts automatically. As the table cells are framed boxes indeed that
+happens here, unless you add an empty line (as in the last row). When you embed
+
+\startlinecorrection[blank] {\showstruts \showboxes \getbuffer} \stoplinecorrection
+
+\startbuffer
+\startxtable[frame=on]
+
+ \startxrow
+ \startxcell[width=3cm]
+ \startitemize[packed]
+ \startitem
+ here filled with some words to force a rather long line
+ \stopitem
+ \stopitemize
+ \stopxcell
+ \stopxrow
+
+ \startxrow
+ \startxcell
+ \startitemize[packed]
+ \startitem
+ here filled with some words to force a rather long line
+ \stopitem
+ \stopitemize
+ \stopxcell
+ \stopxrow
+
+ \startxrow
+ \startxcell
+ \startitemize[packed]
+ \startitem
+ here filled with some words to force a rather long line
+
+ \stopitem
+ \stopitemize
+ \stopxcell
+ \stopxrow
+
+\stopxtable
+\stopbuffer
+
+\typebuffer
+
+Don't count on all mechanisms used inside a cell to provide this but with itemize
+you're lucky.
+
+\startlinecorrection[blank] {\showstruts \showboxes \getbuffer} \stoplinecorrection
\stopsection
@@ -1234,6 +1460,78 @@ in the distribution.
\typebuffer[tight] \start \getbuffer[tight,demo] \stop
\typebuffer[normal] \start \getbuffer[normal,demo] \stop
+\page
+
+\startbuffer
+\startxtable[align={middle,lohi}]
+ \startxrow
+ \startxcell[ny=3] (1,3) \stopxcell
+ \startxcell (1,1) \stopxcell
+ \startxcell (1,1) \stopxcell
+ \stopxrow
+ \startxrow
+ \startxcell (1,1) \stopxcell
+ \startxcell (1,1) \stopxcell
+ \stopxrow
+ \startxrow
+ \startxcell[nx=2] (2,1) \stopxcell
+ \stopxrow
+\stopxtable
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startxtable[align={middle,lohi}]
+ \startxrow
+ \startxcell[ny=2] (1,2) \stopxcell
+ \startxcell (1,1) \stopxcell
+ \startxcell (1,1) \stopxcell
+ \stopxrow
+ \startxrow
+ \startxcell (1,1) \stopxcell
+ \startxcell (1,1) \stopxcell
+ \stopxrow
+ \startxrow
+ \startxcell[nx=2] (2,1) \stopxcell
+ \stopxrow
+\stopxtable
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startxtable[align={middle,lohi}]
+ \startxrow
+ \startxcell[ny=2] (1,2) \stopxcell
+ \startxcell (1,1) \stopxcell
+ \startxcell (1,1) \stopxcell
+ \startxcell (1,1) \stopxcell
+ \stopxrow
+ \startxrow
+ \startxcell[nx=3] (3,1) \stopxcell
+ \stopxrow
+ \startxrow
+ \startxcell[nx=4] (4,1) \stopxcell
+ \stopxrow
+\stopxtable
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\page
+
% \ruledhbox{\getbuffer[normal,demo]}
+\startsection[title={Colofon}]
+
+\starttabulate[|B|p|]
+\NC author \NC \getvariable{document}{author}, \getvariable{document}{affiliation}, \getvariable{document}{location} \NC \NR
+\NC version \NC \currentdate \NC \NR
+\NC website \NC \getvariable{document}{website} \endash\ \getvariable{document}{support} \NC \NR
+\NC copyright \NC \symbol[cc][cc-by-sa-nc] \NC \NR
+\stoptabulate
+
+\stopsection
+
\stopdocument
diff --git a/metapost/context/base/mpiv/mp-crop.mpiv b/metapost/context/base/mpiv/mp-crop.mpiv
index 00bcdcb44..e06cf8def 100644
--- a/metapost/context/base/mpiv/mp-crop.mpiv
+++ b/metapost/context/base/mpiv/mp-crop.mpiv
@@ -15,7 +15,7 @@ if known context_crop : endinput ; fi ;
boolean context_crop ; context_crop := true ;
-vardef crop_marks_lines (expr box, len, offset, nx, ny) =
+vardef crop_marks_lines (expr box, len, offset, nx, ny, boxtoo) =
save p ; picture p ; save w, h, x, y ; numeric w, h, x, y ;
p := image (
x := if nx = 0 : 1 else : nx - 1 fi ;
@@ -30,12 +30,20 @@ vardef crop_marks_lines (expr box, len, offset, nx, ny) =
draw ((llcorner box) -- (llcorner box) shifted (0,-len)) shifted (i*w,-offset) ;
draw ((ulcorner box) -- (ulcorner box) shifted (0, len)) shifted (i*w, offset) ;
endfor ;
+ if boxtoo :
+ for i=0 upto x-1 :
+ for j=0 upto y-1 :
+ draw box enlarged 1/8 shifted (i*w,j*h) dashed evenly withpen pencircle scaled 1/4 ;
+ endfor ;
+ endfor ;
+ fi ;
) ;
setbounds p to box ;
p
enddef ;
vardef crop_marks_cmyk =
+ pickup pencircle scaled 1/2 ;
save p ; picture p ; p := image (
fill ulcircle scaled 12.5 withcolor (1,0,0,0) ;
fill urcircle scaled 12.5 withcolor (0,1,0,0) ;
@@ -125,6 +133,8 @@ enddef ;
def page_marks_add_color(expr width, height, length, offset) = % todo: namespace
+ pickup pencircle scaled 1/2 ; interim linecap := squared ; interim linejoin := butt ;
+
path page ; page := fullsquare xscaled width yscaled height ;
path more ; more := page enlarged (offset+length/2,offset+length/2) ;
@@ -159,6 +169,8 @@ enddef ;
def page_marks_add_marking(expr width, height, length, offset) = % todo: namespace
+ pickup pencircle scaled 1/2 ; interim linecap := squared ; interim linejoin := butt ;
+
path page ; page := fullsquare xscaled width yscaled height ;
path more ; more := page enlarged (offset+length/2,offset+length/2) ;
@@ -169,12 +181,14 @@ def page_marks_add_marking(expr width, height, length, offset) = % todo: namespa
enddef ;
-def page_marks_add_lines(expr width, height, length, offset, nx, ny) = % todo: namespace
+def page_marks_add_lines(expr width, height, length, offset, nx, ny, boxtoo) = % todo: namespace
+
+ pickup pencircle scaled 1/2 ; interim linecap := squared ; interim linejoin := butt ;
path page ; page := fullsquare xscaled width yscaled height ;
path more ; more := page enlarged (offset+length/2,offset+length/2) ;
- draw crop_marks_lines(page,length,offset,nx,ny) ;
+ draw crop_marks_lines(page,length,offset,nx,ny,boxtoo) ;
setbounds currentpicture to page ;
@@ -182,6 +196,8 @@ enddef ;
def page_marks_add_number(expr width, height, length, offset, n) = % todo: namespace
+ pickup pencircle scaled 1/2 ; interim linecap := squared ; interim linejoin := butt ;
+
path page ; page := fullsquare xscaled width yscaled height ;
path more ; more := page enlarged (offset+length/2,offset+length/2) ;
diff --git a/metapost/context/base/mpiv/mp-node.mpiv b/metapost/context/base/mpiv/mp-node.mpiv
index 834a5a01d..1f046a436 100644
--- a/metapost/context/base/mpiv/mp-node.mpiv
+++ b/metapost/context/base/mpiv/mp-node.mpiv
@@ -38,18 +38,23 @@ vardef makenodepath(suffix p) =
fi
enddef ;
-def clearnodepath suffix p =
- save p ; path p ;
+% can take a list:
+def clearpath text t =
+ save t ; path t ;
enddef ;
-clearnodepath nodepath ;
+def clearnodepath = clearpath nodepath enddef ;
+
+clearnodepath ;
+
+% the trailing "," below handles when number of t<3
vardef makenode@#(text t) =
for a = t :
- if (known a) and (numeric a) :
- _makenode(nodepath, t)
+ if (path a) or (unknown a) :
+ mfun_makenode@#(t,)
else :
- _makenode(t)
+ mfun_makenode@#(nodepath, t,)
fi
exitif true ;
endfor
@@ -57,10 +62,10 @@ enddef ;
vardef node@#(text t) =
for a = t :
- if (known a) and (numeric a) :
- _node(nodepath, t)
+ if (path a) or (unknown a) :
+ mfun_node@#(t,)
else :
- _node(t)
+ mfun_node@#(nodepath, t,)
fi
exitif true ;
endfor
@@ -68,81 +73,73 @@ enddef ;
vardef nodeboundingpoint@#(text t) =
for a = t :
- if (known a) and (numeric a) :
- _nodeboundingpoint@#(nodepath,a)
+ if (path a) or (unknown a) :
+ mfun_nodeboundingpoint@#(t)
else :
- _nodeboundingpoint@#(t)
+ mfun_nodeboundingpoint@#(nodepath,a)
fi
exitif true ;
endfor
enddef ;
-vardef fromto@#(expr d,f)(text t) =
+vardef fromto@#(expr d, f)(text t) =
fromtopaths@#(d,nodepath,f,nodepath,t)
enddef ;
% returns a pair suffix if the path is unknown
-vardef _makenode@#(suffix p)(text t) =
- save i, d, b ; numeric i, d ; string b ;
+vardef mfun_makenode@#(suffix p)(expr i)(text t) =
+ save d, b ; string b ;
+ d = dimension p ;
+ if d > 0 :
+ b := prefix p ;
+ if not picture p.pic[i] : scantokens("picture " & b &
+ for j=1 upto d : "[]" & endfor
+ "pic[] ;") ; fi
+ if not pair p.pos[i] : scantokens("pair " & b &
+ for j=1 upto d : "[]" & endfor
+ "pos[] ;") ; fi
+ else :
+ if not picture p.pic[i] : picture p.pic[] ; fi
+ if not pair p.pos[i] : pair p.pos[] ; fi
+ fi
for a = t :
- if unknown i : % first argument is the index
- i = a ;
- d = dimension p ;
- if d > 0 :
- b := prefix p ;
- if not picture p.pic[i] : scantokens("picture " & b &
- for j=1 upto d : "[]" & endfor
- "pic[] ;") ; fi
- if not pair p.pos[i] : scantokens("pair " & b &
- for j=1 upto d : "[]" & endfor
- "pos[] ;") ; fi
- else :
- if not picture p.pic[i] : picture p.pic[] ; fi
- if not pair p.pos[i] : pair p.pos[] ; fi
- fi
+ if known p.pic[i] :
+ addto p.pic[i] also
else :
- if known p.pic[i] :
- addto p.pic[i] also
- else :
- p.pic[i] =
- fi
+ p.pic[i] =
+ fi
if picture a : a
- elseif string a : textext@#(a)
+ elseif string a : if (length(a) > 0) : textext@#(a) else : nullpicture fi
elseif numeric a : textext@#(decimal a)
elseif ((boolean a) and a) : image(draw origin withpen currentpen scaled 4)
else : nullpicture
fi ;
- fi
endfor
p.pos[i] if known p : := point i of p ; fi
enddef ;
% returns a picture
-vardef _node@#(suffix p)(text t) =
- if pair _makenode@#(p,t) :
+vardef mfun_node@#(suffix p)(expr i)(text t) =
+ if pair mfun_makenode@#(p,i,t) :
% nop: enclose in "if ... fi" to gobble the function return.
fi
- % now pick-off only the index:
- for a = t :
- if (unknown p) and (known p.pos[a]) :
- makenodepath(p) ;
- fi
- if known p.pic[a] :
- p.pic[a] if known p : shifted point a of p fi
- else :
- nullpicture
- fi
- exitif true ;
- endfor
+ if (unknown p) and (known p.pos[i]) :
+ makenodepath(p) ;
+ fi
+ if known p.pic[i] :
+ p.pic[i] if known p : shifted point i of p fi
+ else :
+ nullpicture
+ fi
enddef ;
% returns a path
vardef fromtopaths@#(expr d)(suffix p)(expr f)(suffix q)(text s) =
save r, t, l ;
- path r[] ; numeric t ; picture l ;
+ path r[] ; picture l ;
for a = s :
if unknown t :
t = a ;
@@ -159,7 +156,7 @@ vardef fromtopaths@#(expr d)(suffix p)(expr f)(suffix q)(text s) =
else :
point f of p -- point t of q
fi ;
- save deviation ; numeric deviation ;
+ save deviation ;
deviation := if numeric d: d else: 0 fi ;
r1 = if deviation=0 : r0
else :
@@ -175,12 +172,12 @@ vardef fromtopaths@#(expr d)(suffix p)(expr f)(suffix q)(text s) =
else :
l :=
fi
- if picture a : a
- elseif string a : textext@#(a)
- elseif numeric a : textext@#(decimal a)
- elseif ((boolean a) and a) : image(draw origin withpen currentpen scaled 4)
- else : nullpicture
- fi ;
+ if picture a : a
+ elseif string a : if (length(a) > 0) : textext@#(a) else : nullpicture fi
+ elseif numeric a : textext@#(decimal a)
+ elseif ((boolean a) and a) : image(draw origin withpen currentpen scaled 4)
+ else : nullpicture
+ fi ;
fi
endfor
r2 = r1
@@ -202,7 +199,7 @@ enddef ;
% returns pair: bounding point of the node picture
-vardef _nodeboundingpoint@#(suffix p)(expr i) =
+vardef mfun_nodeboundingpoint@#(suffix p)(expr i) =
if known p.pic[i] :
boundingpoint@#(p.pic[i])
else :
@@ -219,7 +216,7 @@ enddef ;
% returns pair: vector between nodes (+ optional scale)
vardef betweennodes@#(suffix p)(expr f)(suffix q)(text s) =
- save t ; numeric t ;
+ save t ;
for a = s :
if unknown t :
t = a ;
@@ -229,3 +226,28 @@ vardef betweennodes@#(suffix p)(expr f)(suffix q)(text s) =
fi
endfor
enddef ;
+
+% helpers that save passing tokens
+
+def mfun_node_init(expr dx, dy, da) =
+ save nodelattice ; pair nodelattice[] ;
+ nodelattice0 = (dx,0) ;
+ nodelattice1 = dy * dir(da) ;
+ clearnodepath ;
+ save nodecount ; nodecount = -1;
+enddef ;
+
+def mfun_node_make(expr x, y, s) =
+ nodecount := nodecount + 1 ;
+ makenode(nodecount,s) = x * nodelattice0 + y * nodelattice1 ;
+enddef ;
+
+def mfun_node_flush =
+ for i=0 upto nodecount:
+ draw node(i) ;
+ endfor
+enddef ;
+
+vardef mfun_nodes_fromto@#(expr d, f)(text t) =
+ fromtopaths@#(d,nodepath,f,nodepath,t)
+enddef ;
diff --git a/scripts/context/lua/mtx-evohome.lua b/scripts/context/lua/mtx-evohome.lua
index 671666493..7fd8612ec 100644
--- a/scripts/context/lua/mtx-evohome.lua
+++ b/scripts/context/lua/mtx-evohome.lua
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['mtx-evohome'] = {
license = "see context related readme files"
}
-require("util-evo")
+local evohome = require("util-evo")
local formatters = string.formatters
@@ -26,6 +26,8 @@ local helpinfo = [[
<flag name="collect"><short>collect data from device</short></flag>
<flag name="presets"><short>file with authenciation data</short></flag>
<flag name="auto"><short>fetch temperature data every hour</short></flag>
+ <flag name="port"><short>server port when running the service, default: 8068</short></flag>
+ <flag name="host"><short>server host when running the service, default: localhost</short></flag>
</subcategory>
</category>
</flags>
@@ -34,6 +36,7 @@ local helpinfo = [[
<title>Example</title>
<subcategory>
<example><command>mtxrun --script evohome --collect --presets=c:/data/develop/domotica/code/evohome-presets.lua</command></example>
+ <example><command>mtxrun --script evohome --server --presets=c:/data/develop/domotica/code/evohome-presets.lua</command></example>
</subcategory>
</category>
</examples>
@@ -58,12 +61,12 @@ function scripts.evohome.collect()
local presets = arguments.presets
local delay = tonumber(arguments.delay) or 15*60*60
if presets then
- presets = utilities.evohome.loadpresets(presets)
+ presets = evohome.helpers.loadpresets(presets)
end
if presets then
local function fetch()
report("current time %a",os.now())
- utilities.evohome.updatetemperatures(presets)
+ evohome.helpers.updatetemperatures(presets)
end
if arguments.auto then
while true do
@@ -80,14 +83,27 @@ function scripts.evohome.collect()
end
end
-
function scripts.evohome.update()
local presets = arguments.presets
if presets then
- presets = utilities.evohome.loadpresets(presets)
+ presets = evohome.helpers.loadpresets(presets)
+ end
+ if presets then
+ evohome.helpers.geteverything(presets)
+ else
+ report("invalid preset file")
end
+end
+
+function scripts.evohome.server()
+ local presets = arguments.presets
if presets then
- utilities.evohome.geteverything(presets)
+ require("util-evo-imp-server")
+ evohome.server {
+ filename = presets, -- e:/domotica/code/evohome-presets.lua
+ host = arguments.host,
+ port = tonumber(arguments.port),
+ }
else
report("invalid preset file")
end
@@ -97,6 +113,8 @@ if environment.argument("collect") then
scripts.evohome.collect()
elseif environment.argument("update") then
scripts.evohome.update()
+elseif environment.argument("server") then
+ scripts.evohome.server()
elseif environment.argument("exporthelp") then
application.export(environment.argument("exporthelp"),environment.files[1])
else
diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua
index d42013d33..9b23f55c4 100644
--- a/scripts/context/lua/mtx-fonts.lua
+++ b/scripts/context/lua/mtx-fonts.lua
@@ -109,6 +109,16 @@ end
loadmodule("char-def.lua")
+loadmodule("font-ini.lua")
+loadmodule("font-log.lua")
+loadmodule("font-con.lua")
+loadmodule("font-cft.lua")
+loadmodule("font-enc.lua")
+loadmodule("font-agl.lua")
+loadmodule("font-cid.lua")
+loadmodule("font-map.lua")
+loadmodule("font-oti.lua")
+
loadmodule("font-otr.lua")
loadmodule("font-cff.lua")
loadmodule("font-ttf.lua")
@@ -116,6 +126,7 @@ loadmodule("font-tmp.lua")
loadmodule("font-dsp.lua")
loadmodule("font-oup.lua")
+loadmodule("font-otl.lua")
loadmodule("font-onr.lua")
-- extra code
diff --git a/scripts/context/lua/mtx-youless.lua b/scripts/context/lua/mtx-youless.lua
index c66824365..32e1bd870 100644
--- a/scripts/context/lua/mtx-youless.lua
+++ b/scripts/context/lua/mtx-youless.lua
@@ -22,7 +22,7 @@ local helpinfo = [[
<metadata>
<entry name="name">mtx-youless</entry>
<entry name="detail">youless Fetcher</entry>
- <entry name="version">1.00</entry>
+ <entry name="version">1.100</entry>
</metadata>
<flags>
<category name="basic">
@@ -30,10 +30,11 @@ local helpinfo = [[
<flag name="collect"><short>collect data from device</short></flag>
<flag name="nobackup"><short>don't backup old datafile</short></flag>
<flag name="nofile"><short>don't write data to file (for checking)</short></flag>
- <flag name="kwh"><short>summative kwh data</short></flag>
- <flag name="watt"><short>collected watt data</short></flag>
+ <flag name="electricity"><short>collected eletricity data (p)</short></flag>
+ <flag name="gas"><short>collected gas data</short></flag>
+ <flag name="pulse"><short>collected eletricity data (s)</short></flag>
<flag name="host"><short>ip address of device</short></flag>
- <flag name="auto"><short>fetch kwh and watt data every hour</short></flag>
+ <flag name="auto"><short>fetch (refresh) all data every hour</short></flag>
</subcategory>
</category>
</flags>
@@ -41,9 +42,10 @@ local helpinfo = [[
<category>
<title>Example</title>
<subcategory>
- <example><command>mtxrun --script youless --collect --host=192.168.2.50 --kwh</command></example>
- <example><command>mtxrun --script youless --collect --host=192.168.2.50 --watt somefile.lua</command></example>
- <example><command>mtxrun --script youless --collect --host=192.168.2.50 --auto file-prefix</command></example>
+ <example><command>mtxrun --script youless --collect --host=192.168.2.50 --electricity somefile.lua</command></example>
+ <example><command>mtxrun --script youless --collect --host=192.168.2.50 --gas somefile.lua</command></example>
+ <example><command>mtxrun --script youless --collect --host=192.168.2.50 --pulse somefile.lua</command></example>
+ <example><command>mtxrun --script youless --collect --host=192.168.2.50 --auto file-prefix</command></example>
</subcategory>
</category>
</examples>
@@ -52,7 +54,7 @@ local helpinfo = [[
local application = logs.application {
name = "mtx-youless",
- banner = "YouLess Fetcher 1.00",
+ banner = "YouLess Fetcher 1.100",
helpinfo = helpinfo,
}
@@ -103,19 +105,24 @@ function scripts.youless.collect()
end
if arguments.auto then
- local filename_kwh = formatters["%s-kwh.lua" ](filename ~= "" and filename or "youless")
- local filename_watt = formatters["%s-watt.lua"](filename ~= "" and filename or "youless")
+ local filename_electricity = formatters["%s-electricity.lua"](filename ~= "" and filename or "youless")
+ local filename_gas = formatters["%s-gas.lua" ] (filename ~= "" and filename or "youless")
+ local filename_pulse = formatters["%s-pulse.lua"] (filename ~= "" and filename or "youless")
while true do
- fetch(filename_kwh,"kwh")
- fetch(filename_watt,"watt")
+ fetch(filename_electricity,"electricity")
+ fetch(filename_gas, "gas")
+ fetch(filename_pulse, "pulse")
report("sleeping for %i seconds",delay)
io.flush()
os.sleep(delay)
end
else
- local variant = environment.arguments.kwh and "kwh" or environment.arguments.watt and "watt"
+ local variant = (environment.arguments.electricity and "electricity") or
+ (environment.arguments.watt and "electricity") or
+ (environment.arguments.gas and "gas") or
+ (environment.arguments.pulse and "pulse")
if not variant then
- report("provide variant --kwh or --watt")
+ report("provide variant --electricity, --gas or --pulse")
return
end
if nofile then
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index 656f4493f..576c95c1f 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -56,7 +56,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lua"] = package.loaded["l-lua"] or true
--- original size: 5427, stripped down to: 2974
+-- original size: 5478, stripped down to: 3018
if not modules then modules={} end modules ['l-lua']={
version=1.001,
@@ -65,6 +65,7 @@ if not modules then modules={} end modules ['l-lua']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
+local next,type,tonumber=next,type,tonumber
LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
LUAMAJORVERSION=tonumber(LUAMAJORVERSION) or 5
LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1
@@ -4382,7 +4383,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-url"] = package.loaded["l-url"] or true
--- original size: 12531, stripped down to: 5721
+-- original size: 12543, stripped down to: 5731
if not modules then modules={} end modules ['l-url']={
version=1.001,
@@ -4393,7 +4394,7 @@ if not modules then modules={} end modules ['l-url']={
}
local char,format,byte=string.char,string.format,string.byte
local concat=table.concat
-local tonumber,type=tonumber,type
+local tonumber,type,next=tonumber,type,next
local P,C,R,S,Cs,Cc,Ct,Cf,Cg,V=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Cf,lpeg.Cg,lpeg.V
local lpegmatch,lpegpatterns,replacer=lpeg.match,lpeg.patterns,lpeg.replacer
url=url or {}
@@ -5165,7 +5166,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 38825, stripped down to: 16749
+-- original size: 39368, stripped down to: 17066
if not modules then modules={} end modules ['l-unicode']={
version=1.001,
@@ -5806,6 +5807,25 @@ function unicode.toutf32string(n)
char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
end
end
+local len=utf.len
+local rep=rep
+function string.utfpadd(s,n)
+ if n and n~=0 then
+ local l=len(s)
+ if n>0 then
+ local d=n-l
+ if d>0 then
+ return rep(c or " ",d)..s
+ end
+ else
+ local d=- n-l
+ if d>0 then
+ return s..rep(c or " ",d)
+ end
+ end
+ end
+ return s
+end
end -- of closure
@@ -5910,7 +5930,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 37217, stripped down to: 20835
+-- original size: 38604, stripped down to: 21710
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -5924,11 +5944,11 @@ utilities.strings=utilities.strings or {}
local strings=utilities.strings
local format,gsub,rep,sub,find=string.format,string.gsub,string.rep,string.sub,string.find
local load,dump=load,string.dump
-local tonumber,type,tostring=tonumber,type,tostring
+local tonumber,type,tostring,next=tonumber,type,tostring,next
local unpack,concat=table.unpack,table.concat
local P,V,C,S,R,Ct,Cs,Cp,Carg,Cc=lpeg.P,lpeg.V,lpeg.C,lpeg.S,lpeg.R,lpeg.Ct,lpeg.Cs,lpeg.Cp,lpeg.Carg,lpeg.Cc
local patterns,lpegmatch=lpeg.patterns,lpeg.match
-local utfchar,utfbyte=utf.char,utf.byte
+local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len
local loadstripped=nil
if LUAVERSION<5.2 then
loadstripped=function(str,shortcuts)
@@ -6018,6 +6038,17 @@ local pattern=Carg(1)/function(t)
function strings.tabtospace(str,tab)
return lpegmatch(pattern,str,1,tab or 7)
end
+function string.utfpadding(s,n)
+ if not n or n==0 then
+ return ""
+ end
+ local l=utflen(s)
+ if n>0 then
+ return nspaces[n-l]
+ else
+ return nspaces[-n-l]
+ end
+end
local space=spacer^0
local nospace=space/""
local endofline=nospace*newline
@@ -6206,6 +6237,7 @@ local utfchar=utf.char
local utfbyte=utf.byte
local lpegmatch=lpeg.match
local nspaces=string.nspaces
+local utfpadding=string.utfpadding
local tracedchar=string.tracedchar
local autosingle=string.autosingle
local autodouble=string.autodouble
@@ -6230,6 +6262,7 @@ else
utfbyte=utf.byte,
lpegmatch=lpeg.match,
nspaces=string.nspaces,
+ utfpadding=string.utfpadding,
tracedchar=string.tracedchar,
autosingle=string.autosingle,
autodouble=string.autodouble,
@@ -6265,6 +6298,29 @@ local format_S=function(f)
return format("tostring(a%s)",n)
end
end
+local format_right=function(f)
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ elseif f>0 then
+ return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
+end
+local format_left=function(f)
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ end
+ if f<0 then
+ return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
+end
local format_q=function()
n=n+1
return format("(a%s and format('%%q',a%s) or '')",n,n)
@@ -6519,6 +6575,8 @@ local builder=Cs { "start",
+V("j")+V("J")
+V("m")+V("M")
+V("z")
++V(">")
++V("<")
)+V("*")
)*(P(-1)+Carg(1))
)^0,
@@ -6562,6 +6620,8 @@ local builder=Cs { "start",
["z"]=(prefix_any*P("z"))/format_z,
["a"]=(prefix_any*P("a"))/format_a,
["A"]=(prefix_any*P("A"))/format_A,
+ ["<"]=(prefix_any*P("<"))/format_left,
+ [">"]=(prefix_any*P(">"))/format_right,
["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
@@ -8056,7 +8116,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 22883, stripped down to: 16045
+-- original size: 22956, stripped down to: 16106
if not modules then modules={} end modules ['util-prs']={
version=1.001,
@@ -8474,14 +8534,16 @@ function parsers.rfc4180splitter(specification)
local field=escaped+non_escaped+Cc("")
local record=Ct(field*(separator*field)^1)
local headerline=record*Cp()
- local wholeblob=Ct((newline^(specification.strict and -1 or 1)*record)^0)
+ local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
+ local headeryes=Ct(morerecords)
+ local headernop=Ct(record*morerecords)
return function(data,getheader)
if getheader then
local header,position=lpegmatch(headerline,data)
- local data=lpegmatch(wholeblob,data,position)
+ local data=lpegmatch(headeryes,data,position)
return data,header
else
- return lpegmatch(wholeblob,data)
+ return lpegmatch(headernop,data)
end
end
end
@@ -8502,8 +8564,8 @@ end
local cardinal=lpegpatterns.cardinal/tonumber
local spacers=lpegpatterns.spacer^0
local endofstring=lpegpatterns.endofstring
-local stepper=spacers*(C(cardinal)*(spacers*S(":-")*spacers*(C(cardinal)+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
-local stepper=spacers*(C(cardinal)*(spacers*S(":-")*spacers*(C(cardinal)+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
+local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
+local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
function parsers.stepper(str,n,action)
if type(n)=="function" then
lpegmatch(stepper,str,1,false,n or print)
@@ -10099,7 +10161,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-pro"] = package.loaded["trac-pro"] or true
--- original size: 5829, stripped down to: 3501
+-- original size: 5841, stripped down to: 3511
if not modules then modules={} end modules ['trac-pro']={
version=1.001,
@@ -10108,7 +10170,7 @@ if not modules then modules={} end modules ['trac-pro']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
-local getmetatable,setmetatable,rawset,type=getmetatable,setmetatable,rawset,type
+local getmetatable,setmetatable,rawset,type,next=getmetatable,setmetatable,rawset,type,next
local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
local report_system=logs.reporter("system","protection")
namespaces=namespaces or {}
@@ -10683,7 +10745,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tpl"] = package.loaded["util-tpl"] or true
--- original size: 7100, stripped down to: 3978
+-- original size: 7112, stripped down to: 3988
if not modules then modules={} end modules ['util-tpl']={
version=1.001,
@@ -10696,7 +10758,7 @@ utilities.templates=utilities.templates or {}
local templates=utilities.templates
local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
local report_template=logs.reporter("template")
-local tostring=tostring
+local tostring,next=tostring,next
local format,sub,byte=string.format,string.sub,string.byte
local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
local replacer
@@ -15396,7 +15458,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
--- original size: 10400, stripped down to: 7659
+-- original size: 10412, stripped down to: 7669
if not modules then modules={} end modules ['lxml-xml']={
version=1.001,
@@ -15405,7 +15467,7 @@ if not modules then modules={} end modules ['lxml-xml']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
-local tonumber=tonumber
+local tonumber,next=tonumber,next
local concat=table.concat
local find,lower,upper=string.find,string.lower,string.upper
local xml=xml
@@ -16584,7 +16646,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-env"] = package.loaded["data-env"] or true
--- original size: 9342, stripped down to: 6887
+-- original size: 9360, stripped down to: 6903
if not modules then modules={} end modules ['data-env']={
version=1.001,
@@ -16594,6 +16656,7 @@ if not modules then modules={} end modules ['data-env']={
license="see context related readme files",
}
local lower,gsub=string.lower,string.gsub
+local next=next
local resolvers=resolvers
local allocate=utilities.storage.allocate
local setmetatableindex=table.setmetatableindex
@@ -16868,7 +16931,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16086, stripped down to: 11433
+-- original size: 16116, stripped down to: 11459
if not modules then modules={} end modules ['data-tmp']={
version=1.100,
@@ -16882,6 +16945,7 @@ local concat=table.concat
local mkdirs,isdir,isfile=dir.mkdirs,lfs.isdir,lfs.isfile
local addsuffix,is_writable,is_readable=file.addsuffix,file.is_writable,file.is_readable
local formatters=string.formatters
+local next,type=next,type
local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
local report_caches=logs.reporter("resolvers","caches")
@@ -21005,8 +21069,8 @@ end -- of closure
-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 866647
--- stripped bytes : 315334
+-- original bytes : 868797
+-- stripped bytes : 316105
-- end library merge
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index 656f4493f..576c95c1f 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -56,7 +56,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lua"] = package.loaded["l-lua"] or true
--- original size: 5427, stripped down to: 2974
+-- original size: 5478, stripped down to: 3018
if not modules then modules={} end modules ['l-lua']={
version=1.001,
@@ -65,6 +65,7 @@ if not modules then modules={} end modules ['l-lua']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
+local next,type,tonumber=next,type,tonumber
LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
LUAMAJORVERSION=tonumber(LUAMAJORVERSION) or 5
LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1
@@ -4382,7 +4383,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-url"] = package.loaded["l-url"] or true
--- original size: 12531, stripped down to: 5721
+-- original size: 12543, stripped down to: 5731
if not modules then modules={} end modules ['l-url']={
version=1.001,
@@ -4393,7 +4394,7 @@ if not modules then modules={} end modules ['l-url']={
}
local char,format,byte=string.char,string.format,string.byte
local concat=table.concat
-local tonumber,type=tonumber,type
+local tonumber,type,next=tonumber,type,next
local P,C,R,S,Cs,Cc,Ct,Cf,Cg,V=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Cf,lpeg.Cg,lpeg.V
local lpegmatch,lpegpatterns,replacer=lpeg.match,lpeg.patterns,lpeg.replacer
url=url or {}
@@ -5165,7 +5166,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 38825, stripped down to: 16749
+-- original size: 39368, stripped down to: 17066
if not modules then modules={} end modules ['l-unicode']={
version=1.001,
@@ -5806,6 +5807,25 @@ function unicode.toutf32string(n)
char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
end
end
+local len=utf.len
+local rep=rep
+function string.utfpadd(s,n)
+ if n and n~=0 then
+ local l=len(s)
+ if n>0 then
+ local d=n-l
+ if d>0 then
+ return rep(c or " ",d)..s
+ end
+ else
+ local d=- n-l
+ if d>0 then
+ return s..rep(c or " ",d)
+ end
+ end
+ end
+ return s
+end
end -- of closure
@@ -5910,7 +5930,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 37217, stripped down to: 20835
+-- original size: 38604, stripped down to: 21710
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -5924,11 +5944,11 @@ utilities.strings=utilities.strings or {}
local strings=utilities.strings
local format,gsub,rep,sub,find=string.format,string.gsub,string.rep,string.sub,string.find
local load,dump=load,string.dump
-local tonumber,type,tostring=tonumber,type,tostring
+local tonumber,type,tostring,next=tonumber,type,tostring,next
local unpack,concat=table.unpack,table.concat
local P,V,C,S,R,Ct,Cs,Cp,Carg,Cc=lpeg.P,lpeg.V,lpeg.C,lpeg.S,lpeg.R,lpeg.Ct,lpeg.Cs,lpeg.Cp,lpeg.Carg,lpeg.Cc
local patterns,lpegmatch=lpeg.patterns,lpeg.match
-local utfchar,utfbyte=utf.char,utf.byte
+local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len
local loadstripped=nil
if LUAVERSION<5.2 then
loadstripped=function(str,shortcuts)
@@ -6018,6 +6038,17 @@ local pattern=Carg(1)/function(t)
function strings.tabtospace(str,tab)
return lpegmatch(pattern,str,1,tab or 7)
end
+function string.utfpadding(s,n)
+ if not n or n==0 then
+ return ""
+ end
+ local l=utflen(s)
+ if n>0 then
+ return nspaces[n-l]
+ else
+ return nspaces[-n-l]
+ end
+end
local space=spacer^0
local nospace=space/""
local endofline=nospace*newline
@@ -6206,6 +6237,7 @@ local utfchar=utf.char
local utfbyte=utf.byte
local lpegmatch=lpeg.match
local nspaces=string.nspaces
+local utfpadding=string.utfpadding
local tracedchar=string.tracedchar
local autosingle=string.autosingle
local autodouble=string.autodouble
@@ -6230,6 +6262,7 @@ else
utfbyte=utf.byte,
lpegmatch=lpeg.match,
nspaces=string.nspaces,
+ utfpadding=string.utfpadding,
tracedchar=string.tracedchar,
autosingle=string.autosingle,
autodouble=string.autodouble,
@@ -6265,6 +6298,29 @@ local format_S=function(f)
return format("tostring(a%s)",n)
end
end
+local format_right=function(f)
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ elseif f>0 then
+ return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
+end
+local format_left=function(f)
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ end
+ if f<0 then
+ return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
+end
local format_q=function()
n=n+1
return format("(a%s and format('%%q',a%s) or '')",n,n)
@@ -6519,6 +6575,8 @@ local builder=Cs { "start",
+V("j")+V("J")
+V("m")+V("M")
+V("z")
++V(">")
++V("<")
)+V("*")
)*(P(-1)+Carg(1))
)^0,
@@ -6562,6 +6620,8 @@ local builder=Cs { "start",
["z"]=(prefix_any*P("z"))/format_z,
["a"]=(prefix_any*P("a"))/format_a,
["A"]=(prefix_any*P("A"))/format_A,
+ ["<"]=(prefix_any*P("<"))/format_left,
+ [">"]=(prefix_any*P(">"))/format_right,
["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
@@ -8056,7 +8116,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 22883, stripped down to: 16045
+-- original size: 22956, stripped down to: 16106
if not modules then modules={} end modules ['util-prs']={
version=1.001,
@@ -8474,14 +8534,16 @@ function parsers.rfc4180splitter(specification)
local field=escaped+non_escaped+Cc("")
local record=Ct(field*(separator*field)^1)
local headerline=record*Cp()
- local wholeblob=Ct((newline^(specification.strict and -1 or 1)*record)^0)
+ local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
+ local headeryes=Ct(morerecords)
+ local headernop=Ct(record*morerecords)
return function(data,getheader)
if getheader then
local header,position=lpegmatch(headerline,data)
- local data=lpegmatch(wholeblob,data,position)
+ local data=lpegmatch(headeryes,data,position)
return data,header
else
- return lpegmatch(wholeblob,data)
+ return lpegmatch(headernop,data)
end
end
end
@@ -8502,8 +8564,8 @@ end
local cardinal=lpegpatterns.cardinal/tonumber
local spacers=lpegpatterns.spacer^0
local endofstring=lpegpatterns.endofstring
-local stepper=spacers*(C(cardinal)*(spacers*S(":-")*spacers*(C(cardinal)+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
-local stepper=spacers*(C(cardinal)*(spacers*S(":-")*spacers*(C(cardinal)+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
+local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
+local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
function parsers.stepper(str,n,action)
if type(n)=="function" then
lpegmatch(stepper,str,1,false,n or print)
@@ -10099,7 +10161,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-pro"] = package.loaded["trac-pro"] or true
--- original size: 5829, stripped down to: 3501
+-- original size: 5841, stripped down to: 3511
if not modules then modules={} end modules ['trac-pro']={
version=1.001,
@@ -10108,7 +10170,7 @@ if not modules then modules={} end modules ['trac-pro']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
-local getmetatable,setmetatable,rawset,type=getmetatable,setmetatable,rawset,type
+local getmetatable,setmetatable,rawset,type,next=getmetatable,setmetatable,rawset,type,next
local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
local report_system=logs.reporter("system","protection")
namespaces=namespaces or {}
@@ -10683,7 +10745,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tpl"] = package.loaded["util-tpl"] or true
--- original size: 7100, stripped down to: 3978
+-- original size: 7112, stripped down to: 3988
if not modules then modules={} end modules ['util-tpl']={
version=1.001,
@@ -10696,7 +10758,7 @@ utilities.templates=utilities.templates or {}
local templates=utilities.templates
local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
local report_template=logs.reporter("template")
-local tostring=tostring
+local tostring,next=tostring,next
local format,sub,byte=string.format,string.sub,string.byte
local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
local replacer
@@ -15396,7 +15458,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
--- original size: 10400, stripped down to: 7659
+-- original size: 10412, stripped down to: 7669
if not modules then modules={} end modules ['lxml-xml']={
version=1.001,
@@ -15405,7 +15467,7 @@ if not modules then modules={} end modules ['lxml-xml']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
-local tonumber=tonumber
+local tonumber,next=tonumber,next
local concat=table.concat
local find,lower,upper=string.find,string.lower,string.upper
local xml=xml
@@ -16584,7 +16646,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-env"] = package.loaded["data-env"] or true
--- original size: 9342, stripped down to: 6887
+-- original size: 9360, stripped down to: 6903
if not modules then modules={} end modules ['data-env']={
version=1.001,
@@ -16594,6 +16656,7 @@ if not modules then modules={} end modules ['data-env']={
license="see context related readme files",
}
local lower,gsub=string.lower,string.gsub
+local next=next
local resolvers=resolvers
local allocate=utilities.storage.allocate
local setmetatableindex=table.setmetatableindex
@@ -16868,7 +16931,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16086, stripped down to: 11433
+-- original size: 16116, stripped down to: 11459
if not modules then modules={} end modules ['data-tmp']={
version=1.100,
@@ -16882,6 +16945,7 @@ local concat=table.concat
local mkdirs,isdir,isfile=dir.mkdirs,lfs.isdir,lfs.isfile
local addsuffix,is_writable,is_readable=file.addsuffix,file.is_writable,file.is_readable
local formatters=string.formatters
+local next,type=next,type
local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
local report_caches=logs.reporter("resolvers","caches")
@@ -21005,8 +21069,8 @@ end -- of closure
-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 866647
--- stripped bytes : 315334
+-- original bytes : 868797
+-- stripped bytes : 316105
-- end library merge
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index 656f4493f..576c95c1f 100644
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -56,7 +56,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lua"] = package.loaded["l-lua"] or true
--- original size: 5427, stripped down to: 2974
+-- original size: 5478, stripped down to: 3018
if not modules then modules={} end modules ['l-lua']={
version=1.001,
@@ -65,6 +65,7 @@ if not modules then modules={} end modules ['l-lua']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
+local next,type,tonumber=next,type,tonumber
LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
LUAMAJORVERSION=tonumber(LUAMAJORVERSION) or 5
LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1
@@ -4382,7 +4383,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-url"] = package.loaded["l-url"] or true
--- original size: 12531, stripped down to: 5721
+-- original size: 12543, stripped down to: 5731
if not modules then modules={} end modules ['l-url']={
version=1.001,
@@ -4393,7 +4394,7 @@ if not modules then modules={} end modules ['l-url']={
}
local char,format,byte=string.char,string.format,string.byte
local concat=table.concat
-local tonumber,type=tonumber,type
+local tonumber,type,next=tonumber,type,next
local P,C,R,S,Cs,Cc,Ct,Cf,Cg,V=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Cf,lpeg.Cg,lpeg.V
local lpegmatch,lpegpatterns,replacer=lpeg.match,lpeg.patterns,lpeg.replacer
url=url or {}
@@ -5165,7 +5166,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 38825, stripped down to: 16749
+-- original size: 39368, stripped down to: 17066
if not modules then modules={} end modules ['l-unicode']={
version=1.001,
@@ -5806,6 +5807,25 @@ function unicode.toutf32string(n)
char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
end
end
+local len=utf.len
+local rep=rep
+function string.utfpadd(s,n)
+ if n and n~=0 then
+ local l=len(s)
+ if n>0 then
+ local d=n-l
+ if d>0 then
+ return rep(c or " ",d)..s
+ end
+ else
+ local d=- n-l
+ if d>0 then
+ return s..rep(c or " ",d)
+ end
+ end
+ end
+ return s
+end
end -- of closure
@@ -5910,7 +5930,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 37217, stripped down to: 20835
+-- original size: 38604, stripped down to: 21710
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -5924,11 +5944,11 @@ utilities.strings=utilities.strings or {}
local strings=utilities.strings
local format,gsub,rep,sub,find=string.format,string.gsub,string.rep,string.sub,string.find
local load,dump=load,string.dump
-local tonumber,type,tostring=tonumber,type,tostring
+local tonumber,type,tostring,next=tonumber,type,tostring,next
local unpack,concat=table.unpack,table.concat
local P,V,C,S,R,Ct,Cs,Cp,Carg,Cc=lpeg.P,lpeg.V,lpeg.C,lpeg.S,lpeg.R,lpeg.Ct,lpeg.Cs,lpeg.Cp,lpeg.Carg,lpeg.Cc
local patterns,lpegmatch=lpeg.patterns,lpeg.match
-local utfchar,utfbyte=utf.char,utf.byte
+local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len
local loadstripped=nil
if LUAVERSION<5.2 then
loadstripped=function(str,shortcuts)
@@ -6018,6 +6038,17 @@ local pattern=Carg(1)/function(t)
function strings.tabtospace(str,tab)
return lpegmatch(pattern,str,1,tab or 7)
end
+function string.utfpadding(s,n)
+ if not n or n==0 then
+ return ""
+ end
+ local l=utflen(s)
+ if n>0 then
+ return nspaces[n-l]
+ else
+ return nspaces[-n-l]
+ end
+end
local space=spacer^0
local nospace=space/""
local endofline=nospace*newline
@@ -6206,6 +6237,7 @@ local utfchar=utf.char
local utfbyte=utf.byte
local lpegmatch=lpeg.match
local nspaces=string.nspaces
+local utfpadding=string.utfpadding
local tracedchar=string.tracedchar
local autosingle=string.autosingle
local autodouble=string.autodouble
@@ -6230,6 +6262,7 @@ else
utfbyte=utf.byte,
lpegmatch=lpeg.match,
nspaces=string.nspaces,
+ utfpadding=string.utfpadding,
tracedchar=string.tracedchar,
autosingle=string.autosingle,
autodouble=string.autodouble,
@@ -6265,6 +6298,29 @@ local format_S=function(f)
return format("tostring(a%s)",n)
end
end
+local format_right=function(f)
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ elseif f>0 then
+ return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
+end
+local format_left=function(f)
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ end
+ if f<0 then
+ return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
+end
local format_q=function()
n=n+1
return format("(a%s and format('%%q',a%s) or '')",n,n)
@@ -6519,6 +6575,8 @@ local builder=Cs { "start",
+V("j")+V("J")
+V("m")+V("M")
+V("z")
++V(">")
++V("<")
)+V("*")
)*(P(-1)+Carg(1))
)^0,
@@ -6562,6 +6620,8 @@ local builder=Cs { "start",
["z"]=(prefix_any*P("z"))/format_z,
["a"]=(prefix_any*P("a"))/format_a,
["A"]=(prefix_any*P("A"))/format_A,
+ ["<"]=(prefix_any*P("<"))/format_left,
+ [">"]=(prefix_any*P(">"))/format_right,
["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
@@ -8056,7 +8116,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 22883, stripped down to: 16045
+-- original size: 22956, stripped down to: 16106
if not modules then modules={} end modules ['util-prs']={
version=1.001,
@@ -8474,14 +8534,16 @@ function parsers.rfc4180splitter(specification)
local field=escaped+non_escaped+Cc("")
local record=Ct(field*(separator*field)^1)
local headerline=record*Cp()
- local wholeblob=Ct((newline^(specification.strict and -1 or 1)*record)^0)
+ local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
+ local headeryes=Ct(morerecords)
+ local headernop=Ct(record*morerecords)
return function(data,getheader)
if getheader then
local header,position=lpegmatch(headerline,data)
- local data=lpegmatch(wholeblob,data,position)
+ local data=lpegmatch(headeryes,data,position)
return data,header
else
- return lpegmatch(wholeblob,data)
+ return lpegmatch(headernop,data)
end
end
end
@@ -8502,8 +8564,8 @@ end
local cardinal=lpegpatterns.cardinal/tonumber
local spacers=lpegpatterns.spacer^0
local endofstring=lpegpatterns.endofstring
-local stepper=spacers*(C(cardinal)*(spacers*S(":-")*spacers*(C(cardinal)+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
-local stepper=spacers*(C(cardinal)*(spacers*S(":-")*spacers*(C(cardinal)+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
+local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
+local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
function parsers.stepper(str,n,action)
if type(n)=="function" then
lpegmatch(stepper,str,1,false,n or print)
@@ -10099,7 +10161,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-pro"] = package.loaded["trac-pro"] or true
--- original size: 5829, stripped down to: 3501
+-- original size: 5841, stripped down to: 3511
if not modules then modules={} end modules ['trac-pro']={
version=1.001,
@@ -10108,7 +10170,7 @@ if not modules then modules={} end modules ['trac-pro']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
-local getmetatable,setmetatable,rawset,type=getmetatable,setmetatable,rawset,type
+local getmetatable,setmetatable,rawset,type,next=getmetatable,setmetatable,rawset,type,next
local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
local report_system=logs.reporter("system","protection")
namespaces=namespaces or {}
@@ -10683,7 +10745,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tpl"] = package.loaded["util-tpl"] or true
--- original size: 7100, stripped down to: 3978
+-- original size: 7112, stripped down to: 3988
if not modules then modules={} end modules ['util-tpl']={
version=1.001,
@@ -10696,7 +10758,7 @@ utilities.templates=utilities.templates or {}
local templates=utilities.templates
local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
local report_template=logs.reporter("template")
-local tostring=tostring
+local tostring,next=tostring,next
local format,sub,byte=string.format,string.sub,string.byte
local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
local replacer
@@ -15396,7 +15458,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
--- original size: 10400, stripped down to: 7659
+-- original size: 10412, stripped down to: 7669
if not modules then modules={} end modules ['lxml-xml']={
version=1.001,
@@ -15405,7 +15467,7 @@ if not modules then modules={} end modules ['lxml-xml']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
-local tonumber=tonumber
+local tonumber,next=tonumber,next
local concat=table.concat
local find,lower,upper=string.find,string.lower,string.upper
local xml=xml
@@ -16584,7 +16646,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-env"] = package.loaded["data-env"] or true
--- original size: 9342, stripped down to: 6887
+-- original size: 9360, stripped down to: 6903
if not modules then modules={} end modules ['data-env']={
version=1.001,
@@ -16594,6 +16656,7 @@ if not modules then modules={} end modules ['data-env']={
license="see context related readme files",
}
local lower,gsub=string.lower,string.gsub
+local next=next
local resolvers=resolvers
local allocate=utilities.storage.allocate
local setmetatableindex=table.setmetatableindex
@@ -16868,7 +16931,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16086, stripped down to: 11433
+-- original size: 16116, stripped down to: 11459
if not modules then modules={} end modules ['data-tmp']={
version=1.100,
@@ -16882,6 +16945,7 @@ local concat=table.concat
local mkdirs,isdir,isfile=dir.mkdirs,lfs.isdir,lfs.isfile
local addsuffix,is_writable,is_readable=file.addsuffix,file.is_writable,file.is_readable
local formatters=string.formatters
+local next,type=next,type
local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
local report_caches=logs.reporter("resolvers","caches")
@@ -21005,8 +21069,8 @@ end -- of closure
-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 866647
--- stripped bytes : 315334
+-- original bytes : 868797
+-- stripped bytes : 316105
-- end library merge
diff --git a/scripts/context/stubs/win64/mtxrun.lua b/scripts/context/stubs/win64/mtxrun.lua
index 656f4493f..576c95c1f 100644
--- a/scripts/context/stubs/win64/mtxrun.lua
+++ b/scripts/context/stubs/win64/mtxrun.lua
@@ -56,7 +56,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lua"] = package.loaded["l-lua"] or true
--- original size: 5427, stripped down to: 2974
+-- original size: 5478, stripped down to: 3018
if not modules then modules={} end modules ['l-lua']={
version=1.001,
@@ -65,6 +65,7 @@ if not modules then modules={} end modules ['l-lua']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
+local next,type,tonumber=next,type,tonumber
LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
LUAMAJORVERSION=tonumber(LUAMAJORVERSION) or 5
LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1
@@ -4382,7 +4383,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-url"] = package.loaded["l-url"] or true
--- original size: 12531, stripped down to: 5721
+-- original size: 12543, stripped down to: 5731
if not modules then modules={} end modules ['l-url']={
version=1.001,
@@ -4393,7 +4394,7 @@ if not modules then modules={} end modules ['l-url']={
}
local char,format,byte=string.char,string.format,string.byte
local concat=table.concat
-local tonumber,type=tonumber,type
+local tonumber,type,next=tonumber,type,next
local P,C,R,S,Cs,Cc,Ct,Cf,Cg,V=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Cf,lpeg.Cg,lpeg.V
local lpegmatch,lpegpatterns,replacer=lpeg.match,lpeg.patterns,lpeg.replacer
url=url or {}
@@ -5165,7 +5166,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 38825, stripped down to: 16749
+-- original size: 39368, stripped down to: 17066
if not modules then modules={} end modules ['l-unicode']={
version=1.001,
@@ -5806,6 +5807,25 @@ function unicode.toutf32string(n)
char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
end
end
+local len=utf.len
+local rep=rep
+function string.utfpadd(s,n)
+ if n and n~=0 then
+ local l=len(s)
+ if n>0 then
+ local d=n-l
+ if d>0 then
+ return rep(c or " ",d)..s
+ end
+ else
+ local d=- n-l
+ if d>0 then
+ return s..rep(c or " ",d)
+ end
+ end
+ end
+ return s
+end
end -- of closure
@@ -5910,7 +5930,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 37217, stripped down to: 20835
+-- original size: 38604, stripped down to: 21710
if not modules then modules={} end modules ['util-str']={
version=1.001,
@@ -5924,11 +5944,11 @@ utilities.strings=utilities.strings or {}
local strings=utilities.strings
local format,gsub,rep,sub,find=string.format,string.gsub,string.rep,string.sub,string.find
local load,dump=load,string.dump
-local tonumber,type,tostring=tonumber,type,tostring
+local tonumber,type,tostring,next=tonumber,type,tostring,next
local unpack,concat=table.unpack,table.concat
local P,V,C,S,R,Ct,Cs,Cp,Carg,Cc=lpeg.P,lpeg.V,lpeg.C,lpeg.S,lpeg.R,lpeg.Ct,lpeg.Cs,lpeg.Cp,lpeg.Carg,lpeg.Cc
local patterns,lpegmatch=lpeg.patterns,lpeg.match
-local utfchar,utfbyte=utf.char,utf.byte
+local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len
local loadstripped=nil
if LUAVERSION<5.2 then
loadstripped=function(str,shortcuts)
@@ -6018,6 +6038,17 @@ local pattern=Carg(1)/function(t)
function strings.tabtospace(str,tab)
return lpegmatch(pattern,str,1,tab or 7)
end
+function string.utfpadding(s,n)
+ if not n or n==0 then
+ return ""
+ end
+ local l=utflen(s)
+ if n>0 then
+ return nspaces[n-l]
+ else
+ return nspaces[-n-l]
+ end
+end
local space=spacer^0
local nospace=space/""
local endofline=nospace*newline
@@ -6206,6 +6237,7 @@ local utfchar=utf.char
local utfbyte=utf.byte
local lpegmatch=lpeg.match
local nspaces=string.nspaces
+local utfpadding=string.utfpadding
local tracedchar=string.tracedchar
local autosingle=string.autosingle
local autodouble=string.autodouble
@@ -6230,6 +6262,7 @@ else
utfbyte=utf.byte,
lpegmatch=lpeg.match,
nspaces=string.nspaces,
+ utfpadding=string.utfpadding,
tracedchar=string.tracedchar,
autosingle=string.autosingle,
autodouble=string.autodouble,
@@ -6265,6 +6298,29 @@ local format_S=function(f)
return format("tostring(a%s)",n)
end
end
+local format_right=function(f)
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ elseif f>0 then
+ return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
+end
+local format_left=function(f)
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ end
+ if f<0 then
+ return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
+end
local format_q=function()
n=n+1
return format("(a%s and format('%%q',a%s) or '')",n,n)
@@ -6519,6 +6575,8 @@ local builder=Cs { "start",
+V("j")+V("J")
+V("m")+V("M")
+V("z")
++V(">")
++V("<")
)+V("*")
)*(P(-1)+Carg(1))
)^0,
@@ -6562,6 +6620,8 @@ local builder=Cs { "start",
["z"]=(prefix_any*P("z"))/format_z,
["a"]=(prefix_any*P("a"))/format_a,
["A"]=(prefix_any*P("A"))/format_A,
+ ["<"]=(prefix_any*P("<"))/format_left,
+ [">"]=(prefix_any*P(">"))/format_right,
["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
@@ -8056,7 +8116,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 22883, stripped down to: 16045
+-- original size: 22956, stripped down to: 16106
if not modules then modules={} end modules ['util-prs']={
version=1.001,
@@ -8474,14 +8534,16 @@ function parsers.rfc4180splitter(specification)
local field=escaped+non_escaped+Cc("")
local record=Ct(field*(separator*field)^1)
local headerline=record*Cp()
- local wholeblob=Ct((newline^(specification.strict and -1 or 1)*record)^0)
+ local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
+ local headeryes=Ct(morerecords)
+ local headernop=Ct(record*morerecords)
return function(data,getheader)
if getheader then
local header,position=lpegmatch(headerline,data)
- local data=lpegmatch(wholeblob,data,position)
+ local data=lpegmatch(headeryes,data,position)
return data,header
else
- return lpegmatch(wholeblob,data)
+ return lpegmatch(headernop,data)
end
end
end
@@ -8502,8 +8564,8 @@ end
local cardinal=lpegpatterns.cardinal/tonumber
local spacers=lpegpatterns.spacer^0
local endofstring=lpegpatterns.endofstring
-local stepper=spacers*(C(cardinal)*(spacers*S(":-")*spacers*(C(cardinal)+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
-local stepper=spacers*(C(cardinal)*(spacers*S(":-")*spacers*(C(cardinal)+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
+local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
+local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
function parsers.stepper(str,n,action)
if type(n)=="function" then
lpegmatch(stepper,str,1,false,n or print)
@@ -10099,7 +10161,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-pro"] = package.loaded["trac-pro"] or true
--- original size: 5829, stripped down to: 3501
+-- original size: 5841, stripped down to: 3511
if not modules then modules={} end modules ['trac-pro']={
version=1.001,
@@ -10108,7 +10170,7 @@ if not modules then modules={} end modules ['trac-pro']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
-local getmetatable,setmetatable,rawset,type=getmetatable,setmetatable,rawset,type
+local getmetatable,setmetatable,rawset,type,next=getmetatable,setmetatable,rawset,type,next
local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
local report_system=logs.reporter("system","protection")
namespaces=namespaces or {}
@@ -10683,7 +10745,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tpl"] = package.loaded["util-tpl"] or true
--- original size: 7100, stripped down to: 3978
+-- original size: 7112, stripped down to: 3988
if not modules then modules={} end modules ['util-tpl']={
version=1.001,
@@ -10696,7 +10758,7 @@ utilities.templates=utilities.templates or {}
local templates=utilities.templates
local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
local report_template=logs.reporter("template")
-local tostring=tostring
+local tostring,next=tostring,next
local format,sub,byte=string.format,string.sub,string.byte
local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
local replacer
@@ -15396,7 +15458,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
--- original size: 10400, stripped down to: 7659
+-- original size: 10412, stripped down to: 7669
if not modules then modules={} end modules ['lxml-xml']={
version=1.001,
@@ -15405,7 +15467,7 @@ if not modules then modules={} end modules ['lxml-xml']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
-local tonumber=tonumber
+local tonumber,next=tonumber,next
local concat=table.concat
local find,lower,upper=string.find,string.lower,string.upper
local xml=xml
@@ -16584,7 +16646,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-env"] = package.loaded["data-env"] or true
--- original size: 9342, stripped down to: 6887
+-- original size: 9360, stripped down to: 6903
if not modules then modules={} end modules ['data-env']={
version=1.001,
@@ -16594,6 +16656,7 @@ if not modules then modules={} end modules ['data-env']={
license="see context related readme files",
}
local lower,gsub=string.lower,string.gsub
+local next=next
local resolvers=resolvers
local allocate=utilities.storage.allocate
local setmetatableindex=table.setmetatableindex
@@ -16868,7 +16931,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16086, stripped down to: 11433
+-- original size: 16116, stripped down to: 11459
if not modules then modules={} end modules ['data-tmp']={
version=1.100,
@@ -16882,6 +16945,7 @@ local concat=table.concat
local mkdirs,isdir,isfile=dir.mkdirs,lfs.isdir,lfs.isfile
local addsuffix,is_writable,is_readable=file.addsuffix,file.is_writable,file.is_readable
local formatters=string.formatters
+local next,type=next,type
local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
local report_caches=logs.reporter("resolvers","caches")
@@ -21005,8 +21069,8 @@ end -- of closure
-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 866647
--- stripped bytes : 315334
+-- original bytes : 868797
+-- stripped bytes : 316105
-- end library merge
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 6a789e77d..83849d219 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2017.11.22 13:35}
+\newcontextversion{2018.01.08 23:03}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index 6c74abf3a..bf662cb56 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2017.11.22 13:35}
+\edef\contextversion{2018.01.08 23:03}
%D For those who want to use this:
diff --git a/tex/context/base/mkii/mult-cs.mkii b/tex/context/base/mkii/mult-cs.mkii
index 61ddaa391..fdce40a3a 100644
--- a/tex/context/base/mkii/mult-cs.mkii
+++ b/tex/context/base/mkii/mult-cs.mkii
@@ -621,6 +621,10 @@
\setinterfaceconstant{align}{zarovnani}
\setinterfaceconstant{aligncharacter}{aligncharacter}
\setinterfaceconstant{alignmentcharacter}{alignmentcharacter}
+\setinterfaceconstant{alignmentleftsample}{alignmentleftsample}
+\setinterfaceconstant{alignmentleftwidth}{alignmentleftwidth}
+\setinterfaceconstant{alignmentrightsample}{alignmentrightsample}
+\setinterfaceconstant{alignmentrightwidth}{alignmentrightwidth}
\setinterfaceconstant{alignsymbol}{alignsymbol}
\setinterfaceconstant{aligntitle}{zarovnejtitul}
\setinterfaceconstant{alternative}{alternativa}
@@ -907,6 +911,7 @@
\setinterfaceconstant{leftoffset}{levyoffset}
\setinterfaceconstant{leftquotation}{citacevlevo}
\setinterfaceconstant{leftquote}{citovatvlevo}
+\setinterfaceconstant{leftsample}{leftsample}
\setinterfaceconstant{leftsentence}{vetavlevo}
\setinterfaceconstant{leftspeech}{leftspeech}
\setinterfaceconstant{leftstyle}{stylvlevo}
@@ -979,6 +984,7 @@
\setinterfaceconstant{nlines}{nradky}
\setinterfaceconstant{norm}{norm}
\setinterfaceconstant{note}{note}
+\setinterfaceconstant{notes}{notes}
\setinterfaceconstant{nr}{nr}
\setinterfaceconstant{nright}{nvpravo}
\setinterfaceconstant{ntop}{nvrsek}
@@ -1109,6 +1115,7 @@
\setinterfaceconstant{rightoffset}{pravyoffset}
\setinterfaceconstant{rightquotation}{citacevpravo}
\setinterfaceconstant{rightquote}{citovatvpravo}
+\setinterfaceconstant{rightsample}{rightsample}
\setinterfaceconstant{rightsentence}{vetavpravo}
\setinterfaceconstant{rightspeech}{rightspeech}
\setinterfaceconstant{rightstyle}{stylvpravo}
diff --git a/tex/context/base/mkii/mult-de.mkii b/tex/context/base/mkii/mult-de.mkii
index 5f8545a90..e26ceb851 100644
--- a/tex/context/base/mkii/mult-de.mkii
+++ b/tex/context/base/mkii/mult-de.mkii
@@ -376,6 +376,7 @@
\setinterfacevariable{norepeat}{norepeat}
\setinterfacevariable{normal}{normal}
\setinterfacevariable{nospacing}{nospacing}
+\setinterfacevariable{nostopper}{nostopper}
\setinterfacevariable{not}{nicht}
\setinterfacevariable{notation}{notation}
\setinterfacevariable{note}{note}
@@ -621,6 +622,10 @@
\setinterfaceconstant{align}{ausrichtung}
\setinterfaceconstant{aligncharacter}{aligncharacter}
\setinterfaceconstant{alignmentcharacter}{alignmentcharacter}
+\setinterfaceconstant{alignmentleftsample}{alignmentleftsample}
+\setinterfaceconstant{alignmentleftwidth}{alignmentleftwidth}
+\setinterfaceconstant{alignmentrightsample}{alignmentrightsample}
+\setinterfaceconstant{alignmentrightwidth}{alignmentrightwidth}
\setinterfaceconstant{alignsymbol}{alignsymbol}
\setinterfaceconstant{aligntitle}{titelausrichten}
\setinterfaceconstant{alternative}{alternative}
@@ -907,6 +912,7 @@
\setinterfaceconstant{leftoffset}{linkeroffset}
\setinterfaceconstant{leftquotation}{linkerzitat}
\setinterfaceconstant{leftquote}{linkerzitieren}
+\setinterfaceconstant{leftsample}{leftsample}
\setinterfaceconstant{leftsentence}{linkersatz}
\setinterfaceconstant{leftspeech}{leftspeech}
\setinterfaceconstant{leftstyle}{linkerstil}
@@ -979,6 +985,7 @@
\setinterfaceconstant{nlines}{zzeile}
\setinterfaceconstant{norm}{norm}
\setinterfaceconstant{note}{note}
+\setinterfaceconstant{notes}{notes}
\setinterfaceconstant{nr}{nr}
\setinterfaceconstant{nright}{nrechts}
\setinterfaceconstant{ntop}{noben}
@@ -1109,6 +1116,7 @@
\setinterfaceconstant{rightoffset}{rechterabstand}
\setinterfaceconstant{rightquotation}{rechterzitat}
\setinterfaceconstant{rightquote}{rechterzitieren}
+\setinterfaceconstant{rightsample}{rightsample}
\setinterfaceconstant{rightsentence}{rechtersatz}
\setinterfaceconstant{rightspeech}{rightspeech}
\setinterfaceconstant{rightstyle}{rechterstil}
@@ -1165,7 +1173,9 @@
\setinterfaceconstant{source}{quelle}
\setinterfaceconstant{space}{spatium}
\setinterfaceconstant{spaceafter}{nachspatium}
+\setinterfaceconstant{spaceafterside}{spaceafterside}
\setinterfaceconstant{spacebefore}{vorspatium}
+\setinterfaceconstant{spacebeforeside}{spacebeforeside}
\setinterfaceconstant{spaceinbetween}{spaceinbetween}
\setinterfaceconstant{spacing}{spatiumausgleich}
\setinterfaceconstant{specification}{specification}
diff --git a/tex/context/base/mkii/mult-en.mkii b/tex/context/base/mkii/mult-en.mkii
index ca4675c08..cc9cc5feb 100644
--- a/tex/context/base/mkii/mult-en.mkii
+++ b/tex/context/base/mkii/mult-en.mkii
@@ -376,6 +376,7 @@
\setinterfacevariable{norepeat}{norepeat}
\setinterfacevariable{normal}{normal}
\setinterfacevariable{nospacing}{nospacing}
+\setinterfacevariable{nostopper}{nostopper}
\setinterfacevariable{not}{not}
\setinterfacevariable{notation}{notation}
\setinterfacevariable{note}{note}
@@ -621,6 +622,10 @@
\setinterfaceconstant{align}{align}
\setinterfaceconstant{aligncharacter}{aligncharacter}
\setinterfaceconstant{alignmentcharacter}{alignmentcharacter}
+\setinterfaceconstant{alignmentleftsample}{alignmentleftsample}
+\setinterfaceconstant{alignmentleftwidth}{alignmentleftwidth}
+\setinterfaceconstant{alignmentrightsample}{alignmentrightsample}
+\setinterfaceconstant{alignmentrightwidth}{alignmentrightwidth}
\setinterfaceconstant{alignsymbol}{alignsymbol}
\setinterfaceconstant{aligntitle}{aligntitle}
\setinterfaceconstant{alternative}{alternative}
@@ -907,6 +912,7 @@
\setinterfaceconstant{leftoffset}{leftoffset}
\setinterfaceconstant{leftquotation}{leftquotation}
\setinterfaceconstant{leftquote}{leftquote}
+\setinterfaceconstant{leftsample}{leftsample}
\setinterfaceconstant{leftsentence}{leftsentence}
\setinterfaceconstant{leftspeech}{leftspeech}
\setinterfaceconstant{leftstyle}{leftstyle}
@@ -979,6 +985,7 @@
\setinterfaceconstant{nlines}{nlines}
\setinterfaceconstant{norm}{norm}
\setinterfaceconstant{note}{note}
+\setinterfaceconstant{notes}{notes}
\setinterfaceconstant{nr}{nr}
\setinterfaceconstant{nright}{nright}
\setinterfaceconstant{ntop}{ntop}
@@ -998,6 +1005,7 @@
\setinterfaceconstant{numberset}{numberset}
\setinterfaceconstant{numberstarter}{numberstarter}
\setinterfaceconstant{numberstopper}{numberstopper}
+\setinterfaceconstant{numberstrut}{numberstrut}
\setinterfaceconstant{numberstyle}{numberstyle}
\setinterfaceconstant{numberwidth}{numberwidth}
\setinterfaceconstant{nx}{nx}
@@ -1109,6 +1117,7 @@
\setinterfaceconstant{rightoffset}{rightoffset}
\setinterfaceconstant{rightquotation}{rightquotation}
\setinterfaceconstant{rightquote}{rightquote}
+\setinterfaceconstant{rightsample}{rightsample}
\setinterfaceconstant{rightsentence}{rightsentence}
\setinterfaceconstant{rightspeech}{rightspeech}
\setinterfaceconstant{rightstyle}{rightstyle}
@@ -1165,7 +1174,9 @@
\setinterfaceconstant{source}{source}
\setinterfaceconstant{space}{space}
\setinterfaceconstant{spaceafter}{spaceafter}
+\setinterfaceconstant{spaceafterside}{spaceafterside}
\setinterfaceconstant{spacebefore}{spacebefore}
+\setinterfaceconstant{spacebeforeside}{spacebeforeside}
\setinterfaceconstant{spaceinbetween}{spaceinbetween}
\setinterfaceconstant{spacing}{spacing}
\setinterfaceconstant{specification}{specification}
@@ -1230,6 +1241,7 @@
\setinterfaceconstant{titledistance}{titledistance}
\setinterfaceconstant{titleleft}{titleleft}
\setinterfaceconstant{titleright}{titleright}
+\setinterfaceconstant{titlestrut}{titlestrut}
\setinterfaceconstant{titlestyle}{titlestyle}
\setinterfaceconstant{to}{to}
\setinterfaceconstant{toffset}{toffset}
diff --git a/tex/context/base/mkii/mult-fr.mkii b/tex/context/base/mkii/mult-fr.mkii
index 42335c3ac..926b52f7b 100644
--- a/tex/context/base/mkii/mult-fr.mkii
+++ b/tex/context/base/mkii/mult-fr.mkii
@@ -621,6 +621,10 @@
\setinterfaceconstant{align}{alignement}
\setinterfaceconstant{aligncharacter}{caracterealigne}
\setinterfaceconstant{alignmentcharacter}{alignementcaractere}
+\setinterfaceconstant{alignmentleftsample}{alignmentleftsample}
+\setinterfaceconstant{alignmentleftwidth}{alignmentleftwidth}
+\setinterfaceconstant{alignmentrightsample}{alignmentrightsample}
+\setinterfaceconstant{alignmentrightwidth}{alignmentrightwidth}
\setinterfaceconstant{alignsymbol}{alignsymbol}
\setinterfaceconstant{aligntitle}{alignementtitre}
\setinterfaceconstant{alternative}{alternative}
@@ -907,6 +911,7 @@
\setinterfaceconstant{leftoffset}{decalagegauche}
\setinterfaceconstant{leftquotation}{citationgauche}
\setinterfaceconstant{leftquote}{citergauche}
+\setinterfaceconstant{leftsample}{leftsample}
\setinterfaceconstant{leftsentence}{phrasegauche}
\setinterfaceconstant{leftspeech}{leftspeech}
\setinterfaceconstant{leftstyle}{leftstyle}
@@ -979,6 +984,7 @@
\setinterfaceconstant{nlines}{nlignes}
\setinterfaceconstant{norm}{norme}
\setinterfaceconstant{note}{note}
+\setinterfaceconstant{notes}{notes}
\setinterfaceconstant{nr}{nr}
\setinterfaceconstant{nright}{ndroite}
\setinterfaceconstant{ntop}{nsup}
@@ -1109,6 +1115,7 @@
\setinterfaceconstant{rightoffset}{rightoffset}
\setinterfaceconstant{rightquotation}{citationdroite}
\setinterfaceconstant{rightquote}{citerdroite}
+\setinterfaceconstant{rightsample}{rightsample}
\setinterfaceconstant{rightsentence}{phrasedroite}
\setinterfaceconstant{rightspeech}{rightspeech}
\setinterfaceconstant{rightstyle}{styledroit}
diff --git a/tex/context/base/mkii/mult-it.mkii b/tex/context/base/mkii/mult-it.mkii
index 7cc5b6524..79cb6de4e 100644
--- a/tex/context/base/mkii/mult-it.mkii
+++ b/tex/context/base/mkii/mult-it.mkii
@@ -376,6 +376,7 @@
\setinterfacevariable{norepeat}{norepeat}
\setinterfacevariable{normal}{normale}
\setinterfacevariable{nospacing}{nospacing}
+\setinterfacevariable{nostopper}{nostopper}
\setinterfacevariable{not}{non}
\setinterfacevariable{notation}{notation}
\setinterfacevariable{note}{note}
@@ -621,6 +622,10 @@
\setinterfaceconstant{align}{allinea}
\setinterfaceconstant{aligncharacter}{allineacarattere}
\setinterfaceconstant{alignmentcharacter}{carattereallineamento}
+\setinterfaceconstant{alignmentleftsample}{alignmentleftsample}
+\setinterfaceconstant{alignmentleftwidth}{alignmentleftwidth}
+\setinterfaceconstant{alignmentrightsample}{alignmentrightsample}
+\setinterfaceconstant{alignmentrightwidth}{alignmentrightwidth}
\setinterfaceconstant{alignsymbol}{alignsymbol}
\setinterfaceconstant{aligntitle}{allineatitolo}
\setinterfaceconstant{alternative}{alternativa}
@@ -907,6 +912,7 @@
\setinterfaceconstant{leftoffset}{offsetsinistro}
\setinterfaceconstant{leftquotation}{citazionesinistra}
\setinterfaceconstant{leftquote}{menzionesinistra}
+\setinterfaceconstant{leftsample}{leftsample}
\setinterfaceconstant{leftsentence}{frasesinistra}
\setinterfaceconstant{leftspeech}{leftspeech}
\setinterfaceconstant{leftstyle}{stilesinistra}
@@ -979,6 +985,7 @@
\setinterfaceconstant{nlines}{nrighe}
\setinterfaceconstant{norm}{norma}
\setinterfaceconstant{note}{note}
+\setinterfaceconstant{notes}{notes}
\setinterfaceconstant{nr}{nr}
\setinterfaceconstant{nright}{ndestra}
\setinterfaceconstant{ntop}{ncima}
@@ -998,6 +1005,7 @@
\setinterfaceconstant{numberset}{numberset}
\setinterfaceconstant{numberstarter}{numberstarter}
\setinterfaceconstant{numberstopper}{numberstopper}
+\setinterfaceconstant{numberstrut}{numberstrut}
\setinterfaceconstant{numberstyle}{stilenumero}
\setinterfaceconstant{numberwidth}{numberwidth}
\setinterfaceconstant{nx}{nx}
@@ -1109,6 +1117,7 @@
\setinterfaceconstant{rightoffset}{offsetdestro}
\setinterfaceconstant{rightquotation}{citazionedestra}
\setinterfaceconstant{rightquote}{menzionedestra}
+\setinterfaceconstant{rightsample}{rightsample}
\setinterfaceconstant{rightsentence}{frasedestra}
\setinterfaceconstant{rightspeech}{rightspeech}
\setinterfaceconstant{rightstyle}{stiledestra}
@@ -1165,7 +1174,9 @@
\setinterfaceconstant{source}{origine}
\setinterfaceconstant{space}{spazio}
\setinterfaceconstant{spaceafter}{spaziodopo}
+\setinterfaceconstant{spaceafterside}{spaceafterside}
\setinterfaceconstant{spacebefore}{spazioprima}
+\setinterfaceconstant{spacebeforeside}{spacebeforeside}
\setinterfaceconstant{spaceinbetween}{spaceinbetween}
\setinterfaceconstant{spacing}{spaziatura}
\setinterfaceconstant{specification}{specification}
@@ -1230,6 +1241,7 @@
\setinterfaceconstant{titledistance}{distanzatitolo}
\setinterfaceconstant{titleleft}{titleleft}
\setinterfaceconstant{titleright}{titleright}
+\setinterfaceconstant{titlestrut}{titlestrut}
\setinterfaceconstant{titlestyle}{stiletitolo}
\setinterfaceconstant{to}{verso}
\setinterfaceconstant{toffset}{toffset}
diff --git a/tex/context/base/mkii/mult-pe.mkii b/tex/context/base/mkii/mult-pe.mkii
index 8ac3113cf..02007f158 100644
--- a/tex/context/base/mkii/mult-pe.mkii
+++ b/tex/context/base/mkii/mult-pe.mkii
@@ -621,6 +621,10 @@
\setinterfaceconstant{align}{تنظیم}
\setinterfaceconstant{aligncharacter}{حرف‌تنظیم}
\setinterfaceconstant{alignmentcharacter}{حرف‌تنظیم‌کردن}
+\setinterfaceconstant{alignmentleftsample}{alignmentleftsample}
+\setinterfaceconstant{alignmentleftwidth}{alignmentleftwidth}
+\setinterfaceconstant{alignmentrightsample}{alignmentrightsample}
+\setinterfaceconstant{alignmentrightwidth}{alignmentrightwidth}
\setinterfaceconstant{alignsymbol}{alignsymbol}
\setinterfaceconstant{aligntitle}{عنوان‌تنظیم}
\setinterfaceconstant{alternative}{جایگزین}
@@ -907,6 +911,7 @@
\setinterfaceconstant{leftoffset}{آفست‌چپ}
\setinterfaceconstant{leftquotation}{نقل‌قول‌چپ}
\setinterfaceconstant{leftquote}{نقل‌چپ}
+\setinterfaceconstant{leftsample}{leftsample}
\setinterfaceconstant{leftsentence}{جمله‌چپ}
\setinterfaceconstant{leftspeech}{سخنرانی‌چپ}
\setinterfaceconstant{leftstyle}{سبک‌چپ}
@@ -979,6 +984,7 @@
\setinterfaceconstant{nlines}{nlines}
\setinterfaceconstant{norm}{norm}
\setinterfaceconstant{note}{note}
+\setinterfaceconstant{notes}{notes}
\setinterfaceconstant{nr}{nr}
\setinterfaceconstant{nright}{nright}
\setinterfaceconstant{ntop}{ntop}
@@ -1109,6 +1115,7 @@
\setinterfaceconstant{rightoffset}{آفست‌راست}
\setinterfaceconstant{rightquotation}{نقل‌قول‌راست}
\setinterfaceconstant{rightquote}{نقل‌راست}
+\setinterfaceconstant{rightsample}{rightsample}
\setinterfaceconstant{rightsentence}{جمله‌راست}
\setinterfaceconstant{rightspeech}{سخنرانی‌راست}
\setinterfaceconstant{rightstyle}{سبک‌راست}
@@ -1165,7 +1172,9 @@
\setinterfaceconstant{source}{منبع}
\setinterfaceconstant{space}{فضا}
\setinterfaceconstant{spaceafter}{فضا‌بعداز}
+\setinterfaceconstant{spaceafterside}{spaceafterside}
\setinterfaceconstant{spacebefore}{فضا‌قبل‌از}
+\setinterfaceconstant{spacebeforeside}{spacebeforeside}
\setinterfaceconstant{spaceinbetween}{فضا‌دربین}
\setinterfaceconstant{spacing}{فضاگذاری}
\setinterfaceconstant{specification}{specification}
diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii
index cb9781e80..7862b2d30 100644
--- a/tex/context/base/mkii/mult-ro.mkii
+++ b/tex/context/base/mkii/mult-ro.mkii
@@ -376,6 +376,7 @@
\setinterfacevariable{norepeat}{norepeat}
\setinterfacevariable{normal}{normal}
\setinterfacevariable{nospacing}{nospacing}
+\setinterfacevariable{nostopper}{nostopper}
\setinterfacevariable{not}{nu}
\setinterfacevariable{notation}{notation}
\setinterfacevariable{note}{note}
@@ -621,6 +622,10 @@
\setinterfaceconstant{align}{aliniere}
\setinterfaceconstant{aligncharacter}{aliniazacaracter}
\setinterfaceconstant{alignmentcharacter}{alierecaracter}
+\setinterfaceconstant{alignmentleftsample}{alignmentleftsample}
+\setinterfaceconstant{alignmentleftwidth}{alignmentleftwidth}
+\setinterfaceconstant{alignmentrightsample}{alignmentrightsample}
+\setinterfaceconstant{alignmentrightwidth}{alignmentrightwidth}
\setinterfaceconstant{alignsymbol}{alignsymbol}
\setinterfaceconstant{aligntitle}{alinieretitlu}
\setinterfaceconstant{alternative}{alternativ}
@@ -907,6 +912,7 @@
\setinterfaceconstant{leftoffset}{offsetstanga}
\setinterfaceconstant{leftquotation}{citatstanga}
\setinterfaceconstant{leftquote}{minicitatstanga}
+\setinterfaceconstant{leftsample}{leftsample}
\setinterfaceconstant{leftsentence}{propozitiestanga}
\setinterfaceconstant{leftspeech}{leftspeech}
\setinterfaceconstant{leftstyle}{stilstanga}
@@ -979,6 +985,7 @@
\setinterfaceconstant{nlines}{nlinii}
\setinterfaceconstant{norm}{norm}
\setinterfaceconstant{note}{note}
+\setinterfaceconstant{notes}{notes}
\setinterfaceconstant{nr}{nr}
\setinterfaceconstant{nright}{ndreapta}
\setinterfaceconstant{ntop}{nsus}
@@ -998,6 +1005,7 @@
\setinterfaceconstant{numberset}{numberset}
\setinterfaceconstant{numberstarter}{numberstarter}
\setinterfaceconstant{numberstopper}{numberstopper}
+\setinterfaceconstant{numberstrut}{numberstrut}
\setinterfaceconstant{numberstyle}{stilnumar}
\setinterfaceconstant{numberwidth}{numberwidth}
\setinterfaceconstant{nx}{nx}
@@ -1109,6 +1117,7 @@
\setinterfaceconstant{rightoffset}{offsetdreapta}
\setinterfaceconstant{rightquotation}{citatdreapta}
\setinterfaceconstant{rightquote}{minicitatdreapta}
+\setinterfaceconstant{rightsample}{rightsample}
\setinterfaceconstant{rightsentence}{propozitiedreapta}
\setinterfaceconstant{rightspeech}{rightspeech}
\setinterfaceconstant{rightstyle}{stildreapta}
@@ -1165,7 +1174,9 @@
\setinterfaceconstant{source}{sursa}
\setinterfaceconstant{space}{spatiu}
\setinterfaceconstant{spaceafter}{spatiudupa}
+\setinterfaceconstant{spaceafterside}{spaceafterside}
\setinterfaceconstant{spacebefore}{spatiuinainte}
+\setinterfaceconstant{spacebeforeside}{spacebeforeside}
\setinterfaceconstant{spaceinbetween}{spaceinbetween}
\setinterfaceconstant{spacing}{spatiere}
\setinterfaceconstant{specification}{specification}
@@ -1230,6 +1241,7 @@
\setinterfaceconstant{titledistance}{distantatitlu}
\setinterfaceconstant{titleleft}{titleleft}
\setinterfaceconstant{titleright}{titleright}
+\setinterfaceconstant{titlestrut}{titlestrut}
\setinterfaceconstant{titlestyle}{stiltitlu}
\setinterfaceconstant{to}{catre}
\setinterfaceconstant{toffset}{toffset}
diff --git a/tex/context/base/mkiv/buff-imp-parsed-xml.lua b/tex/context/base/mkiv/buff-imp-parsed-xml.lua
index b18fb65aa..b098a4989 100644
--- a/tex/context/base/mkiv/buff-imp-parsed-xml.lua
+++ b/tex/context/base/mkiv/buff-imp-parsed-xml.lua
@@ -6,6 +6,7 @@ if not modules then modules = { } end modules ['buff-imp-parsed-xml'] = {
license = "see context related readme files"
}
+local next = next
local format = string.format
local context = context
diff --git a/tex/context/base/mkiv/char-def.lua b/tex/context/base/mkiv/char-def.lua
index 58e1f2c44..d501d73b6 100644
--- a/tex/context/base/mkiv/char-def.lua
+++ b/tex/context/base/mkiv/char-def.lua
@@ -475,12 +475,7 @@ characters.data={
direction="cs",
linebreak="is",
mathclass="punctuation",
- mathspec={
- {
- class="punctuation",
- name="ldotp",
- },
- },
+ mathname="ldotp",
synonyms={ "decimal point", "dot", "period" },
unicodeslot=0x2E,
},
@@ -492,14 +487,7 @@ characters.data={
description="SOLIDUS",
direction="cs",
linebreak="sy",
- mathspec={
- {
- class="middle",
- },
- {
- class="ordinary",
- },
- },
+ mathclass="middle",
synonyms={ "slash", "virgule" },
unicodeslot=0x2F,
},
diff --git a/tex/context/base/mkiv/char-ini.lua b/tex/context/base/mkiv/char-ini.lua
index 8bf35a8dd..a2bb9694c 100644
--- a/tex/context/base/mkiv/char-ini.lua
+++ b/tex/context/base/mkiv/char-ini.lua
@@ -512,7 +512,7 @@ local blocks = allocate {
["uppercaseboldfraktur"] = { first = 0x1D56C, last = 0x1D585, math = true },
["uppercasebolditalic"] = { first = 0x1D468, last = 0x1D481, math = true },
["uppercaseboldscript"] = { first = 0x1D4D0, last = 0x1D4E9, math = true },
- ["uppercasedoublestruck"] = { first = 0x1D538, last = 0x1D551, math = true },
+ ["uppercasedoublestruck"] = { first = 0x1D538, last = 0x1D551, math = true }, -- gaps are filled in elsewhere
["uppercasefraktur"] = { first = 0x1D504, last = 0x1D51D, math = true },
["uppercasegreekbold"] = { first = 0x1D6A8, last = 0x1D6C1, math = true },
["uppercasegreekbolditalic"] = { first = 0x1D71C, last = 0x1D735, math = true },
@@ -540,6 +540,52 @@ local blocks = allocate {
["zanabazarsquare"] = { first = 0x11A00, last = 0x11A4F, description = "Zanabazar Square" },
}
+-- moved from math-act.lua to here:
+
+-- operators : 0x02200
+-- symbolsa : 0x02701
+-- symbolsb : 0x02901
+-- supplemental : 0x02A00
+
+blocks.lowercaseitalic.gaps = {
+ [0x1D455] = 0x0210E, -- ℎ h
+}
+
+blocks.uppercasescript.gaps = {
+ [0x1D49D] = 0x0212C, -- ℬ script B
+ [0x1D4A0] = 0x02130, -- ℰ script E
+ [0x1D4A1] = 0x02131, -- ℱ script F
+ [0x1D4A3] = 0x0210B, -- ℋ script H
+ [0x1D4A4] = 0x02110, -- ℐ script I
+ [0x1D4A7] = 0x02112, -- ℒ script L
+ [0x1D4A8] = 0x02133, -- ℳ script M
+ [0x1D4AD] = 0x0211B, -- ℛ script R
+}
+
+blocks.lowercasescript.gaps = {
+ [0x1D4BA] = 0x0212F, -- ℯ script e
+ [0x1D4BC] = 0x0210A, -- ℊ script g
+ [0x1D4C4] = 0x02134, -- ℴ script o
+}
+
+blocks.uppercasefraktur.gaps = {
+ [0x1D506] = 0x0212D, -- ℭ fraktur C
+ [0x1D50B] = 0x0210C, -- ℌ fraktur H
+ [0x1D50C] = 0x02111, -- ℑ fraktur I
+ [0x1D515] = 0x0211C, -- ℜ fraktur R
+ [0x1D51D] = 0x02128, -- ℨ fraktur Z
+}
+
+blocks.uppercasedoublestruck.gaps = {
+ [0x1D53A] = 0x02102, -- ℂ bb C
+ [0x1D53F] = 0x0210D, -- ℍ bb H
+ [0x1D545] = 0x02115, -- ℕ bb N
+ [0x1D547] = 0x02119, -- ℙ bb P
+ [0x1D548] = 0x0211A, -- ℚ bb Q
+ [0x1D549] = 0x0211D, -- ℝ bb R
+ [0x1D551] = 0x02124, -- ℤ bb Z
+}
+
characters.blocks = blocks
function characters.blockrange(name)
diff --git a/tex/context/base/mkiv/char-tex.lua b/tex/context/base/mkiv/char-tex.lua
index 4ab906bd5..658a01b0b 100644
--- a/tex/context/base/mkiv/char-tex.lua
+++ b/tex/context/base/mkiv/char-tex.lua
@@ -622,11 +622,25 @@ if not csletters then
-- this slows down format generation by over 10 percent
for k, v in next, blocks do
if v.catcode == "letter" then
- for u=v.first,v.last do
- csletters[utfchar(u)] = u
- --
- -- texsetlccode(u,u,u) -- self self
- --
+ local first = v.first
+ local last = v.last
+ local gaps = v.gaps
+ if first and last then
+ for u=first,last do
+ csletters[utfchar(u)] = u
+ --
+ -- texsetlccode(u,u,u) -- self self
+ --
+ end
+ end
+ if gaps then
+ for i=1,#gaps do
+ local u = gaps[i]
+ csletters[utfchar(u)] = u
+ --
+ -- texsetlccode(u,u,u) -- self self
+ --
+ end
end
end
end
diff --git a/tex/context/base/mkiv/char-utf.lua b/tex/context/base/mkiv/char-utf.lua
index 0aeadcc85..8f46ae98f 100644
--- a/tex/context/base/mkiv/char-utf.lua
+++ b/tex/context/base/mkiv/char-utf.lua
@@ -22,6 +22,7 @@ over a string.</p>
educational purposes.</p>
--ldx]]--
+local next, type = next, type
local gsub, find = string.gsub, string.find
local concat, sortedhash, keys, sort = table.concat, table.sortedhash, table.keys, table.sort
local utfchar, utfbyte, utfcharacters, utfvalues = utf.char, utf.byte, utf.characters, utf.values
diff --git a/tex/context/base/mkiv/colo-icc.lua b/tex/context/base/mkiv/colo-icc.lua
index 54072fefa..06a913e17 100644
--- a/tex/context/base/mkiv/colo-icc.lua
+++ b/tex/context/base/mkiv/colo-icc.lua
@@ -9,6 +9,7 @@ if not modules then modules = { } end modules ['colo-icc'] = {
local char, byte, gsub, match, format, strip = string.char, string.byte, string.gsub, string.match, string.format, string.strip
local readstring, readnumber = io.readstring, io.readnumber
local band = bit32.band
+local next = next
local colors = attributes and attributes.colors or { } -- when used in mtxrun
diff --git a/tex/context/base/mkiv/colo-ini.mkiv b/tex/context/base/mkiv/colo-ini.mkiv
index a726a91d6..daee8ada6 100644
--- a/tex/context/base/mkiv/colo-ini.mkiv
+++ b/tex/context/base/mkiv/colo-ini.mkiv
@@ -1432,9 +1432,12 @@
\definecolor[trace:r][r=.75,t=.5,a=1]
\definecolor[trace:g][g=.75,t=.5,a=1]
\definecolor[trace:b][b=.75,t=.5,a=1]
-\definecolor[trace:c][c=.75,t=.5,a=1]
-\definecolor[trace:m][m=.75,t=.5,a=1]
-\definecolor[trace:y][y=.75,t=.5,a=1]
+%definecolor[trace:c][c=.75,t=.5,a=1]
+\definecolor[trace:c][g=.75,b=.75,t=.5,a=1]
+%definecolor[trace:m][m=.75,t=.5,a=1]
+\definecolor[trace:m][r=.75,b=.75,t=.5,a=1]
+%definecolor[trace:y][y=.75,t=.5,a=1]
+\definecolor[trace:y][r=.75,g=.75,t=.5,a=1]
\definecolor[trace:s][s=.75,t=.5,a=1]
\definecolor[trace:d][s=.25,t=.5,a=1]
\definecolor[trace:o][r=1,g=.6,b=.1,t=.5,a=1]
@@ -1443,9 +1446,12 @@
\definecolor[trace:dr][r=.75,t=.75,a=1]
\definecolor[trace:dg][g=.75,t=.75,a=1]
\definecolor[trace:db][b=.75,t=.75,a=1]
-\definecolor[trace:dc][c=.75,t=.75,a=1]
-\definecolor[trace:dm][m=.75,t=.75,a=1]
-\definecolor[trace:dy][y=.75,t=.75,a=1]
+%definecolor[trace:dc][c=.75,t=.75,a=1]
+\definecolor[trace:dc][g=.75,b=.75,t=.75,a=1]
+%definecolor[trace:dm][m=.75,t=.75,a=1]
+\definecolor[trace:dm][r=.75,b=.75,t=.75,a=1]
+%definecolor[trace:dy][y=.75,t=.75,a=1]
+\definecolor[trace:y][r=.75,g=.75,t=.75,a=1]
\definecolor[trace:ds][s=.75,t=.75,a=1]
\definecolor[trace:dd][s=.25,t=.75,a=1]
\definecolor[trace:do][r=1,g=.6,b=.1,t=.75,a=1]
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 37ce0c00b..48067eba5 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2017.11.22 13:35}
+\newcontextversion{2018.01.08 23:03}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 0b1f3b097..41eab7de7 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -41,7 +41,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2017.11.22 13:35}
+\edef\contextversion{2018.01.08 23:03}
\edef\contextkind {beta}
%D For those who want to use this:
@@ -76,8 +76,8 @@
%D We just quit if new functionality is expected.
-\ifnum\luatexversion<70 % also change message
- \writestatus{!!!!}{Your luatex binary is too old, you need at least version 0.70!}
+\ifnum\luatexversion<105 % also change message
+ \writestatus{!!!!}{Your luatex binary is too old, you need at least version 1.05!}
\expandafter\end
\fi
@@ -434,6 +434,7 @@
\loadmarkfile{typo-chr}
\loadmarkfile{typo-rub}
\loadmkivfile{typo-fkr}
+\loadmkivfile{typo-pnc}
\loadmkvifile{type-ini}
\loadmarkfile{type-set}
@@ -521,6 +522,8 @@
\loadmarkfile{page-app}
\loadmarkfile{meta-fig}
+\loadmarkfile{page-ffl}
+
\loadmarkfile{lang-spa} % will become obsolete
\loadmarkfile{typo-ovl} % fuzzy project (tracing) code
diff --git a/tex/context/base/mkiv/core-two.lua b/tex/context/base/mkiv/core-two.lua
index bb1afa7db..5192677b2 100644
--- a/tex/context/base/mkiv/core-two.lua
+++ b/tex/context/base/mkiv/core-two.lua
@@ -6,6 +6,7 @@ if not modules then modules = { } end modules ['core-two'] = {
license = "see context related readme files"
}
+local next = next
local remove, concat = table.remove, table.concat
local allocate = utilities.storage.allocate
diff --git a/tex/context/base/mkiv/data-env.lua b/tex/context/base/mkiv/data-env.lua
index 8bb25036d..1b31caab6 100644
--- a/tex/context/base/mkiv/data-env.lua
+++ b/tex/context/base/mkiv/data-env.lua
@@ -7,6 +7,7 @@ if not modules then modules = { } end modules ['data-env'] = {
}
local lower, gsub = string.lower, string.gsub
+local next = next
local resolvers = resolvers
diff --git a/tex/context/base/mkiv/data-tmp.lua b/tex/context/base/mkiv/data-tmp.lua
index e1903fd82..948827161 100644
--- a/tex/context/base/mkiv/data-tmp.lua
+++ b/tex/context/base/mkiv/data-tmp.lua
@@ -28,6 +28,7 @@ local concat = table.concat
local mkdirs, isdir, isfile = dir.mkdirs, lfs.isdir, lfs.isfile
local addsuffix, is_writable, is_readable = file.addsuffix, file.is_writable, file.is_readable
local formatters = string.formatters
+local next, type = next, type
local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
local trace_cache = false trackers.register("resolvers.cache", function(v) trace_cache = v end)
diff --git a/tex/context/base/mkiv/font-agl.lua b/tex/context/base/mkiv/font-agl.lua
index aec6415f7..49b85421f 100644
--- a/tex/context/base/mkiv/font-agl.lua
+++ b/tex/context/base/mkiv/font-agl.lua
@@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['font-agl'] = {
original = "Adobe Glyph List, version 2.0, September 20, 2002",
}
+local next = next
+
local allocate = utilities.storage.allocate
local mark = utilities.storage.mark
diff --git a/tex/context/base/mkiv/font-aux.lua b/tex/context/base/mkiv/font-aux.lua
index fc6c90bc1..fcbcd6d32 100644
--- a/tex/context/base/mkiv/font-aux.lua
+++ b/tex/context/base/mkiv/font-aux.lua
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['font-aux'] = {
license = "see context related readme files"
}
-local tonumber, type = tonumber, type
+local tonumber, type, next = tonumber, type, next
----- wrap, yield = coroutine.wrap, coroutine.yield
local fonts, font = fonts, font
diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua
index 2dce9b6e4..f4fe474c3 100644
--- a/tex/context/base/mkiv/font-con.lua
+++ b/tex/context/base/mkiv/font-con.lua
@@ -15,6 +15,7 @@ local sortedkeys, sortedhash, serialize, fastcopy = table.sortedkeys, table.sort
local derivetable = table.derive
local ioflush = io.flush
local round = math.round
+local setmetatable, getmetatable, rawget, rawset = setmetatable, getmetatable, rawget, rawset
local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
local trace_scaling = false trackers.register("fonts.scaling", function(v) trace_scaling = v end)
@@ -230,27 +231,87 @@ function constructors.trytosharefont(target,tfmdata)
end
end
+-- function constructors.enhanceparameters(parameters)
+-- local xheight = parameters.x_height
+-- local quad = parameters.quad
+-- local space = parameters.space
+-- local stretch = parameters.space_stretch
+-- local shrink = parameters.space_shrink
+-- local extra = parameters.extra_space
+-- local slant = parameters.slant
+-- -- synonyms
+-- parameters.xheight = xheight
+-- parameters.spacestretch = stretch
+-- parameters.spaceshrink = shrink
+-- parameters.extraspace = extra
+-- parameters.em = quad
+-- parameters.ex = xheight
+-- parameters.slantperpoint = slant
+-- parameters.spacing = {
+-- width = space,
+-- stretch = stretch,
+-- shrink = shrink,
+-- extra = extra,
+-- }
+-- end
+
+local synonyms = {
+ exheight = "x_height",
+ xheight = "x_height",
+ ex = "x_height",
+ emwidth = "quad",
+ em = "quad",
+ spacestretch = "space_stretch",
+ stretch = "space_stretch",
+ spaceshrink = "space_shrink",
+ shrink = "space_shrink",
+ extraspace = "extra_space",
+ xspace = "extra_space",
+ slantperpoint = "slant",
+}
+
function constructors.enhanceparameters(parameters)
- local xheight = parameters.x_height
- local quad = parameters.quad
- local space = parameters.space
- local stretch = parameters.space_stretch
- local shrink = parameters.space_shrink
- local extra = parameters.extra_space
- local slant = parameters.slant
- parameters.xheight = xheight
- parameters.spacestretch = stretch
- parameters.spaceshrink = shrink
- parameters.extraspace = extra
- parameters.em = quad
- parameters.ex = xheight
- parameters.slantperpoint = slant
- parameters.spacing = {
- width = space,
- stretch = stretch,
- shrink = shrink,
- extra = extra,
- }
+ local mt = getmetatable(parameters)
+ local getter = function(t,k)
+ if not k then
+ return nil
+ end
+ local s = synonyms[k]
+ if s then
+ return rawget(t,s) or (mt and mt[s]) or nil
+ end
+ if k == "spacing" then
+ return {
+ width = t.space,
+ stretch = t.space_stretch,
+ shrink = t.space_shrink,
+ extra = t.extra_space,
+ }
+ end
+ return mt and mt[k] or nil
+ end
+ local setter = function(t,k,v)
+ if not k then
+ return 0
+ end
+ local s = synonyms[k]
+ if s then
+ rawset(t,s,v)
+ elseif k == "spacing" then
+ if type(v) == "table" then
+ rawset(t,"space",v.width or 0)
+ rawset(t,"space_stretch",v.stretch or 0)
+ rawset(t,"space_shrink",v.shrink or 0)
+ rawset(t,"extra_space",v.extra or 0)
+ end
+ else
+ rawset(t,k,v)
+ end
+ end
+ setmetatable(parameters, {
+ __index = getter,
+ __newindex = setter,
+ })
end
local function mathkerns(v,vdelta)
@@ -493,7 +554,7 @@ function constructors.scale(tfmdata,specification)
targetparameters.descender = delta * descender
end
--
- constructors.enhanceparameters(targetparameters) -- official copies for us
+ constructors.enhanceparameters(targetparameters) -- official copies for us, now virtual
--
local protrusionfactor = (targetquad ~= 0 and 1000/targetquad) or 0
local scaledwidth = defaultwidth * hdelta
diff --git a/tex/context/base/mkiv/font-ext.lua b/tex/context/base/mkiv/font-ext.lua
index 0fa3f7279..833c9cdea 100644
--- a/tex/context/base/mkiv/font-ext.lua
+++ b/tex/context/base/mkiv/font-ext.lua
@@ -977,6 +977,58 @@ registerotffeature {
--
-- end
+do
+
+ local P, lpegpatterns, lpegmatch = lpeg.P, lpeg.patterns, lpeg.match
+
+ local amount, stretch, shrink, extra
+
+ local factor = lpegpatterns.unsigned
+ local space = lpegpatterns.space
+ local pattern = (
+ (factor / function(n) amount = tonumber(n) or amount end)
+ + (P("+") + P("plus" )) * space^0 * (factor / function(n) stretch = tonumber(n) or stretch end)
+ + (P("-") + P("minus")) * space^0 * (factor / function(n) shrink = tonumber(n) or shrink end)
+ + ( P("extra")) * space^0 * (factor / function(n) extra = tonumber(n) or extra end)
+ + space^1
+ )^1
+
+ local function initialize(tfmdata,key,value)
+ local characters = tfmdata.characters
+ local parameters = tfmdata.parameters
+ if type(value) == "string" then
+ local emwidth = parameters.quad
+ amount, stretch, shrink, extra = 0, 0, 0, false
+ lpegmatch(pattern,value)
+ if not extra then
+ if shrink ~= 0 then
+ extra = shrink
+ elseif stretch ~= 0 then
+ extra = stretch
+ else
+ extra = amount
+ end
+ end
+ parameters.space = amount * emwidth
+ parameters.space_stretch = stretch * emwidth
+ parameters.space_shrink = shrink * emwidth
+ parameters.extra_space = extra * emwidth
+ end
+ end
+
+ -- 1.1 + 1.2 - 1.3 minus 1.4 plus 1.1 extra 1.4 -- last one wins
+
+ registerotffeature {
+ name = "spacing",
+ description = "space settings",
+ manipulators = {
+ base = initialize,
+ node = initialize,
+ }
+ }
+
+end
+
-- -- historic stuff, move from font-ota (handled differently, typo-rep)
--
-- local delete_node = nodes.delete
diff --git a/tex/context/base/mkiv/font-fbk.lua b/tex/context/base/mkiv/font-fbk.lua
index 8c706e9f6..79ebc3f25 100644
--- a/tex/context/base/mkiv/font-fbk.lua
+++ b/tex/context/base/mkiv/font-fbk.lua
@@ -8,6 +8,7 @@ if not modules then modules = { } end modules ['font-fbk'] = {
local cos, tan, rad, format = math.cos, math.tan, math.rad, string.format
local utfbyte, utfchar = utf.byte, utf.char
+local next = next
--[[ldx--
<p>This is very experimental code!</p>
diff --git a/tex/context/base/mkiv/font-gbn.lua b/tex/context/base/mkiv/font-gbn.lua
index 6742f90fb..3256a1649 100644
--- a/tex/context/base/mkiv/font-gbn.lua
+++ b/tex/context/base/mkiv/font-gbn.lua
@@ -13,6 +13,8 @@ if context then
os.exit()
end
+local next = next
+
local fonts = fonts
local nodes = nodes
diff --git a/tex/context/base/mkiv/font-ini.mkvi b/tex/context/base/mkiv/font-ini.mkvi
index c4445b7b9..91459d18e 100644
--- a/tex/context/base/mkiv/font-ini.mkvi
+++ b/tex/context/base/mkiv/font-ini.mkvi
@@ -919,6 +919,8 @@
\newif\ifskipfontcharacteristics \skipfontcharacteristicstrue
+\tracingfonts\plussix % <id: name @ size>
+
%D When fontclasses are used, we define the font global, since namespaces are
%D used. Otherwise we parse the specs each time.
diff --git a/tex/context/base/mkiv/font-lig.lua b/tex/context/base/mkiv/font-lig.lua
index bb9ee0096..1aed9fc5b 100644
--- a/tex/context/base/mkiv/font-lig.lua
+++ b/tex/context/base/mkiv/font-lig.lua
@@ -9,6 +9,8 @@ if not modules then modules = { } end modules ['font-lig'] = {
-- This module is not loaded but generated a file for plain TeX as a substitute
-- for collapsing the input: "luatex-fonts-lig.lua" with "collapse=yes".
+local next = next
+
local standalone = not characters
if standalone then
diff --git a/tex/context/base/mkiv/font-ocl.lua b/tex/context/base/mkiv/font-ocl.lua
index 872247d43..b17cf991d 100644
--- a/tex/context/base/mkiv/font-ocl.lua
+++ b/tex/context/base/mkiv/font-ocl.lua
@@ -101,12 +101,11 @@ else -- for generic
end
--- We need to force page first because otherwise the q's get outside
--- the font switch and as a consequence the next character has no font
--- set (well, it has: the preceding one). As a consequence these fonts
--- are somewhat inefficient as each glyph gets the font set. It's a
--- side effect of the fact that a font is handled when a character gets
--- flushed.
+-- We need to force page first because otherwise the q's get outside the font switch and
+-- as a consequence the next character has no font set (well, it has: the preceding one). As
+-- a consequence these fonts are somewhat inefficient as each glyph gets the font set. It's
+-- a side effect of the fact that a font is handled when a character gets flushed. Okay, from
+-- now on we can use text as literal mode.
local function convert(t,k)
local v = { }
@@ -123,8 +122,104 @@ local function convert(t,k)
return v
end
-local start = { "pdf", "page", "q" }
-local stop = { "pdf", "raw", "Q" }
+local start = { "pdf", "mode", "font" } -- force text mode (so get q Q right)
+----- stop = { "pdf", "mode", "page" } -- force page mode (else overlap)
+local push = { "pdf", "page", "q" }
+local pop = { "pdf", "page", "Q" }
+
+if not LUATEXFUNCTIONALITY or LUATEXFUNCTIONALITY < 6472 then
+ start = { "nop" }
+ ----- = stop
+end
+
+-- -- This one results in color directives inside BT ET but has less q Q pairs. It
+-- -- only shows the first glyph in acrobat and nothing more. No problem with other
+-- -- renderers.
+--
+-- local function initializecolr(tfmdata,kind,value) -- hm, always value
+-- if value then
+-- local resources = tfmdata.resources
+-- local palettes = resources.colorpalettes
+-- if palettes then
+-- --
+-- local converted = resources.converted
+-- if not converted then
+-- converted = setmetatableindex(convert)
+-- resources.converted = converted
+-- end
+-- local colorvalues = sharedpalettes[value] or converted[palettes[tonumber(value) or 1] or palettes[1]] or { }
+-- local classes = #colorvalues
+-- if classes == 0 then
+-- return
+-- end
+-- --
+-- local characters = tfmdata.characters
+-- local descriptions = tfmdata.descriptions
+-- local properties = tfmdata.properties
+-- --
+-- properties.virtualized = true
+-- tfmdata.fonts = {
+-- { id = 0 }
+-- }
+-- local widths = setmetatableindex(function(t,k)
+-- local v = { "right", -k }
+-- t[k] = v
+-- return v
+-- end)
+-- --
+-- local getactualtext = otf.getactualtext
+-- local default = colorvalues[#colorvalues]
+-- local b, e = getactualtext(tounicode(0xFFFD))
+-- local actualb = { "pdf", "page", b } -- saves tables
+-- local actuale = { "pdf", "page", e } -- saves tables
+-- --
+-- local cache = setmetatableindex(function(t,k)
+-- local v = { "char", k } -- could he a weak shared hash
+-- t[k] = v
+-- return v
+-- end)
+-- --
+-- for unicode, character in next, characters do
+-- local description = descriptions[unicode]
+-- if description then
+-- local colorlist = description.colors
+-- if colorlist then
+-- local u = description.unicode or characters[unicode].unicode
+-- local w = character.width or 0
+-- local s = #colorlist
+-- local goback = w ~= 0 and widths[w] or nil -- needs checking: are widths the same
+-- local t = {
+-- start,
+-- not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) }
+-- }
+-- local n = 2
+-- local l = nil
+-- n = n + 1 t[n] = push
+-- for i=1,s do
+-- local entry = colorlist[i]
+-- local v = colorvalues[entry.class] or default
+-- if v and l ~= v then
+-- n = n + 1 t[n] = v
+-- l = v
+-- end
+-- n = n + 1 t[n] = cache[entry.slot]
+-- if s > 1 and i < s and goback then
+-- n = n + 1 t[n] = goback
+-- end
+-- end
+-- n = n + 1 t[n] = pop
+-- n = n + 1 t[n] = actuale
+-- n = n + 1 t[n] = stop
+-- character.commands = t
+-- end
+-- end
+-- end
+-- end
+-- end
+-- end
+--
+-- -- Here we have no color change in BT .. ET and more q Q pairs but even then acrobat
+-- -- fails displaying the overlays correctly. Other renderers do it right.
local function initializecolr(tfmdata,kind,value) -- hm, always value
if value then
@@ -179,15 +274,21 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value
local s = #colorlist
local goback = w ~= 0 and widths[w] or nil -- needs checking: are widths the same
local t = {
- start,
- not u and actualb or { "pdf", "raw", getactualtext(tounicode(u)) }
+ start, -- really needed
+ not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) }
}
local n = 2
local l = nil
+ local f = false
for i=1,s do
local entry = colorlist[i]
local v = colorvalues[entry.class] or default
if v and l ~= v then
+ if f then
+ n = n + 1 t[n] = pop
+ end
+ n = n + 1 t[n] = push
+ f = true
n = n + 1 t[n] = v
l = v
end
@@ -196,8 +297,11 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value
n = n + 1 t[n] = goback
end
end
+ if f then
+ n = n + 1 t[n] = pop
+ end
n = n + 1 t[n] = actuale
- n = n + 1 t[n] = stop
+ -- n = n + 1 t[n] = stop -- not needed
character.commands = t
end
end
@@ -302,7 +406,9 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = sbix|svg
local getactualtext = otf.getactualtext
local storepdfdata = otf.storepdfdata
--
- -- local nop = { "nop" }
+ local b, e = getactualtext(tounicode(0xFFFD))
+ local actualb = { "pdf", "page", b } -- saves tables
+ local actuale = { "pdf", "page", e } -- saves tables
--
for unicode, character in sortedhash(characters) do -- sort is nicer for svg
local index = character.index
@@ -324,18 +430,18 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = sbix|svg
if data then
local setcode, name, nilcode = storepdfdata(data)
if name then
- local bt, et = getactualtext(unicode)
+ local bt = unicode and getactualtext(unicode)
local wd = character.width or 0
local ht = character.height or 0
local dp = character.depth or 0
character.commands = {
- { "pdf", "direct", bt },
+ not unicode and actualb or { "pdf", "page", (getactualtext(unicode)) },
{ "down", dp + dy * hfactor },
{ "right", dx * hfactor },
-- setcode and { "lua", setcode } or nop,
{ "image", { filename = name, width = wd, height = ht, depth = dp } },
-- nilcode and { "lua", nilcode } or nop,
- { "pdf", "direct", et },
+ actuale,
}
character[kind] = true
end
diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua
index 246681d17..75b99e999 100644
--- a/tex/context/base/mkiv/font-ots.lua
+++ b/tex/context/base/mkiv/font-ots.lua
@@ -146,7 +146,7 @@ local trace_plugins = false registertracker("otf.plugins", function
local trace_chains = false registertracker("otf.chains", function(v) trace_chains = v end)
local trace_kernruns = false registertracker("otf.kernruns", function(v) trace_kernruns = v end)
-local trace_discruns = false registertracker("otf.discruns", function(v) trace_discruns = v end)
+----- trace_discruns = false registertracker("otf.discruns", function(v) trace_discruns = v end)
local trace_compruns = false registertracker("otf.compruns", function(v) trace_compruns = v end)
local trace_testruns = false registertracker("otf.testruns", function(v) trace_testruns = v end)
@@ -2748,8 +2748,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
end
else
notmatchreplace[current] = true
- -- different than others, needs checking if "not" is okay so for Kai to check
- if not notmatchpre[current] then
+ if notmatchpre[current] then
goto next
else
break
@@ -3623,9 +3622,14 @@ local function txtdirstate(start,stack,top,rlparmode)
top = top + 1
stack[top] = dir
elseif dir == "-TRT" or dir == "-TLT" then
- top = top - 1
- if stack[top] == "+TRT" then
- new = -1
+ if top == 1 then
+ top = 0
+ new = rlparmode
+ else
+ top = top - 1
+ if stack[top] == "+TRT" then
+ new = -1
+ end
end
else
new = rlparmode
diff --git a/tex/context/base/mkiv/font-pre.mkiv b/tex/context/base/mkiv/font-pre.mkiv
index c8550d815..d09d871f0 100644
--- a/tex/context/base/mkiv/font-pre.mkiv
+++ b/tex/context/base/mkiv/font-pre.mkiv
@@ -153,7 +153,7 @@
[mode=node,analyze=yes,language=dflt,ccmp=yes,
autoscript=position,autolanguage=position,
init=yes,medi=yes,fina=yes,isol=yes,
-% fin2=yes,fin3=yes,med2=yes,
+ % fin2=yes,fin3=yes,med2=yes,
mark=yes,mkmk=yes,kern=yes,curs=yes,
liga=yes,dlig=yes,rlig=yes,clig=yes,calt=yes]
@@ -162,7 +162,7 @@
[mode=node,analyze=yes,language=dflt,ccmp=yes,
autoscript=position,autolanguage=position,
init=yes,medi=yes,fina=yes,isol=yes,
-% fin2=yes,fin3=yes,med2=yes,
+ % fin2=yes,fin3=yes,med2=yes,
mark=yes,mkmk=yes,kern=yes,curs=yes,
rlig=yes,calt=yes]
diff --git a/tex/context/base/mkiv/font-sel.lua b/tex/context/base/mkiv/font-sel.lua
index b4dd9a555..0cf51cad3 100644
--- a/tex/context/base/mkiv/font-sel.lua
+++ b/tex/context/base/mkiv/font-sel.lua
@@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['font-sel'] = {
license = "GNU General Public License"
}
+local next, type = next, type
+
local context = context
local cleanname = fonts.names.cleanname
local gsub, splitup, find, lower = string.gsub, string.splitup, string.find, string.lower
diff --git a/tex/context/base/mkiv/font-shp.lua b/tex/context/base/mkiv/font-shp.lua
index 918304a0b..75a12ac82 100644
--- a/tex/context/base/mkiv/font-shp.lua
+++ b/tex/context/base/mkiv/font-shp.lua
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['font-shp'] = {
license = "see context related readme files"
}
-local tonumber = tonumber
+local tonumber, next = tonumber, next
local concat = table.concat
local formatters = string.formatters
diff --git a/tex/context/base/mkiv/font-tra.mkiv b/tex/context/base/mkiv/font-tra.mkiv
index 6ff2b1bfb..1f50c4a45 100644
--- a/tex/context/base/mkiv/font-tra.mkiv
+++ b/tex/context/base/mkiv/font-tra.mkiv
@@ -346,8 +346,12 @@
\unexpanded\def\startotfcompositionlist#1#2#3\stopotfcompositionlist
{\begingroup
\unexpanded\def\showotfcompositionsample##1%
- {\NC\type{##1}\NC\showotfcompositionlist{#1}{#2}{##1}\NC\definedfont[#1]##1\NC\NR}%
- \starttabulate[||||]
+ {\NC\type{##1}%
+ \NC\showotfcompositionlist{Mono}{#2}{##1}%
+ \NC\showotfcompositionlist{#1}{#2}{##1}%
+ \NC\definedfont[#1]##1%
+ \NC\NR}%
+ \starttabulate[|||||]%
#3%
\stoptabulate
\endgroup}
diff --git a/tex/context/base/mkiv/grph-fig.mkiv b/tex/context/base/mkiv/grph-fig.mkiv
index 1fdc0caa0..3bf3248a6 100644
--- a/tex/context/base/mkiv/grph-fig.mkiv
+++ b/tex/context/base/mkiv/grph-fig.mkiv
@@ -67,7 +67,6 @@
\def\grph_buffers_run_indeed[#1][#2]%
{\xdef\lasttypesetbuffer{\clf_runbuffer{#1}{#2}}}
-
% For manuals and such:
%
% \definetypesetting [name] [options] [settings-a]
@@ -99,11 +98,13 @@
\grph_typesetting_process_indeed{}{#2}{#1}{}%
\fi\fi\fi}
+\defineexternalfigure[typesetting] % so one can set a frame and such
+
\def\grph_typesetting_process_indeed#1#2#3#4% options settings-a filename settings-b
{\begingroup
\edef\m_typesetting_name{\clf_runcontextjob{#3}{#1}}%
\ifx\m_typesetting_name\empty \else
- \expanded{\externalfigure[\m_typesetting_name]}[#2,#4]%
+ \expanded{\externalfigure[\m_typesetting_name][typesetting]}[#2,#4]%
\fi
\endgroup}
diff --git a/tex/context/base/mkiv/grph-inc.lua b/tex/context/base/mkiv/grph-inc.lua
index 8df33f73c..5f403ebc7 100644
--- a/tex/context/base/mkiv/grph-inc.lua
+++ b/tex/context/base/mkiv/grph-inc.lua
@@ -40,7 +40,7 @@ run TeX code from within Lua. Some more functionality will move to Lua.
-- todo: store loaded pages per pdf file someplace
-local tonumber, tostring = tonumber, tostring
+local tonumber, tostring, next = tonumber, tostring, next
local format, lower, find, match, gsub = string.format, string.lower, string.find, string.match, string.gsub
local longtostring = string.longtostring
local contains = table.contains
@@ -558,10 +558,12 @@ function figures.initialize(request)
-- can be determined; at some point the handlers might set them to numbers instead
local w = tonumber(request.width) or 0
local h = tonumber(request.height) or 0
+ local p = tonumber(request.page) or 0
request.width = w > 0 and w or nil
request.height = h > 0 and h or nil
--
- request.page = max(tonumber(request.page) or 1,1)
+ request.page = p > 0 and p or 1
+ request.keepopen = p > 0
request.size = checkimagesize(request.size)
request.object = request.object == v_yes
request["repeat"] = request["repeat"] == v_yes
@@ -1278,7 +1280,7 @@ function figures.done(data)
ds.yscale = 1
end
-- sort of redundant but can be limited
- ds.page = ds.page or du.page or dr.page
+ ds.page = ds.page or du.page or dr.page
return data
end
@@ -1395,19 +1397,22 @@ function checkers.generic(data)
filename = name,
page = page,
pagebox = dr.size,
+ keepopen = dr.keepopen or false,
-- visiblefilename = "", -- this prohibits the full filename ending up in the file
}
codeinjections.setfigurecolorspace(data,figure)
codeinjections.setfiguremask(data,figure)
if figure then
-if page and page > 1 then
- local f = scanimage{ filename = name }
- if f.page and f.pages < page then
- report_inclusion("no page %i in %a, using page 1",page,name)
- page = 1
- figure.page = page
- end
-end
+ -- new, bonus check
+ if page and page > 1 then
+ local f = scanimage{ filename = name }
+ if f.page and f.pages < page then
+ report_inclusion("no page %i in %a, using page 1",page,name)
+ page = 1
+ figure.page = page
+ end
+ end
+ -- till here
local f, comment = checkimage(scanimage(figure))
if not f then
ds.comment = comment
diff --git a/tex/context/base/mkiv/grph-rul.lua b/tex/context/base/mkiv/grph-rul.lua
index 1a1bf091f..03f678973 100644
--- a/tex/context/base/mkiv/grph-rul.lua
+++ b/tex/context/base/mkiv/grph-rul.lua
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['grph-rul'] = {
license = "see context related readme files"
}
-local tonumber = tonumber
+local tonumber, next, type = tonumber, next, type
local attributes = attributes
local nodes = nodes
diff --git a/tex/context/base/mkiv/l-lua.lua b/tex/context/base/mkiv/l-lua.lua
index 02e139eb1..0bbe958a4 100644
--- a/tex/context/base/mkiv/l-lua.lua
+++ b/tex/context/base/mkiv/l-lua.lua
@@ -17,6 +17,8 @@ if not modules then modules = { } end modules ['l-lua'] = {
-- utf.*
-- bit32
+local next, type, tonumber = next, type, tonumber
+
-- compatibility hacks and helpers
LUAMAJORVERSION, LUAMINORVERSION = string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
diff --git a/tex/context/base/mkiv/l-unicode.lua b/tex/context/base/mkiv/l-unicode.lua
index a470fe1ff..60a8cc006 100644
--- a/tex/context/base/mkiv/l-unicode.lua
+++ b/tex/context/base/mkiv/l-unicode.lua
@@ -18,6 +18,9 @@ if not modules then modules = { } end modules ['l-unicode'] = {
-- todo: utf.sub replacement (used in syst-aux)
-- we put these in the utf namespace:
+-- used : byte char gmatch len lower sub upper
+-- not used : dump find format gfind gsub match rep reverse
+
utf = utf or (unicode and unicode.utf8) or { }
utf.characters = utf.characters or string.utfcharacters
@@ -1310,3 +1313,26 @@ function unicode.toutf32string(n)
char(extract(n,24,8))
end
end
+
+-- goodie:
+
+local len = utf.len
+local rep = rep
+
+function string.utfpadd(s,n)
+ if n and n ~= 0 then
+ local l = len(s)
+ if n > 0 then
+ local d = n - l
+ if d > 0 then
+ return rep(c or " ",d) .. s
+ end
+ else
+ local d = - n - l
+ if d > 0 then
+ return s .. rep(c or " ",d)
+ end
+ end
+ end
+ return s
+end
diff --git a/tex/context/base/mkiv/l-url.lua b/tex/context/base/mkiv/l-url.lua
index b189ec5bb..bc407a84d 100644
--- a/tex/context/base/mkiv/l-url.lua
+++ b/tex/context/base/mkiv/l-url.lua
@@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['l-url'] = {
local char, format, byte = string.char, string.format, string.byte
local concat = table.concat
-local tonumber, type = tonumber, type
+local tonumber, type, next = tonumber, type, next
local P, C, R, S, Cs, Cc, Ct, Cf, Cg, V = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.Cf, lpeg.Cg, lpeg.V
local lpegmatch, lpegpatterns, replacer = lpeg.match, lpeg.patterns, lpeg.replacer
diff --git a/tex/context/base/mkiv/lang-dis.lua b/tex/context/base/mkiv/lang-dis.lua
index ec470234f..df59359d2 100644
--- a/tex/context/base/mkiv/lang-dis.lua
+++ b/tex/context/base/mkiv/lang-dis.lua
@@ -61,158 +61,6 @@ local getlanguagedata = languages.getdata
local check_regular = true
-local expanders -- this will go away
-
--- the penalty has been determined by the mode (currently we force 1):
---
--- 0 : exhyphenpenalty
--- 1 : hyphenpenalty
--- 2 : automatichyphenpenalty
---
--- following a - : the pre and post chars are already appended and set
--- so we have pre=preex and post=postex .. however, the previous
--- hyphen is already injected ... downside: the font handler sees this
--- so this is another argument for doing a hyphenation pass in context
-
-if LUATEXVERSION < 1.005 then
-
- expanders = {
- [discretionary_code] = function(d,template)
- -- \discretionary
- return template
- end,
- [explicit_code] = function(d,template)
- -- \-
- local pre, post, replace = getdisc(d)
- local done = false
- if pre then
- local char = isglyph(pre)
- if char and char <= 0 then
- done = true
- flush_list(pre)
- pre = nil
- end
- end
- if post then
- local char = isglyph(post)
- if char and char <= 0 then
- done = true
- flush_list(post)
- post = nil
- end
- end
- if done then
- -- todo: take existing penalty
- setdisc(d,pre,post,replace,explicit_code,tex.exhyphenpenalty)
- else
- setsubtype(d,explicit_code)
- end
- return template
- end,
- [automatic_code] = function(d,template)
- local pre, post, replace = getdisc(d)
- if pre then
- -- we have a preex characters and want that one to replace the
- -- character in front which is the trigger
- if not template then
- -- can there be font kerns already?
- template = getprev(d)
- if template and getid(template) ~= glyph_code then
- template = getnext(d)
- if template and getid(template) ~= glyph_code then
- template = nil
- end
- end
- end
- if template then
- local pseudohead = getprev(template)
- if pseudohead then
- while template ~= d do
- pseudohead, template, removed = remove_node(pseudohead,template)
- -- free old replace ?
- replace = removed
- -- break ?
- end
- else
- -- can't happen
- end
- setdisc(d,pre,post,replace,automatic_code,tex.hyphenpenalty)
- else
- -- print("lone regular discretionary ignored")
- end
- else
- setdisc(d,pre,post,replace,automatic_code,tex.hyphenpenalty)
- end
- return template
- end,
- [regular_code] = function(d,template)
- if check_regular then
- -- simple
- if not template then
- -- can there be font kerns already?
- template = getprev(d)
- if template and getid(template) ~= glyph_code then
- template = getnext(d)
- if template and getid(template) ~= glyph_code then
- template = nil
- end
- end
- end
- if template then
- local language = template and getlang(template)
- local data = getlanguagedata(language)
- local prechar = data.prehyphenchar
- local postchar = data.posthyphenchar
- local pre, post, replace = getdisc(d) -- pre can be set
- local done = false
- if prechar and prechar > 0 then
- done = true
- pre = copy_node(template)
- setchar(pre,prechar)
- end
- if postchar and postchar > 0 then
- done = true
- post = copy_node(template)
- setchar(post,postchar)
- end
- if done then
- setdisc(d,pre,post,replace,regular_code,tex.hyphenpenalty)
- end
- else
- -- print("lone regular discretionary ignored")
- end
- return template
- end
- end,
- [disccodes.first] = function()
- -- forget about them
- end,
- [disccodes.second] = function()
- -- forget about them
- end,
- }
-
- function languages.expand(d,template,subtype)
- if not subtype then
- subtype = getsubtype(d)
- end
- if subtype ~= discretionary_code then
- return expanders[subtype](d,template)
- end
- end
-
-else
-
- function languages.expand()
- -- nothing to be fixed
- end
-
-end
-
-languages.expanders = expanders
-
--- -- -- -- --
-
local setlistcolor = nodes.tracers.colors.setlist
function languages.visualizediscretionaries(head)
diff --git a/tex/context/base/mkiv/lang-exp.lua b/tex/context/base/mkiv/lang-exp.lua
new file mode 100644
index 000000000..70fad48b0
--- /dev/null
+++ b/tex/context/base/mkiv/lang-exp.lua
@@ -0,0 +1,219 @@
+if not modules then modules = { } end modules ['lang-exp'] = {
+ version = 1.001,
+ comment = "companion to lang-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This module contains snippets that were used before we expanded
+-- discretionaries in the engine which makes way more sense. This
+-- code is nod used any more.
+
+if true then
+ return
+end
+
+-- lang-dis.lua:
+
+local expanders -- this will go away
+
+-- the penalty has been determined by the mode (currently we force 1):
+--
+-- 0 : exhyphenpenalty
+-- 1 : hyphenpenalty
+-- 2 : automatichyphenpenalty
+--
+-- following a - : the pre and post chars are already appended and set
+-- so we have pre=preex and post=postex .. however, the previous
+-- hyphen is already injected ... downside: the font handler sees this
+-- so this is another argument for doing a hyphenation pass in context
+
+if LUATEXVERSION < 1.005 then -- not loaded any more
+
+ expanders = {
+ [discretionary_code] = function(d,template)
+ -- \discretionary
+ return template
+ end,
+ [explicit_code] = function(d,template)
+ -- \-
+ local pre, post, replace = getdisc(d)
+ local done = false
+ if pre then
+ local char = isglyph(pre)
+ if char and char <= 0 then
+ done = true
+ flush_list(pre)
+ pre = nil
+ end
+ end
+ if post then
+ local char = isglyph(post)
+ if char and char <= 0 then
+ done = true
+ flush_list(post)
+ post = nil
+ end
+ end
+ if done then
+ -- todo: take existing penalty
+ setdisc(d,pre,post,replace,explicit_code,tex.exhyphenpenalty)
+ else
+ setsubtype(d,explicit_code)
+ end
+ return template
+ end,
+ [automatic_code] = function(d,template)
+ local pre, post, replace = getdisc(d)
+ if pre then
+ -- we have a preex characters and want that one to replace the
+ -- character in front which is the trigger
+ if not template then
+ -- can there be font kerns already?
+ template = getprev(d)
+ if template and getid(template) ~= glyph_code then
+ template = getnext(d)
+ if template and getid(template) ~= glyph_code then
+ template = nil
+ end
+ end
+ end
+ if template then
+ local pseudohead = getprev(template)
+ if pseudohead then
+ while template ~= d do
+ pseudohead, template, removed = remove_node(pseudohead,template)
+ -- free old replace ?
+ replace = removed
+ -- break ?
+ end
+ else
+ -- can't happen
+ end
+ setdisc(d,pre,post,replace,automatic_code,tex.hyphenpenalty)
+ else
+ -- print("lone regular discretionary ignored")
+ end
+ else
+ setdisc(d,pre,post,replace,automatic_code,tex.hyphenpenalty)
+ end
+ return template
+ end,
+ [regular_code] = function(d,template)
+ if check_regular then
+ -- simple
+ if not template then
+ -- can there be font kerns already?
+ template = getprev(d)
+ if template and getid(template) ~= glyph_code then
+ template = getnext(d)
+ if template and getid(template) ~= glyph_code then
+ template = nil
+ end
+ end
+ end
+ if template then
+ local language = template and getlang(template)
+ local data = getlanguagedata(language)
+ local prechar = data.prehyphenchar
+ local postchar = data.posthyphenchar
+ local pre, post, replace = getdisc(d) -- pre can be set
+ local done = false
+ if prechar and prechar > 0 then
+ done = true
+ pre = copy_node(template)
+ setchar(pre,prechar)
+ end
+ if postchar and postchar > 0 then
+ done = true
+ post = copy_node(template)
+ setchar(post,postchar)
+ end
+ if done then
+ setdisc(d,pre,post,replace,regular_code,tex.hyphenpenalty)
+ end
+ else
+ -- print("lone regular discretionary ignored")
+ end
+ return template
+ end
+ end,
+ [disccodes.first] = function()
+ -- forget about them
+ end,
+ [disccodes.second] = function()
+ -- forget about them
+ end,
+ }
+
+ function languages.expand(d,template,subtype)
+ if not subtype then
+ subtype = getsubtype(d)
+ end
+ if subtype ~= discretionary_code then
+ return expanders[subtype](d,template)
+ end
+ end
+
+else
+
+ function languages.expand()
+ -- nothing to be fixed
+ end
+
+end
+
+languages.expanders = expanders
+
+-- lang-hyp.lua:
+
+----- expanders = languages.expanders -- gone in 1.005
+----- expand_explicit = expanders and expanders[explicit_code]
+----- expand_automatic = expanders and expanders[automatic_code]
+
+if LUATEXVERSION < 1.005 then -- not loaded any more
+
+ expanded = function(head)
+ local done = hyphenate(head)
+ if done then
+ for d in traverse_id(disc_code,tonut(head)) do
+ local s = getsubtype(d)
+ if s ~= discretionary_code then
+ expanders[s](d,template)
+ done = true
+ end
+ end
+ end
+ return head, done
+ end
+
+end
+
+-- if id == disc_code then
+-- if expanded then
+-- -- pre 1.005
+-- local subtype = getsubtype(current)
+-- if subtype == discretionary_code then -- \discretionary
+-- size = 0
+-- elseif subtype == explicit_code then -- \- => only here
+-- -- automatic (-) : the old parser makes negative char entries
+-- size = 0
+-- expand_explicit(current)
+-- elseif subtype == automatic_code then -- - => only here
+-- -- automatic (-) : the old hyphenator turns an exhyphen into glyph+disc
+-- size = 0
+-- expand_automatic(current)
+-- else
+-- -- first : done by the hyphenator
+-- -- second : done by the hyphenator
+-- -- regular : done by the hyphenator
+-- size = 0
+-- end
+-- else
+-- size = 0
+-- end
+-- current = getnext(current)
+-- if hyphenonly then
+-- skipping = true
+-- end
diff --git a/tex/context/base/mkiv/lang-hyp.lua b/tex/context/base/mkiv/lang-hyp.lua
index 27bd8130e..53a368b07 100644
--- a/tex/context/base/mkiv/lang-hyp.lua
+++ b/tex/context/base/mkiv/lang-hyp.lua
@@ -688,10 +688,6 @@ if context then
local a_hyphenation = attributes.private("hyphenation")
- local expanders = languages.expanders -- gone in 1.005
- local expand_explicit = expanders and expanders[explicit_code]
- local expand_automatic = expanders and expanders[automatic_code]
-
local interwordpenalty = 5000
function traditional.loadpatterns(language)
@@ -1543,28 +1539,7 @@ featureset.hyphenonly = hyphenonly == v_yes
skipping = false
end
if id == disc_code then
- if expanded then
- -- pre 1.005
- local subtype = getsubtype(current)
- if subtype == discretionary_code then -- \discretionary
- size = 0
- elseif subtype == explicit_code then -- \- => only here
- -- automatic (-) : the old parser makes negative char entries
- size = 0
- expand_explicit(current)
- elseif subtype == automatic_code then -- - => only here
- -- automatic (-) : the old hyphenator turns an exhyphen into glyph+disc
- size = 0
- expand_automatic(current)
- else
- -- first : done by the hyphenator
- -- second : done by the hyphenator
- -- regular : done by the hyphenator
- size = 0
- end
- else
- size = 0
- end
+ size = 0
current = getnext(current)
if hyphenonly then
skipping = true
@@ -1634,7 +1609,6 @@ featureset.hyphenonly = hyphenonly == v_yes
-- local replaceaction = nodes.tasks.replaceaction -- no longer overload this way (too many local switches)
local hyphenate = lang.hyphenate
- local expanders = languages.expanders
local methods = { }
local usedmethod = false
local stack = { }
@@ -1644,29 +1618,6 @@ featureset.hyphenonly = hyphenonly == v_yes
return head, done
end
- local expanded = function (head)
- local done = hyphenate(head)
- return head, done
- end
-
- if LUATEXVERSION < 1.005 then
-
- expanded = function(head)
- local done = hyphenate(head)
- if done then
- for d in traverse_id(disc_code,tonut(head)) do
- local s = getsubtype(d)
- if s ~= discretionary_code then
- expanders[s](d,template)
- done = true
- end
- end
- end
- return head, done
- end
-
- end
-
local getcount = tex.getcount
hyphenators.methods = methods
@@ -1693,7 +1644,7 @@ featureset.hyphenonly = hyphenonly == v_yes
methods.tex = original
methods.original = original
- methods.expanded = expanded -- obsolete starting with 1.005
+ methods.expanded = original -- was expanded before 1.005
methods.traditional = languages.hyphenators.traditional.hyphenate
methods.none = false -- function(head) return head, false end
diff --git a/tex/context/base/mkiv/lang-ini.lua b/tex/context/base/mkiv/lang-ini.lua
index e68938e35..6d202ff5a 100644
--- a/tex/context/base/mkiv/lang-ini.lua
+++ b/tex/context/base/mkiv/lang-ini.lua
@@ -18,7 +18,7 @@ if not modules then modules = { } end modules ['lang-ini'] = {
-- todo: no foo:bar but foo(bar,...)
-local type, tonumber = type, tonumber
+local type, tonumber, next = type, tonumber, next
local utfbyte = utf.byte
local format, gsub, gmatch, find = string.format, string.gsub, string.gmatch, string.find
local concat, sortedkeys, sortedpairs, keys, insert = table.concat, table.sortedkeys, table.sortedpairs, table.keys, table.insert
diff --git a/tex/context/base/mkiv/lang-rep.lua b/tex/context/base/mkiv/lang-rep.lua
index d4d16f6a3..172454fc2 100644
--- a/tex/context/base/mkiv/lang-rep.lua
+++ b/tex/context/base/mkiv/lang-rep.lua
@@ -15,7 +15,7 @@ if not modules then modules = { } end modules ['lang-rep'] = {
-- although (given experiences so far) we don't really need that. After all, each problem
-- is somewhat unique.
-local type, tonumber = type, tonumber
+local type, tonumber, next = type, tonumber, next
local gmatch, gsub = string.gmatch, string.gsub
local utfbyte, utfsplit = utf.byte, utf.split
local P, C, U, Cc, Ct, Cs, lpegmatch = lpeg.P, lpeg.C, lpeg.patterns.utf8character, lpeg.Cc, lpeg.Ct, lpeg.Cs, lpeg.match
diff --git a/tex/context/base/mkiv/lang-wrd.lua b/tex/context/base/mkiv/lang-wrd.lua
index 236fe89a3..b00375cc0 100644
--- a/tex/context/base/mkiv/lang-wrd.lua
+++ b/tex/context/base/mkiv/lang-wrd.lua
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['lang-wrd'] = {
license = "see context related readme files"
}
-local tonumber = tonumber
+local next, tonumber = next, tonumber
local lower = string.lower
local utfchar = utf.char
local concat, setmetatableindex = table.concat, table.setmetatableindex
diff --git a/tex/context/base/mkiv/lpdf-epa.lua b/tex/context/base/mkiv/lpdf-epa.lua
index ac0ca3c92..d17ae5065 100644
--- a/tex/context/base/mkiv/lpdf-epa.lua
+++ b/tex/context/base/mkiv/lpdf-epa.lua
@@ -347,15 +347,22 @@ function codeinjections.getbookmarks(filename)
local subtype = action.S
if subtype == "GoTo" then
destination = action.D
- if type(destination) == "string" then
+ local kind = type(destination)
+ if kind == "string" then
entry.destination = destination
destination = destinations[destination]
local pagedata = destination and destination[1]
if pagedata then
entry.realpage = pagedata.number
end
- else
- -- maybe
+ elseif kind == "table" then
+ local pageref = destination.n
+ if pageref then
+ local pagedata = pages[pageref]
+ if pagedata then
+ entry.realpage = pagedata.number
+ end
+ end
end
else
-- maybe
diff --git a/tex/context/base/mkiv/lpdf-epd.lua b/tex/context/base/mkiv/lpdf-epd.lua
index 59a1aa364..185efd92b 100644
--- a/tex/context/base/mkiv/lpdf-epd.lua
+++ b/tex/context/base/mkiv/lpdf-epd.lua
@@ -31,7 +31,7 @@ if not modules then modules = { } end modules ['lpdf-epd'] = {
-- a safer bet is foo("Title") which will return a decoded string (or the original if it
-- already was unicode).
-local setmetatable, rawset, rawget, type = setmetatable, rawset, rawget, type
+local setmetatable, rawset, rawget, type, next = setmetatable, rawset, rawget, type, next
local tostring, tonumber = tostring, tonumber
local lower, match, char, byte, find = string.lower, string.match, string.char, string.byte, string.find
local abs = math.abs
diff --git a/tex/context/base/mkiv/lpdf-fld.lua b/tex/context/base/mkiv/lpdf-fld.lua
index 29a520790..f220838de 100644
--- a/tex/context/base/mkiv/lpdf-fld.lua
+++ b/tex/context/base/mkiv/lpdf-fld.lua
@@ -1291,78 +1291,18 @@ function methods.push(name,specification)
end
local function makeradioparent(field,specification)
--- specification = enhance(specification,"Radio,RadiosInUnison")
specification = enhance(specification,"Radio,RadiosInUnison,Print,NoToggleToOff")
--- specification = enhance(specification,"Radio,Print,NoToggleToOff")
local d = pdfdictionary {
T = field.name,
FT = pdf_btn,
--- F = fieldplus(specification),
+ -- F = fieldplus(specification),
Ff = fieldflag(specification),
--- H = pdf_n,
+ -- H = pdf_n,
V = fielddefault(field),
}
save_parent(field,specification,d,true)
end
--- local function makeradiochild(name,specification)
--- local field, parent = clones[name], nil
--- if field then
--- field = radios[field.parent]
--- parent = fields[field.parent]
--- if not parent.pobj then
--- if trace_fields then
--- report_fields("forcing parent radio %a",parent.name)
--- end
--- makeradioparent(parent,parent)
--- end
--- else
--- field = radios[name]
--- if not field then
--- report_fields("there is some problem with field %a",name)
--- return nil
--- end
--- parent = fields[field.parent]
--- if not parent.pobj then
--- if trace_fields then
--- report_fields("using parent radio %a",name)
--- end
--- makeradioparent(parent,parent)
--- end
--- end
--- if trace_fields then
--- report_fields("using child radio %a with values %a and default %a",name,field.values,field.default)
--- end
--- local fontsymbol = specification.fontsymbol
--- fontsymbol="star"
--- local d = pdfdictionary {
--- Subtype = pdf_widget,
--- Parent = pdfreference(parent.pobj),
--- F = fieldplus(specification),
--- OC = fieldlayer(specification),
--- AA = fieldactions(specification),
--- H = pdf_n,
--- }
--- if fontsymbol and fontsymbol ~= "" then
--- local appearance, default, value = fieldstates_radio(field,true,false,false,name) -- false is also ok
--- specification.fontsymbol = todingbat(fontsymbol)
--- specification.fontstyle = "symbol"
--- specification.fontalternative = "dingbats"
--- d.DA = fieldsurrounding(specification)
--- d.MK = fieldrendering(specification)
--- d.AS = pdfconstant(value) -- default -- mandate when AP but confuses viewers
--- d.AP = appearance
--- return save_kid(parent,specification,d,value)
--- -- return save_kid(parent,specification,d,name)
--- else
--- -- local appearance, default, value = fieldstates_radio(field,true) -- false is also ok
--- local appearance, default, value = fieldstates_radio(field,true,false,false,name) -- false is also ok
--- d.AS = default -- mandate when AP but confuses viewers
--- d.AP = appearance
--- return save_kid(parent,specification,d,value)
--- end
--- end
-
local function makeradiochild(name,specification)
local field, parent = clones[name], nil
if field then
diff --git a/tex/context/base/mkiv/lpdf-wid.lua b/tex/context/base/mkiv/lpdf-wid.lua
index c2cd3bae1..d04af20f2 100644
--- a/tex/context/base/mkiv/lpdf-wid.lua
+++ b/tex/context/base/mkiv/lpdf-wid.lua
@@ -24,7 +24,7 @@ if not modules then modules = { } end modules ['lpdf-wid'] = {
-- video anyway. Also, it won't play on all platforms and devices so let's wait for
-- html5 media in pdf then.
-local tonumber = tonumber
+local tonumber, next = tonumber, next
local gmatch, gsub, find, lower, format = string.gmatch, string.gsub, string.find, string.lower, string.format
local stripstring = string.strip
local settings_to_array = utilities.parsers.settings_to_array
diff --git a/tex/context/base/mkiv/luat-cod.lua b/tex/context/base/mkiv/luat-cod.lua
index 445e365ff..ad7f34270 100644
--- a/tex/context/base/mkiv/luat-cod.lua
+++ b/tex/context/base/mkiv/luat-cod.lua
@@ -38,7 +38,7 @@ function lua.registeredcodes()
return lua.lastbytecode - lua.firstbytecode + 1
end
--- no file.* functions yet
+-- no file.* and utilities.parsers.* functions yet
function lua.registercode(filename,options)
local barename = gsub(filename,"%.[%a%d]+$","")
@@ -46,7 +46,7 @@ function lua.registercode(filename,options)
local basename = match(barename,"^.+[/\\](.-)$") or barename
if not bytedone[basename] then
local opts = { }
- if options ~= "" then
+ if type(options) == "string" and options ~= "" then
for s in gmatch(options,"([a-z]+)") do
opts[s] = true
end
diff --git a/tex/context/base/mkiv/luat-run.lua b/tex/context/base/mkiv/luat-run.lua
index 2e226dd18..f653e258f 100644
--- a/tex/context/base/mkiv/luat-run.lua
+++ b/tex/context/base/mkiv/luat-run.lua
@@ -6,6 +6,7 @@ if not modules then modules = { } end modules ['luat-run'] = {
license = "see context related readme files"
}
+local next = next
local format, find = string.format, string.find
local insert, remove = table.insert, table.remove
diff --git a/tex/context/base/mkiv/lxml-sor.lua b/tex/context/base/mkiv/lxml-sor.lua
index aba1c3b8d..a30392b95 100644
--- a/tex/context/base/mkiv/lxml-sor.lua
+++ b/tex/context/base/mkiv/lxml-sor.lua
@@ -8,6 +8,7 @@ if not modules then modules = { } end modules ['lxml-sor'] = {
local format, concat, rep = string.format, table.concat, string.rep
local lpegmatch = lpeg.match
+local next = next
local xml = xml
local lxml = lxml
diff --git a/tex/context/base/mkiv/lxml-xml.lua b/tex/context/base/mkiv/lxml-xml.lua
index 62564337c..d1520800f 100644
--- a/tex/context/base/mkiv/lxml-xml.lua
+++ b/tex/context/base/mkiv/lxml-xml.lua
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['lxml-xml'] = {
license = "see context related readme files"
}
-local tonumber = tonumber
+local tonumber, next = tonumber, next
local concat = table.concat
local find, lower, upper = string.find, string.lower, string.upper
diff --git a/tex/context/base/mkiv/math-act.lua b/tex/context/base/mkiv/math-act.lua
index 404ebbbcd..77a355b22 100644
--- a/tex/context/base/mkiv/math-act.lua
+++ b/tex/context/base/mkiv/math-act.lua
@@ -570,54 +570,6 @@ interfaces.implement {
-- check: when true, only set when present in font
-- force: when false, then not set when already set
-local blocks = characters.blocks -- this will move to char-ini
-
--- operators : 0x02200
--- symbolsa : 0x02701
--- symbolsb : 0x02901
--- supplemental : 0x02A00
-
--- from mathematics.gaps:
-
-blocks["lowercaseitalic"].gaps = {
- [0x1D455] = 0x0210E, -- ℎ h
-}
-
-blocks["uppercasescript"].gaps = {
- [0x1D49D] = 0x0212C, -- ℬ script B
- [0x1D4A0] = 0x02130, -- ℰ script E
- [0x1D4A1] = 0x02131, -- ℱ script F
- [0x1D4A3] = 0x0210B, -- ℋ script H
- [0x1D4A4] = 0x02110, -- ℐ script I
- [0x1D4A7] = 0x02112, -- ℒ script L
- [0x1D4A8] = 0x02133, -- ℳ script M
- [0x1D4AD] = 0x0211B, -- ℛ script R
-}
-
-blocks["lowercasescript"].gaps = {
- [0x1D4BA] = 0x0212F, -- ℯ script e
- [0x1D4BC] = 0x0210A, -- ℊ script g
- [0x1D4C4] = 0x02134, -- ℴ script o
-}
-
-blocks["uppercasefraktur"].gaps = {
- [0x1D506] = 0x0212D, -- ℭ fraktur C
- [0x1D50B] = 0x0210C, -- ℌ fraktur H
- [0x1D50C] = 0x02111, -- ℑ fraktur I
- [0x1D515] = 0x0211C, -- ℜ fraktur R
- [0x1D51D] = 0x02128, -- ℨ fraktur Z
-}
-
-blocks["uppercasedoublestruck"].gaps = {
- [0x1D53A] = 0x02102, -- ℂ bb C
- [0x1D53F] = 0x0210D, -- ℍ bb H
- [0x1D545] = 0x02115, -- ℕ bb N
- [0x1D547] = 0x02119, -- ℙ bb P
- [0x1D548] = 0x0211A, -- ℚ bb Q
- [0x1D549] = 0x0211D, -- ℝ bb R
- [0x1D551] = 0x02124, -- ℤ bb Z
-}
-
-- todo: tounicode
-- function mathematics.injectfallbacks(target,original)
@@ -787,6 +739,7 @@ function mathematics.finishfallbacks(target,specification,fallbacks)
if gaps then
for unic, unicode in next, gaps do
remap(unic,unicode,true)
+ remap(unicode,unicode,true)
end
end
end
diff --git a/tex/context/base/mkiv/math-fbk.lua b/tex/context/base/mkiv/math-fbk.lua
index 0af975125..dd3b84bd6 100644
--- a/tex/context/base/mkiv/math-fbk.lua
+++ b/tex/context/base/mkiv/math-fbk.lua
@@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['math-fbk'] = {
license = "see context related readme files"
}
+local next, type = next, type
+
local trace_fallbacks = false trackers.register("math.fallbacks", function(v) trace_fallbacks = v end)
local report_fallbacks = logs.reporter("math","fallbacks")
diff --git a/tex/context/base/mkiv/math-ini.lua b/tex/context/base/mkiv/math-ini.lua
index 5c495dbd7..b79ef8c8c 100644
--- a/tex/context/base/mkiv/math-ini.lua
+++ b/tex/context/base/mkiv/math-ini.lua
@@ -15,6 +15,7 @@ if not modules then modules = { } end modules ['math-ini'] = {
-- to the fam when set ... we use other means .. ok, we could use it for spacing but
-- then we also have to set the other characters (only a subset done now)
+local next, type = next, type
local formatters, find = string.formatters, string.find
local utfchar, utfbyte, utflength = utf.char, utf.byte, utf.length
----- floor = math.floor
@@ -314,15 +315,29 @@ function mathematics.define(family)
local mathclass = character.mathclass
local mathspec = character.mathspec
if mathspec then
+ if mathclass then
+ local name = character.mathname
+ if name then
+ report_math("fatal error, conlicting mathclass and mathspec for %C",unicode)
+ os.exit()
+ else
+ local class = classes[mathclass] or mathclass -- no real checks needed
+ if not class then
+ if trace_defining then
+ report("unknown",family,unicode)
+ end
+ else
+ if trace_defining then
+ report(class,family,unicode)
+ end
+ mset, dset = setmathcharacter(class,family,unicode,unicode,mset,dset)
+ end
+ end
+ end
for i=1,#mathspec do
local m = mathspec[i]
local name = m.name
local class = m.class
- if not class then
- class = mathclass
- elseif not mathclass then
- mathclass = class
- end
if class then
class = classes[class] or class -- no real checks needed
if name then
@@ -331,7 +346,7 @@ function mathematics.define(family)
end
setmathsymbol(name,class,family,unicode)
else
- name = class == classes.variable or class == classes.number and character.adobename
+ name = (class == classes.variable or class == classes.number) and character.adobename -- bad
if name and trace_defining then
report(class,family,unicode,name)
end
@@ -339,17 +354,22 @@ function mathematics.define(family)
mset, dset = setmathcharacter(class,family,unicode,m.unicode or unicode,mset,dset) -- see solidus
end
end
- end
- if mathclass then
+ elseif mathclass then
local name = character.mathname
local class = classes[mathclass] or mathclass -- no real checks needed
- if name == false then
+ if not class then
+ if trace_defining then
+ report("unknown",family,unicode,name)
+ end
+ elseif name == false then
if trace_defining then
report(class,family,unicode,name)
end
- mset, dset = setmathcharacter(class,family,unicode,mset,dset)
+ mset, dset = setmathcharacter(class,family,unicode,unicode,mset,dset)
else
- name = name or character.contextname
+ -- if not name then
+ -- name = character.contextname -- too dangerous, we loose textslash and a few more
+ -- end
if name then
if trace_defining then
report(class,family,unicode,name)
diff --git a/tex/context/base/mkiv/math-ini.mkiv b/tex/context/base/mkiv/math-ini.mkiv
index f951d7571..e4c02b6c2 100644
--- a/tex/context/base/mkiv/math-ini.mkiv
+++ b/tex/context/base/mkiv/math-ini.mkiv
@@ -659,7 +659,7 @@
\letcsnamecsname\csname#1\endcsname\csname\??mathcommand#1\endcsname}
\unexpanded\def\mathcommand#1%
- {\csname\??mathcommand#1\endcsname}
+ {\begincsname\??mathcommand#1\endcsname}
%D Let's define a few comands here:
diff --git a/tex/context/base/mkiv/meta-fnt.lua b/tex/context/base/mkiv/meta-fnt.lua
index 1f5670c66..d061c926a 100644
--- a/tex/context/base/mkiv/meta-fnt.lua
+++ b/tex/context/base/mkiv/meta-fnt.lua
@@ -6,6 +6,7 @@ if not modules then modules = { } end modules ['meta-fnt'] = {
license = "see context related readme files"
}
+local next = next
local concat = table.concat
local format = string.format
local formatters = string.formatters
diff --git a/tex/context/base/mkiv/mlib-lua.lua b/tex/context/base/mkiv/mlib-lua.lua
index b2d97226a..7efed1e5d 100644
--- a/tex/context/base/mkiv/mlib-lua.lua
+++ b/tex/context/base/mkiv/mlib-lua.lua
@@ -673,7 +673,10 @@ do
end
do
-local stores = { }
+
+ local mpvprint = mp.vprint
+
+ local stores = { }
function mp.newstore(name)
stores[name] = { }
@@ -688,7 +691,7 @@ local stores = { }
end
function mp.fromstore(name,key)
- mp.vprint(stores[name][key]) -- type specific
+ mpvprint(stores[name][key]) -- type specific
end
interfaces.implement {
@@ -700,3 +703,14 @@ local stores = { }
}
end
+
+do
+
+ local mpprint = mp.print
+ local texmodes = tex.modes
+
+ function mp.processingmode(s)
+ mpprint(tostring(texmodes[s]))
+ end
+
+end
diff --git a/tex/context/base/mkiv/mlib-pdf.lua b/tex/context/base/mkiv/mlib-pdf.lua
index 7fd6cb62c..75f810fb3 100644
--- a/tex/context/base/mkiv/mlib-pdf.lua
+++ b/tex/context/base/mkiv/mlib-pdf.lua
@@ -578,7 +578,7 @@ function metapost.flush(result,flusher,askedfig)
result[#result+1] = open and "S" or "h S"
end
elseif objecttype == "both" then
- result[#result+1] = evenodd and "h B*" or "h B"-- B* = eo -- b includes closepath
+ result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo -- b includes closepath
end
end
if transformed then
@@ -613,7 +613,7 @@ function metapost.flush(result,flusher,askedfig)
elseif objecttype == "outline" then
result[#result+1] = open and "S" or "h S"
elseif objecttype == "both" then
- result[#result+1] = evenodd and "h B*" or "h B"-- B* = eo -- b includes closepath
+ result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo -- b includes closepath
end
if transformed then
result[#result+1] = "Q"
diff --git a/tex/context/base/mkiv/mlib-pps.lua b/tex/context/base/mkiv/mlib-pps.lua
index 9fc8fec35..bb5ce31e5 100644
--- a/tex/context/base/mkiv/mlib-pps.lua
+++ b/tex/context/base/mkiv/mlib-pps.lua
@@ -7,7 +7,7 @@ if not modules then modules = { } end modules ['mlib-pps'] = {
}
local format, gmatch, match, split = string.format, string.gmatch, string.match, string.split
-local tonumber, type, unpack = tonumber, type, unpack
+local tonumber, type, unpack, next = tonumber, type, unpack, next
local round, sqrt, min, max = math.round, math.sqrt, math.min, math.max
local insert, remove, concat = table.insert, table.remove, table.concat
local Cs, Cf, C, Cg, Ct, P, S, V, Carg = lpeg.Cs, lpeg.Cf, lpeg.C, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.S, lpeg.V, lpeg.Carg
diff --git a/tex/context/base/mkiv/mlib-run.lua b/tex/context/base/mkiv/mlib-run.lua
index 93ce1fec2..18bc7e4da 100644
--- a/tex/context/base/mkiv/mlib-run.lua
+++ b/tex/context/base/mkiv/mlib-run.lua
@@ -29,7 +29,7 @@ approach is way faster than an external <l n='metapost'/> and processing time
nears zero.</p>
--ldx]]--
-local type, tostring, tonumber = type, tostring, tonumber
+local type, tostring, tonumber, next = type, tostring, tonumber, next
local gsub, match, find = string.gsub, string.match, string.find
local striplines = utilities.strings.striplines
local concat, insert, remove = table.concat, table.insert, table.remove
diff --git a/tex/context/base/mkiv/mult-aux.lua b/tex/context/base/mkiv/mult-aux.lua
index 353b5e69c..bcd5ae5be 100644
--- a/tex/context/base/mkiv/mult-aux.lua
+++ b/tex/context/base/mkiv/mult-aux.lua
@@ -7,6 +7,7 @@ if not modules then modules = { } end modules ['mult-aux'] = {
}
local find = string.find
+local next = next
interfaces.namespaces = interfaces.namespaces or { }
local namespaces = interfaces.namespaces
diff --git a/tex/context/base/mkiv/mult-def.lua b/tex/context/base/mkiv/mult-def.lua
index bbb079cc8..0cb60487d 100644
--- a/tex/context/base/mkiv/mult-def.lua
+++ b/tex/context/base/mkiv/mult-def.lua
@@ -6589,6 +6589,18 @@ return {
["pe"]="حرف‌تنظیم",
["ro"]="aliniazacaracter",
},
+ ["alignmentleftwidth"]={
+ ["en"]="alignmentleftwidth",
+ },
+ ["alignmentrightwidth"]={
+ ["en"]="alignmentrightwidth",
+ },
+ ["alignmentleftsample"]={
+ ["en"]="alignmentleftsample",
+ },
+ ["alignmentrightsample"]={
+ ["en"]="alignmentrightsample",
+ },
["alignmentcharacter"]={
["cs"]="alignmentcharacter",
["de"]="alignmentcharacter",
@@ -9271,6 +9283,11 @@ return {
},
["note"]={
["en"]="note",
+ ["nl"]="noot",
+ },
+ ["notes"]={
+ ["en"]="notes",
+ ["nl"]="noten",
},
["nr"]={
["cs"]="nr",
@@ -10278,6 +10295,12 @@ return {
["pe"]="همان‌صفحه",
["ro"]="aceeasipagina",
},
+ ["leftsample"]={
+ ["en"]="leftsample",
+ },
+ ["rightsample"]={
+ ["en"]="rightsample",
+ },
["sample"]={
["cs"]="vzor",
["de"]="muster",
@@ -10457,6 +10480,14 @@ return {
["pe"]="فضای‌کناری‌قبل",
["ro"]="spatiulateralinainte",
},
+ ["spaceafterside"]={
+ ["en"]="spaceafterside",
+ ["nl"]="witnazij",
+ },
+ ["spacebeforeside"]={
+ ["en"]="spacebeforeside",
+ ["nl"]="witvoorzij",
+ },
["sign"]={
["cs"]="znak",
["de"]="zeichen",
@@ -10720,6 +10751,14 @@ return {
["pe"]="بست",
["ro"]="strut",
},
+ ["numberstrut"]={
+ ["en"]="numberstrut",
+ ["nl"]="nummerstrut",
+ },
+ ["titlestrut"]={
+ ["en"]="titlestrut",
+ ["nl"]="titelstrut",
+ },
["style"]={
["cs"]="pismeno",
["de"]="stil",
@@ -16367,6 +16406,10 @@ return {
["pe"]="ایست",
["ro"]="stopper",
},
+ ["nostopper"]={
+ ["en"]="nostopper",
+ ["nl"]="geenafsluiter",
+ },
["stretch"]={
["cs"]="natahnout",
["de"]="strecken",
diff --git a/tex/context/base/mkiv/mult-ini.lua b/tex/context/base/mkiv/mult-ini.lua
index f600c6111..b899d25f2 100644
--- a/tex/context/base/mkiv/mult-ini.lua
+++ b/tex/context/base/mkiv/mult-ini.lua
@@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['mult-ini'] = {
local format, gmatch, match, find, sub = string.format, string.gmatch, string.match, string.find, string.sub
local lpegmatch = lpeg.match
local serialize, concat = table.serialize, table.concat
-local rawget, type, tonumber = rawget, type, tonumber
+local rawget, type, tonumber, next = rawget, type, tonumber, next
local context = context
local commands = commands
diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua
index 848bd8804..f54052bb0 100644
--- a/tex/context/base/mkiv/mult-low.lua
+++ b/tex/context/base/mkiv/mult-low.lua
@@ -244,6 +244,7 @@ return {
"doifelsenextoptional", "doifnextoptionalelse",
"doifelsenextoptionalcs", "doifnextoptionalcselse",
"doifelsefastoptionalcheck", "doiffastoptionalcheckelse",
+ "doifelsefastoptionalcheckcs", "doiffastoptionalcheckcselse",
"doifelsenextbgroup", "doifnextbgroupelse",
"doifelsenextbgroupcs", "doifnextbgroupcselse",
"doifelsenextparenthesis", "doifnextparenthesiselse",
@@ -341,7 +342,7 @@ return {
--
"offinterlineskip", "oninterlineskip", "nointerlineskip",
--
- "strut", "halfstrut", "quarterstrut", "depthstrut", "halflinestrut", "noheightstrut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "begstrut", "endstrut", "lineheight",
+ "strut", "halfstrut", "quarterstrut", "depthstrut", "halflinestrut", "noheightstrut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "strutgap", "begstrut", "endstrut", "lineheight",
"leftboundary", "rightboundary", "signalcharacter",
--
"ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing",
diff --git a/tex/context/base/mkiv/node-fnt.lua b/tex/context/base/mkiv/node-fnt.lua
index 888e61cdb..f846f996d 100644
--- a/tex/context/base/mkiv/node-fnt.lua
+++ b/tex/context/base/mkiv/node-fnt.lua
@@ -143,28 +143,28 @@ local ligaturing = nuts.ligaturing
local kerning = nuts.kerning
-- -- -- this will go away
-
-local disccodes = nodes.disccodes
-local explicit_code = disccodes.explicit
-local automatic_code = disccodes.automatic
-local expanders = nil
-
-function fonts.setdiscexpansion(v)
- if v == nil or v == true then
- expanders = languages and languages.expanders
- elseif type(v) == "table" then
- expanders = v
- else
- expanders = false
- end
-end
-
-function fonts.getdiscexpansion()
- return expanders and true or false
-end
-
-fonts.setdiscexpansion(true)
-
+--
+-- local disccodes = nodes.disccodes
+-- local explicit_code = disccodes.explicit
+-- local automatic_code = disccodes.automatic
+-- local expanders = nil
+--
+-- function fonts.setdiscexpansion(v)
+-- if v == nil or v == true then
+-- expanders = languages and languages.expanders
+-- elseif type(v) == "table" then
+-- expanders = v
+-- else
+-- expanders = false
+-- end
+-- end
+--
+-- function fonts.getdiscexpansion()
+-- return expanders and true or false
+-- end
+--
+-- fonts.setdiscexpansion(true)
+--
-- -- -- till here
local function start_trace(head)
@@ -196,9 +196,9 @@ local function stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant,e,expa
report_fonts("dynamics: %s",a > 0 and concat(keys(attrfonts)," ") or "none")
report_fonts("built-in: %s",b > 0 and b or "none")
report_fonts("removed : %s",r > 0 and r or "none")
-if expanders then
- report_fonts("expanded: %s",e > 0 and e or "none")
-end
+ -- if expanders then
+ -- report_fonts("expanded: %s",e > 0 and e or "none")
+ -- end
report_fonts()
end
@@ -445,12 +445,12 @@ function handlers.characters(head,groupcode,size,packtype,direction)
if firstnone then
protectnone()
end
- elseif expanders then
- local subtype = getsubtype(d)
- if subtype == automatic_code or subtype == explicit_code then
- expanders[subtype](d)
- e = e + 1
- end
+ -- elseif expanders then
+ -- local subtype = getsubtype(d)
+ -- if subtype == automatic_code or subtype == explicit_code then
+ -- expanders[subtype](d)
+ -- e = e + 1
+ -- end
end
end
diff --git a/tex/context/base/mkiv/node-nut.lua b/tex/context/base/mkiv/node-nut.lua
index b0730526b..a621b6481 100644
--- a/tex/context/base/mkiv/node-nut.lua
+++ b/tex/context/base/mkiv/node-nut.lua
@@ -115,85 +115,6 @@ nuts.tonut = tonut
nodes.tonode = tonode
nodes.tonut = tonut
--- getters
-
--- if not direct.getcomponents then
---
--- local getfield = direct.getfield
--- local setfield = direct.setfield
--- local setsubtype = direct.setsubtype
---
--- local attributelist_code = nodecodes.attributelist
---
--- function direct.getcomponents(n) return getfield(n,"components") end
--- function direct.setcomponents(n,c) setfield(n,"components",c) end
--- function direct.getkern(n) return getfield(n,"kern") end
--- function direct.getwidth(n) return getfield(n,"width") end
--- function direct.setwidth(n,w) return setfield(n,"width",w) end
--- function direct.getheight(n) return getfield(n,"height") end
--- function direct.setheight(n,h) return setfield(n,"height",h) end
--- function direct.getdepth(n) return getfield(n,"depth") end
--- function direct.setdepth(n,d) return setfield(n,"depth",d) end
--- function direct.getshift(n) return getfield(n,"shift") end
--- function direct.setshift(n,s) return setfield(n,"shift",s) end
--- function direct.getpenalty(n) return getfield(n,"penalty") end
--- function direct.setpenalty(n,p) setfield(n,"penalty",p) end
--- function direct.getdir(n) return getfield(n,"dir") end
--- function direct.setdir(n,p) setfield(n,"dir",p) end
--- function direct.getlanguage(n) return getfield(n,"lang") end
--- function direct.setlanguage(n,l) return setfield(n,"lang",l) end
--- function direct.getattributelist(n) getfield(n,"attr") end
---
--- function direct.getnucleus(n) return getfield(n,"nucleus") end
--- function direct.setnucleus(n,p) return setfield(n,"nucleus",p) end
--- function direct.getsup(n) return getfield(n,"sup") end
--- function direct.setsup(n,p) return setfield(n,"sup",p) end
--- function direct.getsub(n) return getfield(n,"sub") end
--- function direct.setsub(n,p) return setfield(n,"sub",p) end
---
--- function direct.setattributelist(n,a)
--- if a and type(a) ~= attributelist_code then
--- a = getfield(a,"attr")
--- end
--- setfield(n,"attr",a)
--- end
---
--- function direct.setkern(n,k,s)
--- setfield(n,"kern",k)
--- if s then
--- setsubtype(n,s)
--- end
--- end
---
--- function direct.setfont(n,f,c)
--- setfield(n,"font",f)
--- if c then
--- setfield(n,"char",f)
--- end
--- end
---
--- function direct.getoffsets(n)
--- return getfield(n,"xoffset"), getfield(n,"yoffset")
--- end
---
--- function direct.setoffsets(n,x,y)
--- if x then
--- setfield(n,"xoffset",x)
--- end
--- if y then
--- setfield(n,"yoffset",y)
--- end
--- end
---
--- end
---
--- if LUATEXVERSION < 1.005 then
--- local getfield = direct.getfield
--- function direct.getnucleus(n) return getfield(n,"nucleus") end
--- function direct.getsub (n) return getfield(n,"sub") end
--- function direct.getsup (n) return getfield(n,"sup") end
--- end
-
-- -- some tracing:
--
-- local hash = table.setmetatableindex("number")
@@ -217,19 +138,17 @@ nodes.tonut = tonut
-- return f(...)
-- end
-- end
-
+--
-- track("getfield")
--- setters
-
-- helpers
-if not direct.getfam then
+if not direct.getfam then -- LUATEXVERSION < 1.070
local getfield = direct.getfield
local setfield = direct.setfield
- direct.getfam = function(n,f) getfield(n,"small_fam",f) end
- direct.setfam = function(n,f) setfield(n,"small_fam",f) end
+ direct.getfam = function(n) return getfield(n,"small_fam") end
+ direct.setfam = function(n,f) setfield(n,"small_fam",f) end
end
nuts.tostring = direct.tostring
@@ -408,20 +327,6 @@ local d_setlink = direct.setlink
local d_setboth = direct.setboth
local d_getboth = direct.getboth
--- local function remove(head,current,free_too)
--- local t = current
--- head, current = d_remove_node(head,current)
--- if not t then
--- -- forget about it
--- elseif free_too then
--- d_flush_node(t)
--- t = nil
--- else
--- d_setboth(t) -- (t,nil,nil)
--- end
--- return head, current, t
--- end
-
local function remove(head,current,free_too)
if current then
local h, c = d_remove_node(head,current)
@@ -454,12 +359,6 @@ function nuts.replace(head,current,new) -- no head returned if false
head, current, new = false, head, current
end
local prev, next = d_getboth(current)
--- if next then
--- d_setlink(new,next)
--- end
--- if prev then
--- d_setlink(prev,new)
--- end
if prev or next then
d_setlink(prev,new,next)
end
@@ -957,7 +856,7 @@ if not nuts.unprotect_glyph then
end
-if LUATEXFUNCTIONALITY < 6384 then
+if LUATEXFUNCTIONALITY < 6384 then -- LUATEXVERSION < 1.070
local getfield = nuts.getfield
local setfield = nuts.setfield
diff --git a/tex/context/base/mkiv/node-tra.lua b/tex/context/base/mkiv/node-tra.lua
index fab9d51ac..f12599866 100644
--- a/tex/context/base/mkiv/node-tra.lua
+++ b/tex/context/base/mkiv/node-tra.lua
@@ -11,6 +11,7 @@ if not modules then modules = { } end modules ['node-tra'] = {
might become a runtime module instead. This module will be cleaned up!</p>
--ldx]]--
+local next = next
local utfchar = utf.char
local format, match, gmatch, concat, rep = string.format, string.match, string.gmatch, table.concat, string.rep
local lpegmatch = lpeg.match
diff --git a/tex/context/base/mkiv/page-brk.mkiv b/tex/context/base/mkiv/page-brk.mkiv
index 7ab74c0e4..e18c0d923 100644
--- a/tex/context/base/mkiv/page-brk.mkiv
+++ b/tex/context/base/mkiv/page-brk.mkiv
@@ -504,7 +504,7 @@
\ifdim\pagetotal<\pagegoal \relax
\getnoflines\pagegoal
\ifdim\dimexpr\page_check_amount-\noflines\lineheight\relax>-\lineheight
- \pagecheckparameter\c!before
+ \pagecheckerparameter\c!before
\penalty-\plustenthousand
\pagecheckerparameter\c!after
\else
diff --git a/tex/context/base/mkiv/page-ffl.mkiv b/tex/context/base/mkiv/page-ffl.mkiv
new file mode 100644
index 000000000..5536371a7
--- /dev/null
+++ b/tex/context/base/mkiv/page-ffl.mkiv
@@ -0,0 +1,211 @@
+%D \module
+%D [ file=page-ffl,
+%D version=2018.01.04,
+%D title=\CONTEXT\ Page Macros,
+%D subtitle=Facing floats,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Page Macros / Facing floats}
+
+%D The code below comes from a module made for Thomas Schmitz and is now part of the
+%D core. A simple example is given here:
+%D
+%D \starttyping
+%D \definefacingfloat
+%D [whatever]
+%D
+%D \setupfacingfloat
+%D [whatever]
+%D [style=bold,
+%D color=white]
+%D
+%D \setupfacingfloat
+%D [whatever:left]
+%D [background=color,
+%D backgroundcolor=red]
+%D
+%D \setupfacingfloat
+%D [whatever:right]
+%D [background=color,
+%D backgroundcolor=green]
+%D
+%D \startfacingfloat[whatever]
+%D {\dorecurse{10}{\samplefile{tufte} }}
+%D {\dorecurse{10}{\samplefile{ward} }}
+%D {\dorecurse{10}{\samplefile{tufte} }}
+%D {\dorecurse{10}{\samplefile{ward} }}
+%D \stopfacingfloat
+%D
+%D \startfacingfloat[whatever]
+%D \startcontent \dorecurse{10}{\samplefile{tufte} } \stopcontent
+%D \startcontent \dorecurse{10}{\samplefile{ward} } \stopcontent
+%D \startcontent \dorecurse{10}{\samplefile{tufte} } \stopcontent
+%D \startcontent \dorecurse{10}{\samplefile{ward} } \stopcontent
+%D \stopfacingfloat
+%D
+%D \dorecurse{10}{\samplefile{sapolsky} }
+%D \stoptyping
+%D
+%D The idea is to flush related floats more or less in parallel.
+
+\unprotect
+
+\installcorenamespace {facingfloat}
+
+\installframedcommandhandler \??facingfloat {facingfloat} \??facingfloat
+
+\setupfacingfloat
+ [\c!spaceinbetween=\v!big,
+ \c!inbetween={\blank[\v!big]},
+ %\c!style,
+ %\c!color,
+ \c!page=\v!yes]
+
+\appendtoks
+ \ifx\currentfacingfloatparent\empty
+ \normalexpanded{\definefacingfloat[\currentfacingfloat:\v!left ][\currentfacingfloat]}%
+ \normalexpanded{\definefacingfloat[\currentfacingfloat:\v!right][\currentfacingfloat]}%
+ \fi
+\to \everydefinefacingfloat
+
+\newcount\c_strc_floats_saved
+\newcount\c_strc_floats_flushed
+
+\newbox\b_strc_floats_facing_l
+\newbox\b_strc_floats_facing_r
+
+\let\m_strc_floats_state\relax
+
+\def\strc_floats_facing_flush
+ {\ifnum\c_strc_floats_flushed<\c_strc_floats_saved
+ \global\advance\c_strc_floats_flushed\plusone
+ \floatingpenalty\zerocount
+ \insert\namedinsertionnumber\s!topfloat\bgroup
+ \forgetall
+ \ifconditional\c_page_one_top_of_insert
+ \ifconditional\c_page_one_correct_top_insert
+ \topskipcorrection % [xx] new: see icare topbleed
+ \kern-\lineskip
+ \par
+ \prevdepth\maxdimen
+ \fi
+ \fi
+ \directboxfromcache{\currentfacingfloat}{\number\c_strc_floats_flushed}%
+ \vskip\s_page_one_between_top_insert
+ \egroup
+ \ifnum\c_strc_floats_saved=\c_strc_floats_flushed
+ \global\c_strc_floats_saved \zerocount
+ \global\c_strc_floats_flushed\zerocount
+ \resetboxesincache{\currentfacingfloat}%
+ \fi
+ \fi}
+
+\unexpanded\def\strc_floats_facing_setup
+ {\edef\currentfacingfloat{\currentfacingfloat:\m_strc_floats_state}%
+ \usefacingfloatstyleandcolor\c!style\v!color}
+
+\unexpanded\def\strc_floats_facing_collect
+ {\ifx\m_strc_floats_state\v!left
+ \ifvoid\nextbox\else\ifzeropt\wd\nextbox\else
+ \ifvoid\b_strc_floats_facing_l
+ \setbox\b_strc_floats_facing_l\box\nextbox
+ \else
+ \setbox\b_strc_floats_facing_l\vbox\bgroup
+ \unvbox\b_strc_floats_facing_l
+ \facingfloatparameter\c!inbetween
+ \unvbox\nextbox
+ \egroup
+ \fi
+ \fi\fi
+ \let\m_strc_floats_state\v!right
+ \else\ifx\m_strc_floats_state\v!right
+ \ifvoid\nextbox\else\ifzeropt\wd\nextbox\else
+ \ifvoid\b_strc_floats_facing_r
+ \setbox\b_strc_floats_facing_r\box\nextbox
+ \else
+ \setbox\b_strc_floats_facing_r\vbox\bgroup
+ \unvbox\b_strc_floats_facing_r
+ \facingfloatparameter\c!inbetween
+ \unvbox\nextbox
+ \egroup
+ \fi
+ \fi\fi
+ \let\m_strc_floats_state\v!left
+ \else
+ \let\m_strc_floats_state\v!left
+ \fi\fi}
+
+\unexpanded\def\strc_floats_facing_handle
+ {\strc_floats_facing_collect
+ \doifnextbgroupelse
+ \strc_floats_facing_handle_indeed
+ \strc_floats_wrap_up}
+
+\unexpanded\def\strc_floats_facing_handle_indeed
+ {\dowithnextboxcontent
+ \strc_floats_facing_setup
+ \strc_floats_facing_handle
+ \vbox}
+
+\unexpanded\def\startfacingfloat[#1]%
+ {\begingroup
+ % todo: \usepageparameter
+ \edef\p_page{\facingfloatparameter\c!page}%
+ \ifx\p_page\empty
+ \page[\p_page]%
+ \fi
+ %
+ \let\startcontent\bgroup
+ \let\stopcontent\egroup
+ \def\currentfacingfloat{#1}%
+ \strc_floats_facing_handle}
+
+\unexpanded\def\stopfacingfloat
+ {\endgroup}
+
+\unexpanded\def\strc_floats_wrap_up
+ {\edef\p_spaceinbetween{\facingfloatparameter\c!spaceinbetween}%
+ \ifx\p_spaceinbetween\empty
+ \scratchdimen\zeropoint
+ \else
+ \setbox\scratchbox\vbox{\directvspacing\p_spaceinbetween}%
+ \scratchdimen\htdp\scratchbox
+ \fi
+ \doloop{%
+ \strc_floats_facing_flush_wrap\b_strc_floats_facing_l\v!left
+ \strc_floats_facing_flush_wrap\b_strc_floats_facing_r\v!right
+ \ifvoid\b_strc_floats_facing_l\relax\ifvoid\b_strc_floats_facing_r\relax
+ \exitloop
+ \fi\fi}}
+
+\def\strc_floats_facing_flush_wrap#1#2%
+ {\ifvoid#1\relax
+ % todo
+ \else
+ \begingroup
+ \setbox\scratchbox\vsplit#1 upto \textheight
+ \setbox\scratchbox\hpack\bgroup
+ \edef\currentfacingfloat{\currentfacingfloat:#2}%
+ \inheritedfacingfloatframed{\box\scratchbox}%
+ \egroup
+ \ifdim\ht\scratchbox<\dimexpr\textheight-\scratchdimen\relax
+ \setbox\scratchbox\vbox{\box\scratchbox\directvspacing\p_spaceinbetween}%
+ \else
+ \setbox\scratchbox\vbox to \textheight{\box\scratchbox\vss}%
+ \fi
+ \global\advance\c_strc_floats_saved\plusone
+ \putboxincache{\currentfacingfloat}{\number\c_strc_floats_saved}\scratchbox
+ \endgroup
+ \fi}
+
+\appendtoks
+ \strc_floats_facing_flush
+\to \everyafteroutput
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/page-flt.lua b/tex/context/base/mkiv/page-flt.lua
index a082cc71e..41a35d47b 100644
--- a/tex/context/base/mkiv/page-flt.lua
+++ b/tex/context/base/mkiv/page-flt.lua
@@ -9,6 +9,7 @@ if not modules then modules = { } end modules ['page-flt'] = {
-- floats -> managers.floats
-- some functions are a tex/lua mix so we need a separation
+local next = next
local tostring = tostring
local insert, remove = table.insert, table.remove
local find = string.find
diff --git a/tex/context/base/mkiv/page-lay.mkiv b/tex/context/base/mkiv/page-lay.mkiv
index 8da2b5017..294718f9c 100644
--- a/tex/context/base/mkiv/page-lay.mkiv
+++ b/tex/context/base/mkiv/page-lay.mkiv
@@ -473,11 +473,23 @@
[\page_paper_the_paper_size{#1}]%
[\page_paper_the_print_size{#2}]}}
-\setvalue{\??layoutpaper\v!reset }{\global\setfalse\c_page_target_paper_landscape
- \global\setfalse\c_page_target_paper_mirror
- \global\setfalse\c_page_target_paper_negate
- \global\c_page_target_paper_orientation\uprotationangle
- \global\c_page_target_paper_reverse \uprotationangle}
+\unexpanded\def\page_paper_reset_paper
+ {\global\setfalse\c_page_target_paper_landscape
+ \global\setfalse\c_page_target_paper_mirror
+ \global\setfalse\c_page_target_paper_negate
+ \global\c_page_target_paper_orientation\uprotationangle
+ \global\c_page_target_paper_reverse \uprotationangle}
+
+\unexpanded\def\page_paper_reset_print
+ {\global\setfalse\c_page_target_print_landscape
+ \global\setfalse\c_page_target_print_mirror
+ \global\setfalse\c_page_target_print_negate
+ \global\c_page_target_print_orientation\uprotationangle
+ \global\c_page_target_print_reverse \uprotationangle}
+
+\letvalue{\??layoutpaper\v!reset}\page_paper_reset_paper
+\letvalue{\??layoutprint\v!reset}\page_paper_reset_print
+
\setvalue{\??layoutpaper\v!landscape }{\global\settrue\c_page_target_paper_landscape}
\setvalue{\??layoutpaper\v!mirrored }{\global\settrue\c_page_target_paper_mirror}
\setvalue{\??layoutpaper\v!negative }{\global\settrue\c_page_target_paper_negate}
@@ -490,11 +502,6 @@
\setvalue{\??layoutpaper\number\leftrotationangle }{\global\c_page_target_paper_orientation\leftrotationangle
\global\c_page_target_paper_reverse \rightrotationangle}
-\setvalue{\??layoutprint\v!reset }{\global\setfalse\c_page_target_print_landscape
- \global\setfalse\c_page_target_print_mirror
- \global\setfalse\c_page_target_print_negate
- \global\c_page_target_print_orientation\uprotationangle
- \global\c_page_target_print_reverse \uprotationangle}
\setvalue{\??layoutprint\v!landscape }{\global\settrue\c_page_target_print_landscape}
\setvalue{\??layoutprint\v!mirrored }{\global\settrue\c_page_target_print_mirror}
\setvalue{\??layoutprint\v!negative }{\global\settrue\c_page_target_print_negate}
@@ -519,18 +526,20 @@
\fi}
\unexpanded\def\page_paper_set_current_indeed[#1][#2]%
- {\edef\m_page_asked_paper{\v!reset,#1}% can be the restores
- \edef\m_page_asked_print{\v!reset,#2}%
+ {\edef\m_page_asked_paper{#1}% can be the restores
+ \edef\m_page_asked_print{#2}%
%
\page_paper_set_restore\m_page_asked_paper\m_page_asked_print
%
% locate page target
\let\currentlayouttarget\empty
+ \page_paper_reset_paper
\processcommacommand[\m_page_asked_paper]\page_paper_identify_target
\ifx\currentlayouttarget\empty
\let\currentlayouttarget\currentpage
\fi
\global\let\papersize\currentlayouttarget
+ \page_paper_reset_paper
\processcommacommand[\m_page_asked_paper]\page_paper_handle_page_option
\global\paperwidth \layouttargetparameter\c!width \relax
\global\paperheight\layouttargetparameter\c!height\relax
@@ -550,8 +559,10 @@
%
\page_paper_set_offsets
% locate paper target
+ \page_paper_reset_print
\processcommacommand[\m_page_asked_print]\page_paper_identify_target
\global\let\printpapersize\currentlayouttarget
+ \page_paper_reset_print
\processcommacommand[\m_page_asked_print]\page_paper_handle_print_option
\global\printpaperwidth \layouttargetparameter\c!width \relax
\global\printpaperheight\layouttargetparameter\c!height\relax
diff --git a/tex/context/base/mkiv/page-mix.lua b/tex/context/base/mkiv/page-mix.lua
index 0d8e64cea..b0e1783e4 100644
--- a/tex/context/base/mkiv/page-mix.lua
+++ b/tex/context/base/mkiv/page-mix.lua
@@ -121,7 +121,7 @@ local function collectinserts(result,nxt,nxtid)
if nxtid == insert_code then
i = i + 1
result.i = i
- inserttotal = inserttotal + getheight(nxt) -- height includes depth
+ inserttotal = inserttotal + getheight(nxt) -- height includes depth (hm, still? needs checking)
local s = getsubtype(nxt)
local c = inserts[s]
if trace_detail then
@@ -265,6 +265,7 @@ local function preparesplit(specification) -- a rather large function
local height = 0
local depth = 0
local skip = 0
+ local handlenotes = specification.notes or false
local splitmethod = specification.splitmethod or false
if splitmethod == v_none then
splitmethod = false
@@ -628,7 +629,7 @@ local function preparesplit(specification) -- a rather large function
if trace_state then
report_state("%-8s > column %s, content: %s","line (1)",column,listtoutf(getlist(current),true,true))
end
- if more then
+ if more and handlenotes then
nxt, inserts, insertskips, nextskips, inserttotal = collectinserts(result,nxt,nxtid)
end
local state, skipped = checked(advance+inserttotal+insertskips,more and "line (2)" or "line only",lastlocked)
@@ -751,7 +752,7 @@ local function preparesplit(specification) -- a rather large function
specification.overflow = overflow
specification.discarded = discarded
- setlist(getbox(specification.box),nil)
+ setlist(getbox(specification.box))
return specification
end
@@ -774,9 +775,9 @@ local function finalize(result)
end
local t = r.tail
if t then
- setnext(t,nil)
+ setnext(t)
else
- setnext(h,nil)
+ setnext(h)
r.tail = h
end
for c, list in next, r.inserts do
@@ -784,11 +785,13 @@ local function finalize(result)
for i=1,#list do
local l = list[i]
local h = new_hlist()
+ local g = getlist(l)
t[i] = h
- setlist(h,getlist(l))
- local wd, ht, dp = getwhd(l)
- -- here ht is still ht + dp !
- setwhd(h,getwidth(h),ht,dp)
+ setlist(h,g)
+ local ht = getheight(l)
+ local dp = getdepth(l)
+ local wd = getwidth(g)
+ setwhd(h,wd,ht,dp)
setlist(l)
end
setprev(t[1]) -- needs checking
@@ -908,7 +911,6 @@ local function getsplit(result,n)
return s
end
end
-
if grid then
-- print(n,result.maxtotal,r.total,r.extra)
if isglobal then
@@ -960,13 +962,11 @@ local function getsplit(result,n)
end
for c, list in next, r.inserts do
-
local l = concatnodes(list)
for i=1,#list-1 do
setdepth(list[i],0)
end
local b = vpack(l) -- multiple arguments, todo: fastvpack
-
-- setbox("global",c,b)
setbox(c,b)
r.inserts[c] = nil
@@ -1035,6 +1035,7 @@ implement {
{ "alternative" },
{ "internalgrid" },
{ "grid", "boolean" },
+ { "notes", "boolean" },
}
}
}
diff --git a/tex/context/base/mkiv/page-mix.mkiv b/tex/context/base/mkiv/page-mix.mkiv
index 326d01994..9fa80275a 100644
--- a/tex/context/base/mkiv/page-mix.mkiv
+++ b/tex/context/base/mkiv/page-mix.mkiv
@@ -84,6 +84,7 @@
\c!step=.25\lineheight, % needs some experimenting
%\c!splitmethod=\v!fixed, % will be default
\c!direction=\v!normal, % new (also todo in the new columnsets)
+ \c!notes=\v!yes,
\c!method=\ifinner\s!box\else\s!otr\fi] % automatic as suggested by WS
\let\startmixedcolumns\relax % defined later
@@ -123,6 +124,8 @@
\setnewconstant\c_page_mix_routine_balance \plusthree
\setnewconstant\c_page_mix_routine_error \plusfour
+\newconditional\c_page_mix_process_notes
+
%D The main environment is called as follows:
%D
%D \starttyping
@@ -183,7 +186,8 @@
\c!splitmethod=\v!none,
\c!grid=\v!tolerant,
\c!internalgrid=\v!halfline, % new, we may still revert to \v!line
- \c!balance=\v!yes]
+ \c!balance=\v!yes,
+ \c!notes=\v!no] % kind of hidden
% better
@@ -193,6 +197,17 @@
\c!grid=\v!yes,
\c!internalgrid=\v!line]
+% even better:
+
+\setupitemgroup
+ [\c!grid=\v!tolerant:10] % 10 pct tolerance in columns snapping
+
+\setupmixedcolumns
+ [\s!itemgroupcolumns]
+ [\c!grid=\itemgroupparameter\c!grid]
+
+% the fast hooks:
+
\unexpanded\def\strc_itemgroups_start_columns
{\startmixedcolumns[\s!itemgroupcolumns]} % we could have a fast one
@@ -464,18 +479,29 @@
\let\page_mix_fast_columns_stop\relax
+\newtoks\t_page_mix_at_the_end
+
+\def\page_mix_finalize_columns
+ {\ifconditional\c_page_mix_process_notes \else
+ \global\t_page_mix_at_the_end{\stoppostponingnotes}%
+ \fi}
+
\unexpanded\def\page_mix_columns_stop_yes
- {\begincsname\??mixedcolumnsstop \currentmixedcolumnsmethod\endcsname % no \relax
+ {\begincsname\??mixedcolumnsstop\currentmixedcolumnsmethod\endcsname % no \relax
+ \page_mix_finalize_columns
\endgroup
\begincsname\??mixedcolumnsafter\currentmixedcolumnsmethod\endcsname\relax
\mixedcolumnsparameter\c!after\relax
\popmacro\currentmixedcolumnsmethod
- \popmacro\currentmixedcolumns}
+ \popmacro\currentmixedcolumns
+ \the\t_page_mix_at_the_end\global\t_page_mix_at_the_end\emptytoks}
\unexpanded\def\page_mix_columns_stop_nop
- {\endgroup
+ {\page_mix_finalize_columns
+ \endgroup
\popmacro\currentmixedcolumnsmethod
- \popmacro\currentmixedcolumns}
+ \popmacro\currentmixedcolumns
+ \the\t_page_mix_at_the_end\global\t_page_mix_at_the_end\emptytoks}
% \unexpanded\def\page_mix_columns_stop_yes
% {\begincsname\??mixedcolumnsstop \currentmixedcolumnsmethod\endcsname % no \relax
@@ -528,6 +554,11 @@
\leftskip \zeropoint
\rightskip\zeropoint
%
+ \doifelse{\mixedcolumnsparameter\c!notes}\v!yes\settrue\setfalse\c_page_mix_process_notes
+ \ifconditional\c_page_mix_process_notes \else
+ \startpostponingnotes
+ \fi
+ %
\d_page_mix_threshold\zeropoint
%
\d_page_mix_column_width\dimexpr(\d_page_mix_max_width-\d_page_mix_distance*\numexpr(\c_page_mix_n_of_columns-\plusone)\relax)/\c_page_mix_n_of_columns\relax
@@ -649,7 +680,8 @@
balance {#1}%
alternative {\mixedcolumnsparameter\c!alternative}%
internalgrid {\mixedcolumnsparameter\c!internalgrid}%
- grid \ifgridsnapping true\else false\fi
+ grid \ifgridsnapping tru\else fals\fi e %
+ notes \ifconditional\c_page_mix_process_notes tru\else fals\fi e %
\relax
\deadcycles\zerocount}
@@ -725,7 +757,9 @@
\hskip-\d_page_mix_column_width
\vbox \bgroup
\hsize\d_page_mix_column_width
- \placenoteinserts
+ \ifconditional\c_page_mix_process_notes
+ \placenoteinserts
+ \fi
\egroup
\hss
\egroup}
diff --git a/tex/context/base/mkiv/page-mrk.mkiv b/tex/context/base/mkiv/page-mrk.mkiv
index 43116e84d..69746ea89 100644
--- a/tex/context/base/mkiv/page-mrk.mkiv
+++ b/tex/context/base/mkiv/page-mrk.mkiv
@@ -13,13 +13,19 @@
\writestatus{loading}{ConTeXt Page Macros / Cutmarks and Colorbars}
-%D This module depends on \METAPOST.
-
\unprotect
-% \def\pagecutmarksymbol {\the\realpageno}
-% \let\pagecutmarktoptext \empty
-% \let\pagecutmarkbottomtext \empty
+%D This module implements curmarks and depends on \METAPOST.
+%D
+%D \starttyping
+%D \setuplayout[marking=on,location=middle]
+%D \setuplayout[marking=page,location=middle]
+%D \setuplayout[marking=empty,location=middle]
+%D \setuplayout[marking={color,page},location=middle]
+%D \setuplayout[marking={one,page},location=middle]
+%D \setuplayout[marking={two,page},location=middle]
+%D \setuplayout[marking={four,page},location=middle]
+%D \stoptyping
\def\pagecutmarklength {5mm}
\def\pagecutmarkoffset {3mm} % slightly larger than before, and now a fixed size
@@ -49,7 +55,8 @@
\startuniqueMPgraphic{print:lines}{w,h,l,o,x,y}
loadmodule "crop" ;
- page_marks_add_lines(\MPvar w,\MPvar h,\MPvar l,\MPvar o,\MPvar x,\MPvar y) ;
+ page_marks_add_lines(\MPvar w,\MPvar h,\MPvar l,\MPvar o,\MPvar x,\MPvar y,
+ \ifconditional\c_page_marks_add_page_lines tru\else fals\fi e) ;
\stopuniqueMPgraphic
\startuseMPgraphic{print:number}{w,h,l,o,n}
@@ -112,9 +119,7 @@
\scratchheight\ht#1%
\scratchdepth \dp#1%
\box#1\relax
- \ifconditional\c_page_marks_add_page_lines
- \page_marks_add_lines
- \fi
+ \page_marks_add_lines
\egroup}
\def\page_marks_add_more_indeed#1%
@@ -163,28 +168,29 @@
% \let\pagecutmarkbottomtext\extrapagecutmarkbottomtext}
\installpagecutmark\v!on
- {\settrue\c_page_marks_add_page_lines
+ {%settrue\c_page_marks_add_page_lines
\settrue\c_page_marks_add_more_lines
\settrue\c_page_marks_add_more_number}
-\installpagecutmark\v!page % todo
- {\settrue\c_page_marks_add_more_lines
+\installpagecutmark\v!page
+ {\settrue\c_page_marks_add_page_lines
+ \settrue\c_page_marks_add_more_lines
\settrue\c_page_marks_add_more_number}
\installpagecutmark\v!empty
- {\settrue\c_page_marks_add_page_lines
+ {%settrue\c_page_marks_add_page_lines
\settrue\c_page_marks_add_more_lines}
\installpagecutmark\v!color
- {\settrue\c_page_marks_add_page_lines
+ {%settrue\c_page_marks_add_page_lines
\settrue\c_page_marks_add_more_lines
\settrue\c_page_marks_add_more_color
\settrue\c_page_marks_add_more_marking
\settrue\c_page_marks_add_more_number}
-\installpagecutmark\v!one {\global\c_page_marks_max\plusone}
-\installpagecutmark\v!two {\global\c_page_marks_max\plustwo}
-\installpagecutmark\v!four{\global\c_page_marks_max\plusfour}
+\installpagecutmark\v!one {\global\c_page_marks_max\plusone} % first page
+\installpagecutmark\v!two {\global\c_page_marks_max\plustwo} % first two pages
+\installpagecutmark\v!four{\global\c_page_marks_max\plusfour} % first four pages
\unexpanded\def\page_marks_set#1%
{\begincsname\??layoutmarking#1\endcsname}
diff --git a/tex/context/base/mkiv/page-otr.mkvi b/tex/context/base/mkiv/page-otr.mkvi
index 1fe928c36..45dc86482 100644
--- a/tex/context/base/mkiv/page-otr.mkvi
+++ b/tex/context/base/mkiv/page-otr.mkvi
@@ -192,7 +192,7 @@
\installoutputroutine\synchronizeoutput % use \triggerpagebuilder instead
{\ifvoid\normalpagebox\else
\unvbox\normalpagebox
- \pagediscards % does more harm than good .. needs thinking
+ % not \pagediscards as it does more harm than good
\fi}
\installoutputroutine\discardpage
diff --git a/tex/context/base/mkiv/page-sid.mkiv b/tex/context/base/mkiv/page-sid.mkiv
index 75f7725c3..e8f2b03a4 100644
--- a/tex/context/base/mkiv/page-sid.mkiv
+++ b/tex/context/base/mkiv/page-sid.mkiv
@@ -63,6 +63,8 @@
\newdimen \d_page_sides_bottomskip
\newdimen \d_page_sides_downshift
\newdimen \d_page_sides_pagetotal
+\newdimen \d_page_sides_topoffset
+\newdimen \d_page_sides_bottomoffset
\setnewconstant \c_page_sides_method \plusone % 0=raw 1=safe (.99) 2=tight (-1pt)
\setnewconstant \c_page_sides_align \zerocount
@@ -212,7 +214,8 @@
{\global\d_page_sides_vsize\d_page_sides_vsize_reset
% also here if used at all \global\holdinginserts\zerocount
\global\setfalse\c_page_sides_short
- \global\setfalse\c_page_sides_flag}
+ \global\setfalse\c_page_sides_flag
+ \global\c_page_sides_checks_done\zerocount}
\unexpanded\def\doifelsesidefloat
{\par
@@ -282,37 +285,50 @@
\fi}%
\endgroup}
-\def\page_sides_flush_floats_after_none
- {\ifdim\parskip>\zeropoint % why this test ?
- \ifdim\d_page_sides_bottomskip>\parskip
- \blank[\v!nowhite,\rootfloatparameter\c!sidespaceafter]%
- \fi
- \else
- \blank[\rootfloatparameter\c!sidespaceafter]%
- \fi}
-
-\def\page_sides_flush_floats_blank#1% we need to deal with the distance
- {\ifdim\d_page_sides_bottomskip>\d_page_sides_topskip
- \blank[%
- \ifnum#1>\zerocount\v!nowhite,\fi
- \ifdim\d_page_sides_topskip >\zeropoint-\rootfloatparameter\c!sidespacebefore,\fi % the next one
- \ifdim\d_page_sides_bottomskip>\zeropoint \rootfloatparameter\c!sidespaceafter \fi
- ]%
- \else\ifdim\d_page_sides_bottomskip<\d_page_sides_topskip
- \blank[%
- \ifnum#1>\zerocount\v!nowhite,\fi
- \ifdim\d_page_sides_bottomskip>\zeropoint -\rootfloatparameter\c!sidespaceafter ,\fi
- \ifdim\d_page_sides_topskip >\zeropoint \rootfloatparameter\c!sidespacebefore \fi
- ]%
- \fi\fi}
+\def\page_sides_flush_floats_after_none % we force a flush
+ {\edef\tempstring{%
+ \ifdim\d_page_sides_bottomskip>\zeropoint
+ \ifdim\parskip>\zeropoint % why this test ?
+ \ifdim\d_page_sides_bottomskip>\parskip
+ \v!nowhite,\rootfloatparameter\c!sidespaceafter
+ \fi
+ \else
+ \rootfloatparameter\c!sidespaceafter
+ \fi
+ \fi}%
+ \ifx\tempstring\empty\else\ifx\tempstring\v!none\else
+ \blank[\tempstring]%
+ \fi\fi
+ \page_sides_inject_after}
+
+\def\page_sides_flush_floats_blank#1% we have two successive ones
+ {\edef\tempstring{%
+ \ifx#1\empty\else#1,\fi
+ \ifdim\d_page_sides_bottomskip>\d_page_sides_topskip
+ \ifdim\d_page_sides_topskip >\zeropoint-\rootfloatparameter\c!sidespacebefore,\fi % the next one
+ \ifdim\d_page_sides_bottomskip>\zeropoint \rootfloatparameter\c!sidespaceafter ,\fi
+ \else\ifdim\d_page_sides_bottomskip<\d_page_sides_topskip
+ \ifdim\d_page_sides_bottomskip>\zeropoint -\rootfloatparameter\c!sidespaceafter ,\fi
+ \ifdim\d_page_sides_topskip >\zeropoint \rootfloatparameter\c!sidespacebefore,\fi
+ \else % equal
+ \rootfloatparameter\c!sidespacebefore % inbetween
+ \fi\fi}%
+ \ifx\tempstring\empty\else\ifx\tempstring\v!none\else
+ \blank[\tempstring]%
+ \fi\fi
+ \page_sides_inject_after}
-\def\page_sides_flush_floats_after_next
+\def\page_sides_flush_floats_after_next % we have two successive ones
{\ifdim\parskip>\zeropoint % why this test ?
\ifdim\d_page_sides_bottomskip>\parskip
- \page_sides_flush_floats_blank\plusone
- \fi
+ \page_sides_flush_floats_blank\v!nowhite
+ \else\ifdim\d_page_sides_topskip>\parskip
+ \page_sides_flush_floats_blank\v!nowhite
+ \else
+ % use parskip
+ \fi\fi
\else
- \page_sides_flush_floats_blank\zerocount
+ \page_sides_flush_floats_blank\empty
\fi}
\def\page_sides_check_floats_after_par
@@ -647,12 +663,25 @@
% % but it seems to work
% \endgroup}
+\def\page_sides_inject_before
+ {\edef\tempstring{\rootfloatparameter\c!spacebeforeside}%
+ \ifx\tempstring\empty\else\ifx\tempstring\v!none\else
+ \blank[\tempstring]%
+ \fi\fi}
+
+\def\page_sides_inject_after
+ {\edef\tempstring{\rootfloatparameter\c!spaceafterside}%
+ \ifx\tempstring\empty\else\ifx\tempstring\v!none\else
+ \blank[\tempstring]%
+ \fi\fi}
+
\def\page_sides_prepare_space
{%\fakenextstrutline % does more bad than good at page crossing
\inhibitblank} % hm, why here .. gets obscured anyway
\def\page_sides_handle_float#1% grid (4) is rather experimental
- {\page_sides_prepare_space
+ {\page_sides_inject_before
+ \page_sides_prepare_space
\page_sides_apply_horizontal_shift
\page_sides_check_previous_float
\page_sides_inject_dummy_lines
@@ -820,7 +849,7 @@
\fi
\kern-\privatescratchcounter\baselineskip
\penalty\zerocount
- \triggerpagebuilder
+ \triggerpagebuilder % the penalty already does that
\endgroup}
\def\adjustsidefloatdisplaylines % public, will change
diff --git a/tex/context/base/mkiv/publ-ini.lua b/tex/context/base/mkiv/publ-ini.lua
index 99a37e8b9..038a15d5a 100644
--- a/tex/context/base/mkiv/publ-ini.lua
+++ b/tex/context/base/mkiv/publ-ini.lua
@@ -362,7 +362,7 @@ local listtolist = nil
do
- local initialize = nil
+ local initialize = nil -- we delay
initialize = function(t)
usedentries = allocate { }
@@ -370,77 +370,75 @@ do
listtocite = allocate { }
listtolist = allocate { }
local names = { }
- local internals = structures.references.internals
local p_collect = (C(R("09")^1) * Carg(1) / function(s,entry) listtocite[tonumber(s)] = entry end + P(1))^0
local nofunique = 0
local nofreused = 0
- for i=1,#internals do
- local entry = internals[i]
- if entry then
- local metadata = entry.metadata
- if metadata then
- local kind = metadata.kind
- if kind == "full" then
- -- reference (in list)
- local userdata = entry.userdata
- if userdata then
- local tag = userdata.btxref
- if tag then
- local set = userdata.btxset or v_default
- local s = usedentries[set]
- if s then
- local u = s[tag]
- if u then
- u[#u+1] = entry
- else
- s[tag] = { entry }
- end
- nofreused = nofreused + 1
+ -- local internals = references.sortedinternals -- todo: when we need it more than once
+ -- for i=1,#internals do -- but currently we don't do this when not
+ -- local entry = internals[i] -- needed anyway so ...
+ local internals = structures.references.internals
+ for i, entry in sortedhash(internals) do
+ local metadata = entry.metadata
+ if metadata then
+ local kind = metadata.kind
+ if kind == "full" then
+ -- reference (in list)
+ local userdata = entry.userdata
+ if userdata then
+ local tag = userdata.btxref
+ if tag then
+ local set = userdata.btxset or v_default
+ local s = usedentries[set]
+ if s then
+ local u = s[tag]
+ if u then
+ u[#u+1] = entry
else
- usedentries[set] = { [tag] = { entry } }
- nofunique = nofunique + 1
+ s[tag] = { entry }
end
- -- alternative: collect prev in group
- local int = tonumber(userdata.btxint)
- if int then
- listtocite[int] = entry
- end
- local detail = datasets[set].details[tag]
--- todo: these have to be pluggable
- if detail then
- local author = detail.author
- if author then
- for i=1,#author do
- local a = author[i]
- local s = a.surnames
- if s then
- local c = concat(s,"+")
- local n = names[c]
- if n then
- n[#n+1] = a
- break
- else
- names[c] = { a }
- end
+ nofreused = nofreused + 1
+ else
+ usedentries[set] = { [tag] = { entry } }
+ nofunique = nofunique + 1
+ end
+ -- alternative: collect prev in group
+ local int = tonumber(userdata.btxint)
+ if int then
+ listtocite[int] = entry
+ end
+ local detail = datasets[set].details[tag]
+ -- todo: these have to be pluggable
+ if detail then
+ local author = detail.author
+ if author then
+ for i=1,#author do
+ local a = author[i]
+ local s = a.surnames
+ if s then
+ local c = concat(s,"+")
+ local n = names[c]
+ if n then
+ n[#n+1] = a
+ break
+ else
+ names[c] = { a }
end
end
end
end
end
end
- elseif kind == "btx" or kind == "userdata" then -- will go: kind == "userdata"
- -- list entry (each cite)
- local userdata = entry.userdata
- if userdata then
- local int = tonumber(userdata.btxint)
- if int then
- citetolist[int] = entry
- end
+ end
+ elseif kind == "btx" then
+ -- list entry (each cite)
+ local userdata = entry.userdata
+ if userdata then
+ local int = tonumber(userdata.btxint)
+ if int then
+ citetolist[int] = entry
end
end
end
- else
- -- weird
end
end
for k, v in sortedhash(names) do
@@ -459,7 +457,7 @@ do
end
end
if trace_detail then
- report("%s unique bibentries: %s reused entries",nofunique,nofreused)
+ report("%s unique references, %s reused entries",nofunique,nofreused)
end
initialize = nil
end
@@ -500,6 +498,7 @@ local findallused do
local todo = { }
local okay = { } -- only if mark
local allused = usedentries[dataset] or { }
+ -- local allused = usedentries[dataset] -- only test
local luadata = current.luadata
local details = current.details
local ordered = current.ordered
@@ -604,39 +603,40 @@ local findallused do
end
end
end
- else
- if find then
- tags = { }
- for i=1,#ordered do
- local entry = ordered[i]
- if find(entry) then
- local tag = entry.tag
- local parent = details[tag].parent
- if parent then
- tag = parent
- end
- tags[#tags+1] = tag
- todo[tag] = true
- end
- end
- if #tags == 0 and not reported[reference] then
- tags[1] = reference
- reported[reference] = true
- end
- else
- for i=1,#tags do
- local tag = tags[i]
+ elseif find then
+ tags = { }
+ for i=1,#ordered do
+ local entry = ordered[i]
+ if find(entry) then
+ local tag = entry.tag
local parent = details[tag].parent
if parent then
tag = parent
- tags[i] = tag
- end
- if luadata[tag] then
- todo[tag] = true
- elseif not reported[tag] then
- reported[tag] = true
- report_cite("non-existent entry %a in %a",tag,dataset)
end
+ tags[#tags+1] = tag
+ todo[tag] = true
+ -- okay[#okay+1] = entry -- only test
+ end
+ end
+ if #tags == 0 and not reported[reference] then
+ tags[1] = reference
+ reported[reference] = true
+ end
+ else
+ for i=1,#tags do
+ local tag = tags[i]
+ local parent = details[tag].parent
+ if parent then
+ tag = parent
+ tags[i] = tag
+ end
+ local entry = luadata[tag]
+ if entry then
+ todo[tag] = true
+ -- okay[#okay+1] = entry -- only test
+ elseif not reported[tag] then
+ reported[tag] = true
+ report_cite("non-existent entry %a in %a",tag,dataset)
end
end
end
@@ -2645,6 +2645,7 @@ do
local found, todo, list = findallused(dataset,reference,internal,method == v_text or method == v_always) -- also when not in list
--
if not found or #found == 0 then
+-- if not list or #list == 0 then
report("no entry %a found in dataset %a",reference,dataset)
elseif not setup then
report("invalid reference for %a",reference)
diff --git a/tex/context/base/mkiv/scrn-wid.lua b/tex/context/base/mkiv/scrn-wid.lua
index 2ed5b52eb..636d547da 100644
--- a/tex/context/base/mkiv/scrn-wid.lua
+++ b/tex/context/base/mkiv/scrn-wid.lua
@@ -21,6 +21,8 @@ if not modules then modules = { } end modules ['scrn-wid'] = {
-- sane person will create media rich pdf's as long as it's that unpredictable. Just
-- look at the specification and viewer preferences and decide.
+local next = next
+
interactions = interactions or { }
local interactions = interactions
diff --git a/tex/context/base/mkiv/scrp-ini.lua b/tex/context/base/mkiv/scrp-ini.lua
index a91a93970..d5cad643f 100644
--- a/tex/context/base/mkiv/scrp-ini.lua
+++ b/tex/context/base/mkiv/scrp-ini.lua
@@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['scrp-ini'] = {
-- We need to rewrite this a bit ... rather old code ... will be done when japanese
-- is finished.
-local tonumber = tonumber
+local tonumber, next = tonumber, next
local trace_analyzing = false trackers.register("scripts.analyzing", function(v) trace_analyzing = v end)
local trace_injections = false trackers.register("scripts.injections", function(v) trace_injections = v end)
diff --git a/tex/context/base/mkiv/spac-hor.mkiv b/tex/context/base/mkiv/spac-hor.mkiv
index ba1b833ce..6c60be868 100644
--- a/tex/context/base/mkiv/spac-hor.mkiv
+++ b/tex/context/base/mkiv/spac-hor.mkiv
@@ -381,9 +381,9 @@
%D \macros
%D {frenchspacing,nonfrenchspacing}
%D
-%D Somehow \type{\frenchspacing} can lead to hyphenation between
-%D dashes so we now have \type {\newfrenchspacing} (moved from
-%D \type {syst-chr}).
+%D Somehow \type{\frenchspacing} can lead to hyphenation between dashes so we now
+%D have \type {\newfrenchspacing} (moved from \type {syst-chr}). Maybe it's not
+%D needed any more.
%D Hm ... todo:
diff --git a/tex/context/base/mkiv/spac-ver.mkiv b/tex/context/base/mkiv/spac-ver.mkiv
index f3c12bed4..c529322e1 100644
--- a/tex/context/base/mkiv/spac-ver.mkiv
+++ b/tex/context/base/mkiv/spac-ver.mkiv
@@ -1548,6 +1548,17 @@
{%\gridsnappingtrue
\begincsname\??gridsnappers#1\endcsname}
+% maybe:
+%
+% \def\spac_grids_snap_value_set#1%
+% {%\gridsnappingtrue
+% \ifcsname\??gridsnappers#1\endcsname
+% \lastnamedcs
+% \else
+% \definegridsnapping[#1][#1]%
+% \begincsname\??gridsnappers#1\endcsname
+% \fi}
+
\def\spac_grids_snap_value_auto#1%
{\ifcsname\??gridsnappers#1\endcsname
\lastnamedcs
@@ -1578,35 +1589,41 @@
% min centers a box rounded downwards
% max centers a box rounded upwards
-%D We're not downward compatible with \MKII !
-
-\definegridsnapping[\v!normal] [\v!maxheight,\v!maxdepth,\v!strut]
-\definegridsnapping[\v!standard] [\v!maxheight,\v!maxdepth,\v!strut]
-\definegridsnapping[\v!yes] [\v!maxheight,\v!maxdepth,\v!strut]
-
-\definegridsnapping[\v!strict] [\v!maxdepth:0.8,\v!maxheight:0.8,\v!strut]
-\definegridsnapping[\v!tolerant] [\v!maxdepth:1.2,\v!maxheight:1.2,\v!strut]
-
-\definegridsnapping[\v!top] [\v!minheight,\v!maxdepth,\v!strut]
-\definegridsnapping[\v!bottom] [\v!maxheight,\v!mindepth,\v!strut]
-\definegridsnapping[\v!both] [\v!minheight,\v!mindepth,\v!strut]
-
-\definegridsnapping[\v!broad] [\v!maxheight,\v!maxdepth,\v!strut,0.8] % maybe 0.85
-\definegridsnapping[\v!fit] [\v!maxheight,\v!maxdepth,\v!strut,1.2] % tight 0.15
-
-\definegridsnapping[\v!first] [\v!first]
-\definegridsnapping[\v!last] [\v!last]
-\definegridsnapping[\v!high] [\v!minheight,\v!maxdepth,\v!none]
-\definegridsnapping[\v!one] [\v!minheight,\v!mindepth]
-\definegridsnapping[\v!low] [\v!maxheight,\v!mindepth,\v!none]
-\definegridsnapping[\v!none] [\v!none]
-\definegridsnapping[\v!line] [\v!line]
-\definegridsnapping[\v!strut] [\v!strut]
-\definegridsnapping[\v!box] [\v!box]
-\definegridsnapping[\v!min] [\v!min]
-\definegridsnapping[\v!max] [\v!max]
-
-\definegridsnapping[\v!middle] [\v!maxheight,\v!maxdepth] % used in placement
+%D We're not downward compatible with \MKII ! Not yet in interface file:
+
+\definegridsnapping[\v!normal] [\v!maxheight,\v!maxdepth,\v!strut]
+\definegridsnapping[\v!standard] [\v!maxheight,\v!maxdepth,\v!strut]
+\definegridsnapping[\v!yes] [\v!maxheight,\v!maxdepth,\v!strut]
+
+\definegridsnapping[\v!strict] [\v!maxdepth:0.8,\v!maxheight:0.8,\v!strut]
+\definegridsnapping[\v!tolerant] [\v!maxdepth:1.2,\v!maxheight:1.2,\v!strut]
+\definegridsnapping[\v!verytolerant] [\v!maxdepth:1.4,\v!maxheight:1.4,\v!strut]
+
+\definegridsnapping[\v!tolerant:10] [\v!maxdepth:1.1,\v!maxheight:1.1,\v!strut] % 10 pct tolerance
+\definegridsnapping[\v!tolerant:20] [\v!maxdepth:1.2,\v!maxheight:1.2,\v!strut] % 20 pct tolerance
+\definegridsnapping[\v!tolerant:30] [\v!maxdepth:1.3,\v!maxheight:1.3,\v!strut] % 30 pct tolerance
+\definegridsnapping[\v!tolerant:40] [\v!maxdepth:1.4,\v!maxheight:1.4,\v!strut] % 40 pct tolerance
+
+\definegridsnapping[\v!top] [\v!minheight,\v!maxdepth,\v!strut]
+\definegridsnapping[\v!bottom] [\v!maxheight,\v!mindepth,\v!strut]
+\definegridsnapping[\v!both] [\v!minheight,\v!mindepth,\v!strut]
+
+\definegridsnapping[\v!broad] [\v!maxheight,\v!maxdepth,\v!strut,0.8] % maybe 0.85
+\definegridsnapping[\v!fit] [\v!maxheight,\v!maxdepth,\v!strut,1.2] % tight 0.15
+
+\definegridsnapping[\v!first] [\v!first]
+\definegridsnapping[\v!last] [\v!last]
+\definegridsnapping[\v!high] [\v!minheight,\v!maxdepth,\v!none]
+\definegridsnapping[\v!one] [\v!minheight,\v!mindepth]
+\definegridsnapping[\v!low] [\v!maxheight,\v!mindepth,\v!none]
+\definegridsnapping[\v!none] [\v!none]
+\definegridsnapping[\v!line] [\v!line]
+\definegridsnapping[\v!strut] [\v!strut]
+\definegridsnapping[\v!box] [\v!box]
+\definegridsnapping[\v!min] [\v!min]
+\definegridsnapping[\v!max] [\v!max]
+
+\definegridsnapping[\v!middle] [\v!maxheight,\v!maxdepth] % used in placement
\definegridsnapping[\v!math] [\v!maxdepth:1.05,\v!maxheight:1.05,\v!strut] % experimental, maybe 1.1
\definegridsnapping[\v!math:\v!line] [\v!math,\v!line,\v!split]
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index de25dd503..7818625cd 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index 8b8060c3f..afcb37ae4 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/strc-blk.lua b/tex/context/base/mkiv/strc-blk.lua
index 0ababcfc0..492abc768 100644
--- a/tex/context/base/mkiv/strc-blk.lua
+++ b/tex/context/base/mkiv/strc-blk.lua
@@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['strc-blk'] = {
-- this one runs on top of buffers and structure
-local type = type
+local type, next = type, next
local find, format, validstring = string.find, string.format, string.valid
local settings_to_set, settings_to_array = utilities.parsers.settings_to_set, utilities.parsers.settings_to_array
local allocate = utilities.storage.allocate
diff --git a/tex/context/base/mkiv/strc-enu.mkvi b/tex/context/base/mkiv/strc-enu.mkvi
index 8eff706bb..4680a3981 100644
--- a/tex/context/base/mkiv/strc-enu.mkvi
+++ b/tex/context/base/mkiv/strc-enu.mkvi
@@ -88,7 +88,7 @@
%\c!headcolor=,
%\c!titlecolor=,
\c!width=8\emwidth,
- \c!distance=\zeropoint,
+ %\c!distance=\zeropoint,
\c!distance=\emwidth,
\c!titledistance=.5\emwidth,
%\c!hang=,
@@ -111,7 +111,6 @@
\c!expansion=\v!no,
%\c!xmlsetup=,
%\s!catcodes=,
- %
\c!way=\v!by\v!text,
\c!prefix=\v!no,
\c!prefixconnector=.,
diff --git a/tex/context/base/mkiv/strc-flt.mkvi b/tex/context/base/mkiv/strc-flt.mkvi
index 45d395f21..4f7d93645 100644
--- a/tex/context/base/mkiv/strc-flt.mkvi
+++ b/tex/context/base/mkiv/strc-flt.mkvi
@@ -141,6 +141,8 @@
\c!spaceafter=\v!big,
\c!sidespacebefore=\rootfloatparameter\c!spacebefore,
\c!sidespaceafter=\rootfloatparameter\c!spaceafter,
+ \c!spacebeforeside=, % extra, not part of, can be used to add whitespace before text
+ \c!spaceafterside=, % idem
\c!sidealign=\v!normal,
\c!textmethod=\ifgridsnapping2\else0\fi, % 0=raw 1=safe (.99pg) 2=tight (-1pt) % THIS WILL CHANGE
\c!sidemethod=\ifgridsnapping2\else1\fi, % 0=raw 1=safe (.99pg) 2=tight (-1pt) % THIS WILL CHANGE
@@ -737,6 +739,25 @@
% nicer is a bunch of states and one loop that sets those states
+\newdimen\d_strc_floats_margin
+\newdimen\d_strc_floats_top
+\newdimen\d_strc_floats_bottom
+%newdimen\d_strc_floats_top_side
+%newdimen\d_strc_floats_bottom_side
+
+\def\strc_floats_calculate_skip#target#skip%
+ {\begingroup
+ \edef\askedfloatskip{\rootfloatparameter#skip}%
+ \ifx\askedfloatskip\empty
+ \global#target\zeropoint
+ \else\ifx\askedfloatskip\v!none
+ \global#target\zeropoint
+ \else
+ \setbox\scratchbox\vbox{\whitespace\blank[\askedfloatskip]}% todo: move whitespace inside blank
+ \global#target\ht\scratchbox
+ \fi\fi
+ \endgroup}
+
\def\strc_floats_analyze_variables_two
{\ifinsidecolumns
\global\setfalse\c_strc_floats_par_float
@@ -745,13 +766,36 @@
{\global\settrue \c_strc_floats_par_float}%
{\global\setfalse\c_strc_floats_par_float}%
\fi
- \global\d_page_sides_shift \zeropoint
- \global\d_page_sides_maximum \zeropoint
- \global\c_page_sides_method \floatparameter\c!sidemethod
- \global\c_page_one_float_method \floatparameter\c!textmethod
- \global\c_page_sides_align \zerocount
- \global\c_strc_floats_rotation \zerocount
- \strc_floats_calculate_skips
+ % variable initializations
+ \global\d_page_sides_shift \zeropoint
+ \global\d_page_sides_maximum \zeropoint
+ \global\c_page_sides_align \zerocount
+ \global\c_strc_floats_rotation \zerocount
+ \global\d_strc_floats_margin \rootfloatparameter\c!margin
+ \global\d_page_sides_leftshift \floatparameter \c!leftmargindistance
+ \global\d_page_sides_rightshift \floatparameter \c!rightmargindistance
+ \global\d_page_sides_topoffset \floatparameter \c!topoffset
+ \global\d_page_sides_bottomoffset\floatparameter \c!bottomoffset
+ \global\c_page_sides_method \floatparameter \c!sidemethod
+ \global\c_page_one_float_method \floatparameter \c!textmethod
+ \global\c_page_floats_n_of_top \rootfloatparameter\c!ntop
+ \global\c_page_floats_n_of_bottom\rootfloatparameter\c!nbottom
+ \ifconditional\c_strc_floats_par_float
+ \global\d_strc_floats_top \zeropoint
+ \global\d_strc_floats_bottom \zeropoint
+ %\strc_floats_calculate_skip\d_strc_floats_top_side \c!spacebeforeside
+ %\strc_floats_calculate_skip\d_strc_floats_bottom_side\c!spaceafterside
+ \strc_floats_calculate_skip\d_page_sides_topskip \c!sidespacebefore
+ \strc_floats_calculate_skip\d_page_sides_bottomskip \c!sidespaceafter
+ \else
+ \global\d_page_sides_topskip \zeropoint
+ \global\d_page_sides_bottomskip \zeropoint
+ %\global\d_strc_floats_top_side \zeropoint
+ %\global\d_strc_floats_bottom_side\zeropoint
+ \strc_floats_calculate_skip\d_strc_floats_top \c!spacebefore
+ \strc_floats_calculate_skip\d_strc_floats_bottom\c!spaceafter
+ \fi
+ % keyword handling
\ifconditional\c_strc_floats_par_float
\processaction
[\floatparameter\c!sidealign]
@@ -769,12 +813,9 @@
\fi
\doifinset\v!high\floatlocation{\global\d_page_sides_topskip \zeropoint}%
\doifinset\v!low \floatlocation{\global\d_page_sides_bottomskip\zeropoint}%
- \doifinset\v!fit \floatlocation
- {\global\d_page_sides_topskip \zeropoint
- \global\d_page_sides_bottomskip\zeropoint
- \global\d_strc_floats_margin \zeropoint}%
- \global\advance\d_page_sides_topskip \floatparameter\c!topoffset
- \global\advance\d_page_sides_bottomskip\floatparameter\c!bottomoffset
+ \doifinset\v!fit \floatlocation{\global\d_page_sides_topskip \zeropoint
+ \global\d_page_sides_bottomskip\zeropoint
+ \global\d_strc_floats_margin \zeropoint}%
\else
\processallactionsinset
[\floatlocation]%
@@ -799,7 +840,12 @@
\letfloatcaptionparameter\c!rightmargin\effectiverightskip}%
\ifemptyfloatcaption \ifnofloatnumber
\global\nofloatcaptiontrue
- \fi \fi}
+ \fi \fi
+ % more variable initializations
+ \ifconditional\c_strc_floats_par_float
+ \global\advance\d_page_sides_topskip \d_page_sides_topoffset
+ \global\advance\d_page_sides_bottomskip\d_page_sides_bottomoffset
+ \fi}
% documenteren in details
@@ -1164,34 +1210,6 @@
\unexpanded\def\placefloats
{\page_otr_command_flush_floats}
-\newdimen\d_strc_floats_margin
-\newdimen\d_strc_floats_top
-\newdimen\d_strc_floats_bottom
-
-\def\strc_floats_calculate_skip#target#skip%
- {\edef\askedfloatskip{#skip}%
- \ifx\askedfloatskip\empty
- \global#target\zeropoint
- \else\ifx\askedfloatskip\v!none
- \global#target\zeropoint
- \else
- \setbox\scratchbox\vbox{\whitespace\blank[\askedfloatskip]}% todo: move whitespace inside blank
- \global#target\ht\scratchbox
- \fi\fi}
-
-\def\strc_floats_calculate_skips
- {\begingroup
- \strc_floats_calculate_skip\d_strc_floats_top {\rootfloatparameter\c!spacebefore }%
- \strc_floats_calculate_skip\d_strc_floats_bottom {\rootfloatparameter\c!spaceafter }%
- \strc_floats_calculate_skip\d_page_sides_topskip {\rootfloatparameter\c!sidespacebefore}%
- \strc_floats_calculate_skip\d_page_sides_bottomskip{\rootfloatparameter\c!sidespaceafter }%
- \global\d_strc_floats_margin \rootfloatparameter\c!margin
- \global\d_page_sides_leftshift \floatparameter \c!leftmargindistance
- \global\d_page_sides_rightshift \floatparameter \c!rightmargindistance
- \global\c_page_floats_n_of_top \rootfloatparameter\c!ntop
- \global\c_page_floats_n_of_bottom\rootfloatparameter\c!nbottom
- \endgroup}
-
\unexpanded\def\betweenfloatblanko % assumes that spaceafter is present
{\blank[\rootfloatparameter\c!spacebefore]} % or v!back,....
diff --git a/tex/context/base/mkiv/strc-itm.mkvi b/tex/context/base/mkiv/strc-itm.mkvi
index 6d9ab7b46..0bea62de8 100644
--- a/tex/context/base/mkiv/strc-itm.mkvi
+++ b/tex/context/base/mkiv/strc-itm.mkvi
@@ -448,6 +448,7 @@
\setvalue{\??itemgroupkeyword\v!serried }{\edef\itemgroupfirst{-\ifx\itemgroupfirst\empty1\else\itemgroupfirst\fi}%
\letitemgroupparameter\c!factor\itemgroupfirst}
\setvalue{\??itemgroupkeyword\v!stopper }{\letitemgroupparameter\c!placestopper\v!yes} % keep {}
+\setvalue{\??itemgroupkeyword\v!nostopper }{\letitemgroupparameter\c!placestopper\v!no} % keep {}
\setvalue{\??itemgroupkeyword\v!repeat }{\settrue\c_strc_itemgroups_repeat}
\setvalue{\??itemgroupkeyword\v!norepeat }{\setfalse\c_strc_itemgroups_repeat}
\setvalue{\??itemgroupkeyword\v!reverse }{\settrue\c_strc_itemgroups_reverse}
@@ -1131,19 +1132,21 @@
\strc_itemgroups_margin_symbol
\let\strc_itemgroups_margin_symbol\relax
\dostarttagged\t!itemcontent\empty
- \strut
+ \begstrut % \strut
\nobreak % else problems with intext items
\seteffectivehsize % NEW !
\hskip\d_strc_itemgroups_signal % concat
\itemgroupparameter\c!command}
\unexpanded\def\stopitemgroupitem
- {\ifconditional\c_strc_itemgroups_text
+ {\ifhmode
+ \endstrut % new per 2017-12-15
+ \fi
+ \ifconditional\c_strc_itemgroups_text
% nothing
\else
\endgraf
\fi}
-
\unexpanded\def\startitemgrouphead
{\dosingleempty\strc_itemgroups_start_head}
@@ -1218,7 +1221,9 @@
\dotagsetitem\s!symbol}
\unexpanded\def\strc_itemgroups_start_dummy
- {\strc_itemgroups_start_symbol\strut\strut} % two ?
+ {\strc_itemgroups_start_symbol
+ %\strut\strut} % two ?
+ \begstrut}
\unexpanded\def\strc_itemgroups_start_subitem
{\settrue\c_strc_itemgroups_sub
diff --git a/tex/context/base/mkiv/strc-lst.lua b/tex/context/base/mkiv/strc-lst.lua
index be8e07112..a235fac75 100644
--- a/tex/context/base/mkiv/strc-lst.lua
+++ b/tex/context/base/mkiv/strc-lst.lua
@@ -15,7 +15,7 @@ if not modules then modules = { } end modules ['strc-lst'] = {
--
-- move more to commands
-local tonumber, type = tonumber, type
+local tonumber, type, next = tonumber, type, next
local concat, insert, remove, sort = table.concat, table.insert, table.remove, table.sort
local lpegmatch = lpeg.match
diff --git a/tex/context/base/mkiv/strc-lst.mkvi b/tex/context/base/mkiv/strc-lst.mkvi
index b33ebc5d0..cefaa0e14 100644
--- a/tex/context/base/mkiv/strc-lst.mkvi
+++ b/tex/context/base/mkiv/strc-lst.mkvi
@@ -144,7 +144,8 @@
\def\strc_lists_inject_nop[#dummya][#dummyb]%
{\endgroup}
-\unexpanded\def\strc_lists_inject_enhance#listindex#internal%
+% \unexpanded
+\def\strc_lists_inject_enhance#listindex#internal%
{\normalexpanded{\ctxlatecommand{enhancelist(\number#listindex)}}}
\unexpanded\def\strc_lists_inject_yes[#settings][#userdata]% can be used directly
diff --git a/tex/context/base/mkiv/strc-mat.mkiv b/tex/context/base/mkiv/strc-mat.mkiv
index 20a639fa3..c6b277991 100644
--- a/tex/context/base/mkiv/strc-mat.mkiv
+++ b/tex/context/base/mkiv/strc-mat.mkiv
@@ -46,6 +46,7 @@
\c!indentnext=\v!no,
\c!alternative=\s!default,
\c!strut=\v!no,
+ \c!numberstrut=\v!yes, % \v!no \v!yes \v!always
\c!distance=2\emwidth]
\setupformulaframed
@@ -236,11 +237,14 @@
\global\setfalse\c_strc_formulas_inside_place_sub
\to \everyresetformulas
+\def\strc_formulas_place_number_noneed
+ {\doif{\formulaparameter\c!numberstrut}\v!always\strut}
+
\def\strc_formulas_place_numbering % place formula
{\settrue\c_strc_formulas_handle_number
\strc_formulas_check_reference\c_strc_formulas_place_number_mode\currentplaceformulareference
\ifnum\c_strc_formulas_place_number_mode=\plustwo
- \glet\strc_formulas_place_number\relax
+ \glet\strc_formulas_place_number\strc_formulas_place_number_noneed
\else
\glet\strc_formulas_place_number\strc_formulas_place_number_indeed
\fi
@@ -281,7 +285,12 @@
\begingroup
\useformulastyleandcolor\c!numberstyle\c!numbercolor
\formulaparameter\c!numbercommand
- {\strut
+ {\edef\p_strut{\formulaparameter\c!numberstrut}%
+ \ifx\p_strut\v!always
+ \strut
+ \else\ifx\p_strut\v!yes
+ \strut
+ \fi\fi
\formulaparameter\c!left
\namedtaggedlabeltexts
\t!formulalabel \v!formula
diff --git a/tex/context/base/mkiv/strc-not.mkvi b/tex/context/base/mkiv/strc-not.mkvi
index 70a1d5ce8..a1c44bce8 100644
--- a/tex/context/base/mkiv/strc-not.mkvi
+++ b/tex/context/base/mkiv/strc-not.mkvi
@@ -1550,6 +1550,16 @@
\let\flushnotes\relax
+\unexpanded\def\startpostponingnotes % experimental, page-mix
+ {\ifconditional\postponingnotes\else
+ \global\settrue\postponingnotes
+ %\global\let\flushnotes\doflushnotes
+ \clf_postponenotes
+ \fi}
+
+\unexpanded\def\stoppostponingnotes % experimental, page-mix
+ {\doflushnotes}
+
\unexpanded\def\doflushnotes
{\ifconditional\postponingnotes
\begingroup
diff --git a/tex/context/base/mkiv/strc-ref.lua b/tex/context/base/mkiv/strc-ref.lua
index 75b66fd7b..73f1ca886 100644
--- a/tex/context/base/mkiv/strc-ref.lua
+++ b/tex/context/base/mkiv/strc-ref.lua
@@ -16,7 +16,7 @@ if not modules then modules = { } end modules ['strc-ref'] = {
local format, find, gmatch, match, strip = string.format, string.find, string.gmatch, string.match, string.strip
local floor = math.floor
-local rawget, tonumber, type = rawget, tonumber, type
+local rawget, tonumber, type, next = rawget, tonumber, type, next
local lpegmatch = lpeg.match
local insert, remove, copytable = table.insert, table.remove, table.copy
local formatters = string.formatters
diff --git a/tex/context/base/mkiv/strc-reg.lua b/tex/context/base/mkiv/strc-reg.lua
index e4bf0852c..51771e3b8 100644
--- a/tex/context/base/mkiv/strc-reg.lua
+++ b/tex/context/base/mkiv/strc-reg.lua
@@ -387,6 +387,7 @@ local function initializer()
end
end
end
+ -- references.sortedinternals = sortedkeys(internalreferences) -- todo: when we need it more than once
end
local function finalizer()
diff --git a/tex/context/base/mkiv/strc-sec.mkiv b/tex/context/base/mkiv/strc-sec.mkiv
index ef7e9108a..b4b9568fc 100644
--- a/tex/context/base/mkiv/strc-sec.mkiv
+++ b/tex/context/base/mkiv/strc-sec.mkiv
@@ -671,6 +671,7 @@
\newconditional\c_strc_sectioning_place
\newconditional\c_strc_sectioning_empty
\newconditional\c_strc_sectioning_hidden
+\newconditional\c_strc_sectioning_section
\newconditional\headshownumber % public
\newconditional\headisdisplay % public
@@ -701,22 +702,32 @@
\setvalue{\??headplace\v!yes}%
{\setfalse\c_strc_sectioning_empty
\settrue \c_strc_sectioning_place
- \setfalse\c_strc_sectioning_hidden}
+ \setfalse\c_strc_sectioning_hidden
+ \setfalse\c_strc_sectioning_section}
\setvalue{\??headplace\v!empty}%
{\settrue \c_strc_sectioning_empty
\settrue \c_strc_sectioning_place
- \setfalse\c_strc_sectioning_hidden}
+ \setfalse\c_strc_sectioning_hidden
+ \setfalse\c_strc_sectioning_section}
\setvalue{\??headplace\v!no}%
{\settrue \c_strc_sectioning_empty
\setfalse\c_strc_sectioning_place
- \setfalse\c_strc_sectioning_hidden}
+ \setfalse\c_strc_sectioning_hidden
+ \setfalse\c_strc_sectioning_section}
\setvalue{\??headplace\v!hidden}%
{\settrue \c_strc_sectioning_empty
\setfalse\c_strc_sectioning_place
- \settrue \c_strc_sectioning_hidden}
+ \settrue \c_strc_sectioning_hidden
+ \setfalse\c_strc_sectioning_section}
+
+\setvalue{\??headplace\v!section}%
+ {\settrue \c_strc_sectioning_empty
+ \setfalse\c_strc_sectioning_place
+ \settrue \c_strc_sectioning_hidden
+ \settrue \c_strc_sectioning_section}
\unexpanded\def\strc_sectioning_initialize_placement
{\expandnamespaceparameter\??headplace\headparameter\c!placehead\v!yes}
@@ -758,7 +769,8 @@
% so we need a 'keep track of raw set option' (or maybe a funny internal prefix)
\unexpanded\def\setheadmarking % li:: so that we can use \marking[section]{Taco needed this}
- {\normalexpanded{\setmarking[\currenthead]{li::\currentstructurelistnumber}}}
+ {\strc_sectioning_delayed_flush
+ \normalexpanded{\setmarking[\currenthead]{li::\currentstructurelistnumber}}}
\let\deepstructurenumbercommand\relax
\let\deepstructuretitlecommand \relax
@@ -879,7 +891,11 @@
\strc_sectioning_report
\dostarttagged\t!sectioncaption\empty
\let\getheadsyncs\theheadsynchonization
- \strc_rendering_place_head_hidden % only something when tracing
+ \ifconditional\c_strc_sectioning_section
+ \strc_rendering_place_head_section
+ \else
+ \strc_rendering_place_head_hidden % only something when tracing
+ \fi
\dostoptagged
\else
\strc_sectioning_before_nop % toegevoegd ivm subpaginanr / tug sheets
@@ -907,7 +923,11 @@
\strc_sectioning_report
\let\getheadsyncs\theheadsynchonization
\dostarttagged\t!sectioncaption\empty
- \strc_rendering_place_head_hidden % only something when tracing
+ \ifconditional\c_strc_sectioning_section
+ \strc_rendering_place_head_section
+ \else
+ \strc_rendering_place_head_hidden % only something when tracing
+ \fi
\dostoptagged
\else
% do nothing / should be vbox to 0pt
@@ -953,6 +973,20 @@
% todo: when in the page builder we need to resolve the marking immediately
% because otherwise we have an async
+\newbox\b_sectioning_delayed
+
+\def\strc_sectioning_delayed_flush
+ {\ifvoid\b_sectioning_delayed\else
+ \smashboxed\b_sectioning_delayed
+ \fi}
+
+\unexpanded\def\strc_rendering_place_head_section % see hidden below
+ {\global\setbox\b_sectioning_delayed\hpack\bgroup
+ \setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}%
+ \hpack\headreferenceattributes{}%
+ \currentstructuresynchronize
+ \egroup}
+
\unexpanded\def\strc_rendering_place_head_hidden % maybe trialtypesetting check
{\setxvalue{\??hiddenheadattr\currenthead}%
{\headreferenceattributes}% can be used when making a box
diff --git a/tex/context/base/mkiv/strc-syn.mkiv b/tex/context/base/mkiv/strc-syn.mkiv
index 85398106d..8d609e425 100644
--- a/tex/context/base/mkiv/strc-syn.mkiv
+++ b/tex/context/base/mkiv/strc-syn.mkiv
@@ -162,9 +162,9 @@
%c!hang=,
%c!sample=,
\c!margin=\v!no,
- \c!before=\blank,
+ \c!before=\startpacked,
\c!inbetween=\blank,
- \c!after=\blank,
+ \c!after=\stoppacked,
%c!indentnext=,
%c!indenting=,
%
@@ -424,8 +424,9 @@
{\strc_constructions_initialize{#1}%
\setupcurrentsimplelist[#2]%
\let\synonymentry\strc_synonym_normal
- \startpacked
- \clf_processsynonyms
+ % so we can hook tabulate into before and after
+ \normalexpanded{\simplelistparameter\c!before
+ \noexpand\clf_processsynonyms
{#1}%
{%
criterium {\simplelistparameter\c!criterium}%
@@ -433,7 +434,8 @@
method {\simplelistparameter\c!method}%
}%
\relax
- \stoppacked}%
+ \simplelistparameter\c!after}%
+ \relax}%
{}% todo: message that invalid
\endgroup}
@@ -467,8 +469,8 @@
%\c!command=, % we test for defined !
%\c!criterium=,
%\c!style=,
- %\c!before=,
- \c!after=\endgraf,
+ \c!before=\startpacked,
+ \c!after=\stoppacked,
%\c!expansion=,
\c!method=]
@@ -596,6 +598,7 @@
\unexpanded\def\placelistofsorts
{\dodoubleempty\strc_sorting_place_list}
+
\def\strc_sorting_place_list[#1][#2]%
{\begingroup
\edef\currentsimplelist{#1}%
@@ -607,8 +610,9 @@
\else
\let\synonymentry\strc_sorting_command
\fi
- \startpacked
- \clf_processsynonyms
+ % so we can hook tabulate into before and after
+ \normalexpanded{\simplelistparameter\c!before
+ \noexpand\clf_processsynonyms
{#1}%
{%
criterium {\simplelistparameter\c!criterium}%
@@ -616,7 +620,7 @@
method {\simplelistparameter\c!method}%
}%
\relax
- \stoppacked
+ \simplelistparameter\c!after}%
\endgroup}
\unexpanded\def\completelistofsorts
diff --git a/tex/context/base/mkiv/supp-box.lua b/tex/context/base/mkiv/supp-box.lua
index fc8ad1ae4..1193c30b6 100644
--- a/tex/context/base/mkiv/supp-box.lua
+++ b/tex/context/base/mkiv/supp-box.lua
@@ -10,7 +10,7 @@ if not modules then modules = { } end modules ['supp-box'] = {
local report_hyphenation = logs.reporter("languages","hyphenation")
-local tonumber = tonumber
+local tonumber, next, type = tonumber, next, type
local lpegmatch = lpeg.match
diff --git a/tex/context/base/mkiv/supp-box.mkiv b/tex/context/base/mkiv/supp-box.mkiv
index eb824ee31..b2a29b3be 100644
--- a/tex/context/base/mkiv/supp-box.mkiv
+++ b/tex/context/base/mkiv/supp-box.mkiv
@@ -79,6 +79,7 @@
\def\strutht {\ht\strutbox}
\def\strutwd {\wd\strutbox}
\def\struthtdp{\dimexpr\ht\strutbox+\dp\strutbox\relax}
+\def\strutgap {\dimexpr\ht\strutbox-\dp\strutbox\relax}
%D \macros
%D {voidbox,nextbox}
@@ -2668,7 +2669,7 @@
%D A funny (but rather stupid) one, plus a redefinition.
\unexpanded\def\removebottomthings
- {\dorecurse5{\unskip\unkern\unpenalty}}
+ {\dorecurse\plusfive{\unskip\unkern\unpenalty}}
\unexpanded\def\removelastskip % \ifvmode the plain tex one \fi
{\ifvmode\ifzeropt\lastskip\else\vskip-\lastskip\fi\fi}
diff --git a/tex/context/base/mkiv/syst-aux.lua b/tex/context/base/mkiv/syst-aux.lua
index b5ebe1681..f88938686 100644
--- a/tex/context/base/mkiv/syst-aux.lua
+++ b/tex/context/base/mkiv/syst-aux.lua
@@ -11,7 +11,7 @@ if not modules then modules = { } end modules ['syst-aux'] = {
-- utfmatch(str,"(.?)(.*)$")
-- utf.sub(str,1,1)
-local tonumber = tonumber
+local tonumber, next = tonumber, next
local utfsub = utf.sub
local P, S, R, C, Cc, Cs, Carg, lpegmatch = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Carg, lpeg.match
local next = next
diff --git a/tex/context/base/mkiv/syst-ini.mkiv b/tex/context/base/mkiv/syst-ini.mkiv
index 2c8263962..3480b03d1 100644
--- a/tex/context/base/mkiv/syst-ini.mkiv
+++ b/tex/context/base/mkiv/syst-ini.mkiv
@@ -345,6 +345,11 @@
\newbox \scratchboxfour \newbox \scratchboxfive \newbox \scratchboxsix
%D \macros
+%D {tempstring}
+
+\let\tempstring\empty
+
+%D \macros
%D {scratchwidth, scratchheight, scratchdepth, scratchoffset, scratchdistance}
%D
%D A few more scratch dimensions:
diff --git a/tex/context/base/mkiv/tabl-mis.mkiv b/tex/context/base/mkiv/tabl-mis.mkiv
index 2d88f3495..b2af1993e 100644
--- a/tex/context/base/mkiv/tabl-mis.mkiv
+++ b/tex/context/base/mkiv/tabl-mis.mkiv
@@ -165,7 +165,7 @@
\unexpanded\def\startparagraphs[#1]% quite slow
{\bgroup % (1)
\edef\currentparagraphs{#1}%
- \paragraphsparameter\c!before
+ % \paragraphsparameter\c!before
\edef\p_width{\paragraphsparameter\c!width}%
\ifx\p_width\empty
\d_typo_paragraphs_width\availablehsize
@@ -194,10 +194,14 @@
\parindent\zeropoint
\c_typo_paragraphs_n\zerocount
\let\\=\typo_paragraphs_next % downward compatible
- \dontleavehmode\inheritedparagraphsframed
+ \edef\p_offset{\paragraphsparameter\c!offset}%
+ \doifelsedimension\p_offset
+ {\scratchoffset\p_offset}%
+ {\scratchoffset\zeropoint}%
+ \setbox\scratchbox\hpack
\bgroup % (2)
\forgetall
- \advance\hsize-2\dimexpr\paragraphsparameter\c!offset\relax
+ \advance\hsize-2\scratchoffset
\let\typo_paragraphs_start_cell\typo_paragraphs_start_cell_indeed
\let\typo_paragraphs_stop_cell \typo_paragraphs_stop_cell_indeed
\typo_paragraphs_start_cell_indeed}
@@ -205,6 +209,9 @@
\unexpanded\def\stopparagraphs
{\stopparagraphscell
\egroup % (2)
+ \letparagraphsparameter\c!align\v!flushleft % normal
+ \paragraphsparameter\c!before
+ \dontleavehmode\inheritedparagraphsframed{\box\scratchbox}%
\paragraphsparameter\c!after
\egroup} % (1)
diff --git a/tex/context/base/mkiv/tabl-tbl.mkiv b/tex/context/base/mkiv/tabl-tbl.mkiv
index edaf231e2..f80df82d7 100644
--- a/tex/context/base/mkiv/tabl-tbl.mkiv
+++ b/tex/context/base/mkiv/tabl-tbl.mkiv
@@ -1033,6 +1033,7 @@
\appendtoks
\setuevalue{\e!start\currenttabulation}{\tabl_start_defined[\currenttabulation]}%
+ \letvalue{\e!stop\currenttabulation}\relax
\letvalue{\??tabulatehead\currenttabulation}\empty
\letvalue{\??tabulatefoot\currenttabulation}\empty
\to \everydefinetabulation
@@ -1072,7 +1073,7 @@
%\expandafter\ifx\lastnamedcs\empty
\let\tabl_tabulate_insert_foot\empty
\else
- \let\tabl_tabulate_insert_foot\tabl_tabulate_insert_head_content
+ \let\tabl_tabulate_insert_foot\tabl_tabulate_insert_foot_content
\fi
\else
\let\tabl_tabulate_insert_foot\empty
@@ -1196,7 +1197,7 @@
\unexpanded\def\tabl_tabulate_start_ignore
{\em Nested tabulate is not (yet) supported.\relax
- \expandafter\gobbleuntil\csname\e!stop\v!tabulate\endcsname}
+ \expandafter\gobbleuntil\csname\ifconditional\c_tabl_generic stoptabulate\else\e!stop\v!tabulate\fi\endcsname}
\appendtoks
\letvalue{\e!start\v!tabulate}\tabl_tabulate_start_ignore % only the main one
@@ -1337,7 +1338,7 @@
\d_tabl_tabulate_indent\dimexpr\leftskip+\hangindent\ifx\p_indenting\v!yes+\parindent\fi\relax
\global\c_tabl_tabulate_column\zerocount
\processcontent
- {\e!stop\ifx\currenttabulationparent\empty\v!tabulate\else\currenttabulationparent\fi}
+ {\ifconditional\c_tabl_generic stoptabulate\else\e!stop\ifx\currenttabulationparent\empty\v!tabulate\else\currenttabulationparent\fi\fi}
\tabl_tabulate_insert_body
\tabl_tabulate_process}
@@ -2678,11 +2679,21 @@
%D \stopwhatever
%D \stoptyping
-%D This is needed because we soemtimes use the english command in
+%D This is needed because we sometimes use the english command in
%D tracing macros. In fact, most detailed tracing macros that
%D are done with \LUA\ only work in the english interface anyway.
-\definetabulate[tabulate] \setuptabulate[tabulate][\c!format=\v!none] % so no \v! here
+% \definetabulate[tabulate] \setuptabulate[tabulate][\c!format=\v!none] % so no \v! here
+
+\newconditional\c_tabl_generic
+
+\unexpanded\setuvalue{starttabulate}%
+ {\bgroup % whole thing
+ \settrue\c_tabl_generic
+ \let\currenttabulationparent\empty
+ \dodoubleempty\tabl_start_regular}
+
+\letvalue{stoptabulate}\relax
%D The following helpers are just there because we also have them at the \LUA\ end:
%D
diff --git a/tex/context/base/mkiv/tabl-xtb.lua b/tex/context/base/mkiv/tabl-xtb.lua
index 0835576c7..524ca109c 100644
--- a/tex/context/base/mkiv/tabl-xtb.lua
+++ b/tex/context/base/mkiv/tabl-xtb.lua
@@ -128,7 +128,7 @@ function xtables.create(settings)
local widths = { }
local heights = { }
local depths = { }
- local spans = { }
+ -- local spans = { }
local distances = { }
local autowidths = { }
local modes = { }
@@ -143,7 +143,7 @@ function xtables.create(settings)
widths = widths,
heights = heights,
depths = depths,
- spans = spans,
+ -- spans = spans,
distances = distances,
modes = modes,
autowidths = autowidths,
@@ -250,9 +250,24 @@ function xtables.set_reflow_width()
local c = data.currentcolumn
local rows = data.rows
local row = rows[r]
+ local cold = c
while row[c].span do -- can also be previous row ones
c = c + 1
end
+ -- bah, we can have a span already
+ if c > cold then
+ local ro = row[cold]
+ local rx = ro.nx
+ local ry = ro.ny
+ if rx > 1 or ry > 1 then
+ local rn = row[c]
+ rn.nx = rx
+ rn.ny = ry
+ ro.nx = 1 -- or 0
+ ro.ny = 1 -- or 0
+ -- do we also need to set ro.span and rn.span
+ end
+ end
local tb = getbox("b_tabl_x")
local drc = row[c]
--
@@ -290,6 +305,8 @@ function xtables.set_reflow_width()
-- end
-- end
if drc.ny < 2 then
+ -- report_xtable("set width, old: ht=%p, dp=%p",heights[r],depths[r])
+ -- report_xtable("set width, new: ht=%p, dp=%p",height,depth)
if height > heights[r] then
heights[r] = height
end
@@ -306,11 +323,11 @@ function xtables.set_reflow_width()
local fixedcolumns = data.fixedcolumns
local fixedrows = data.fixedrows
if dimensionstate == 1 then
- if cspan > 1 then
- -- ignore width
- elseif width > fixedcolumns[c] then -- how about a span here?
- fixedcolumns[c] = width
- end
+ if cspan > 1 then
+ -- ignore width
+ elseif width > fixedcolumns[c] then -- how about a span here?
+ fixedcolumns[c] = width
+ end
elseif dimensionstate == 2 then
fixedrows[r] = height
elseif dimensionstate == 3 then
@@ -360,7 +377,7 @@ function xtables.set_reflow_width()
--
local nx, ny = drc.nx, drc.ny
if nx > 1 or ny > 1 then
- local spans = data.spans
+ -- local spans = data.spans -- not used
local self = true
for y=1,ny do
for x=1,nx do
@@ -369,9 +386,9 @@ function xtables.set_reflow_width()
else
local ry = r + y - 1
local cx = c + x - 1
- if y > 1 then
- spans[ry] = true
- end
+ -- if y > 1 then
+ -- spans[ry] = true -- not used
+ -- end
rows[ry][cx].span = true
end
end
@@ -432,13 +449,17 @@ function xtables.set_reflow_height()
--
if drc.ny < 2 then
if data.fixedrows[r] == 0 then -- and drc.dimensionstate < 2
- local heights = data.heights
- local depths = data.depths
- if height > heights[r] then
- heights[r] = height
- end
- if depth > depths[r] then
- depths[r] = depth
+ if drc.ht + drc.dp <= height + depth then -- new per 2017-12-15
+ local heights = data.heights
+ local depths = data.depths
+ -- report_xtable("set height, old: ht=%p, dp=%p",heights[r],depths[r])
+ -- report_xtable("set height, new: ht=%p, dp=%p",height,depth)
+ if height > heights[r] then
+ heights[r] = height
+ end
+ if depth > depths[r] then
+ depths[r] = depth
+ end
end
end
end
@@ -471,7 +492,7 @@ function xtables.initialize_construct()
--
local width = widths[c]
local height = heights[r]
- local depth = depths[r]
+ local depth = depths[r] -- problem: can be the depth of a one liner
--
for x=1,drc.nx-1 do
width = width + widths[c+x]
@@ -518,7 +539,6 @@ function xtables.reflow_width()
local nofrows = data.nofrows
local nofcolumns = data.nofcolumns
local rows = data.rows
--- inspect(rows)
for r=1,nofrows do
local row = rows[r]
for c=1,nofcolumns do
@@ -550,8 +570,7 @@ function xtables.reflow_width()
showwidths("stage 1",widths,autowidths)
end
local noffrozen = 0
--- here we can also check spans
- -- inspect(data.fixedcspans)
+ -- here we can also check spans
if options[v_max] then
for c=1,nofcolumns do
width = width + widths[c]
@@ -676,8 +695,6 @@ function xtables.reflow_width()
--
data.currentrow = 0
data.currentcolumn = 0
- --
--- inspect(data)
end
function xtables.reflow_height()
@@ -738,8 +755,6 @@ function xtables.reflow_height()
end
end
end
- --
--- inspect(data)
end
local function showspans(data)
@@ -769,7 +784,7 @@ function xtables.construct()
local heights = data.heights
local depths = data.depths
local widths = data.widths
- local spans = data.spans
+ -- local spans = data.spans
local distances = data.distances
local modes = data.modes
local settings = data.settings
@@ -1171,7 +1186,6 @@ function xtables.cleanup()
-- end
-- end
-- data.result = nil
- -- inspect(data)
data = table.remove(stack)
end
diff --git a/tex/context/base/mkiv/tabl-xtb.mkvi b/tex/context/base/mkiv/tabl-xtb.mkvi
index 24b004b2b..dc4a30e2b 100644
--- a/tex/context/base/mkiv/tabl-xtb.mkvi
+++ b/tex/context/base/mkiv/tabl-xtb.mkvi
@@ -140,8 +140,12 @@
\c!autostrut=\v!no,
\c!split=\v!auto, % a number will take that many lines
\c!splitoffset=\zeropoint, % extra space taken
- % \c!aligncharacter=\v!no,
- % \c!alignmentcharacter={,},
+ \c!aligncharacter=\v!no,
+ \c!alignmentcharacter={,},
+ \c!alignmentleftsample=,
+ \c!alignmentrightsample=,
+ \c!alignmentleftwidth=\zeropoint,
+ \c!alignmentrightwidth=\zeropoint,
% \c!option=, % \v!stretch {\v!stretch,\v!width}
% \c!footer=,
% \c!header=,
@@ -335,6 +339,7 @@
\clf_x_table_cleanup
\dostoptagged
\resetbuffer[\tabl_x_current_buffer]%
+ \resetcharacteralign
\egroup}
% text flow split modes
@@ -480,8 +485,50 @@
{\tabl_x_start_cell_nop
\tabl_x_stop_cell}
+% \unexpanded\def\tabl_x_begin_of_cell
+% {%\inhibitblank % already in framed
+% \everypar{\delayedbegstrut}}
+
+\def\tabl_x_setup_character_align
+ {\edef\p_left {\directxtableparameter\c!alignmentleftsample}%
+ \edef\p_right{\directxtableparameter\c!alignmentrightsample}%
+ \ifx\p_left\empty
+ \scratchdimenone\dimexpr\directxtableparameter\c!alignmentleftwidth\relax
+ \else
+ \setbox\scratchbox\hbox{\p_left}%
+ \scratchdimenone\wd\scratchbox
+ \fi
+ \ifx\p_right\empty
+ \scratchdimentwo\dimexpr\directxtableparameter\c!alignmentrightwidth\relax
+ \else
+ \setbox\scratchbox\hbox{\p_right}%
+ \scratchdimentwo\wd\scratchbox
+ \fi
+ \clf_setcharacteraligndetail
+ \clf_x_table_c
+ {\directxtableparameter\c!alignmentcharacter}%
+ \scratchdimenone
+ \scratchdimentwo
+ \relax}
+
+\newtoks\t_tabl_x_every_cell
+
+% \appendtoks
+% \inhibitblank % already in framed
+% \to \t_tabl_x_every_cell
+
+\appendtoks
+ \edef\p_characteralign{\directxtableparameter\c!aligncharacter}%
+ \ifx\p_characteralign\v!yes
+ \ifcase\clf_x_table_r\or
+ \tabl_x_setup_character_align
+ \fi
+ \signalcharacteralign\clf_x_table_c\clf_x_table_r
+ \fi
+\to \t_tabl_x_every_cell
+
\unexpanded\def\tabl_x_begin_of_cell
- {%\inhibitblank % already in framed
+ {\the\t_tabl_x_every_cell
\everypar{\delayedbegstrut}}
\unexpanded\def\tabl_x_end_of_cell
@@ -519,7 +566,7 @@
\let\tabl_x_set_hsize\relax
\unexpanded\def\tabl_x_start_cell_reflow_width_yes[#settings]%
- {\setbox\b_tabl_x\hbox\bgroup
+ {\setbox\b_tabl_x\hpack\bgroup
\ifnum\c_tabl_x_nesting>\plusone
\letxtableparameter\c!width \v!fit % overloads given width
\letxtableparameter\c!height\v!fit % overloads given height
@@ -548,7 +595,7 @@
\tabl_x_set_hsize}
\unexpanded\def\tabl_x_start_cell_reflow_width_nop
- {\setbox\b_tabl_x\hbox\bgroup
+ {\setbox\b_tabl_x\hpack\bgroup
\ifnum\c_tabl_x_nesting>\plusone
\letxtableparameter\c!width \v!fit % overloads given width
\letxtableparameter\c!height\v!fit % overloads given height
@@ -568,7 +615,7 @@
\clf_x_table_set_reflow_width}
\unexpanded\def\tabl_x_start_cell_reflow_height_yes[#settings]%
- {\setbox\b_tabl_x\hbox\bgroup
+ {\setbox\b_tabl_x\hpack\bgroup
\clf_x_table_init_reflow_height
\ifcase\c_tabl_x_skip_mode % can be sped up
\ifnum\c_tabl_x_nesting>\plusone
@@ -582,7 +629,7 @@
\fi}
\unexpanded\def\tabl_x_start_cell_reflow_height_nop
- {\setbox\b_tabl_x\hbox\bgroup
+ {\setbox\b_tabl_x\hpack\bgroup
\clf_x_table_init_reflow_height
\ifcase\c_tabl_x_skip_mode % can be sped up
\ifnum\c_tabl_x_nesting>\plusone
@@ -604,7 +651,7 @@
\unexpanded\def\tabl_x_start_cell_construct_yes[#settings]%
{\dostarttagged\t!tablecell\empty % can't we just tag the box
- \setbox\b_tabl_x\hbox\bgroup
+ \setbox\b_tabl_x\hpack\bgroup
\setupcurrentxtable[#settings]%
\letxtableparameter\c!width \d_tabl_x_width % overloads given width
\letxtableparameter\c!height\d_tabl_x_height % overloads given height
@@ -615,7 +662,7 @@
\unexpanded\def\tabl_x_start_cell_construct_nop
{\dostarttagged\t!tablecell\empty % can't we just tag the box
- \setbox\b_tabl_x\hbox\bgroup
+ \setbox\b_tabl_x\hpack\bgroup
\letxtableparameter\c!width \d_tabl_x_width % overloads given width
\letxtableparameter\c!height\d_tabl_x_height % overloads given height (commenting it ... nice option)
\clf_x_table_init_construct
diff --git a/tex/context/base/mkiv/task-ini.lua b/tex/context/base/mkiv/task-ini.lua
index 1c21252f7..36b346342 100644
--- a/tex/context/base/mkiv/task-ini.lua
+++ b/tex/context/base/mkiv/task-ini.lua
@@ -71,7 +71,7 @@ appendaction("shipouts", "normalizers", "typesetters.showsuspects")
appendaction("shipouts", "normalizers", "typesetters.margins.finalhandler") -- disabled
------------("shipouts", "normalizers", "nodes.handlers.cleanuppage") -- disabled
appendaction("shipouts", "normalizers", "builders.paragraphs.expansion.trace") -- disabled
-appendaction("shipouts", "normalizers", "typesetters.alignments.handler")
+appendaction("shipouts", "normalizers", "typesetters.alignments.handler") -- disabled
appendaction("shipouts", "normalizers", "nodes.references.handler") -- disabled
appendaction("shipouts", "normalizers", "nodes.destinations.handler") -- disabled
appendaction("shipouts", "normalizers", "nodes.rules.handler") -- disabled
diff --git a/tex/context/base/mkiv/toks-ini.lua b/tex/context/base/mkiv/toks-ini.lua
index 312a8b318..36b47d0dd 100644
--- a/tex/context/base/mkiv/toks-ini.lua
+++ b/tex/context/base/mkiv/toks-ini.lua
@@ -9,6 +9,7 @@ tokens = tokens or { }
local tokens = tokens
local token = token -- the built in one
+local next = next
local tonumber = tonumber
local tostring = tostring
local utfchar = utf.char
diff --git a/tex/context/base/mkiv/trac-ctx.lua b/tex/context/base/mkiv/trac-ctx.lua
index 493ce7936..29159d130 100644
--- a/tex/context/base/mkiv/trac-ctx.lua
+++ b/tex/context/base/mkiv/trac-ctx.lua
@@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['trac-ctx'] = {
license = "see context related readme files"
}
+local next = next
+
local context = context
local implement = interfaces.implement
local register = trackers.register
diff --git a/tex/context/base/mkiv/trac-fil.lua b/tex/context/base/mkiv/trac-fil.lua
index 8cc903e2a..f422c9f6b 100644
--- a/tex/context/base/mkiv/trac-fil.lua
+++ b/tex/context/base/mkiv/trac-fil.lua
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['trac-fil'] = {
license = "see context related readme files"
}
-local rawset, tonumber, type, pcall = rawset, tonumber, type, pcall
+local rawset, tonumber, type, pcall, next = rawset, tonumber, type, pcall, next
local format, concat = string.format, table.concat
local openfile = io.open
local date = os.date
diff --git a/tex/context/base/mkiv/trac-lmx.lua b/tex/context/base/mkiv/trac-lmx.lua
index 4f4ea62c4..c7f949618 100644
--- a/tex/context/base/mkiv/trac-lmx.lua
+++ b/tex/context/base/mkiv/trac-lmx.lua
@@ -695,6 +695,8 @@ if arg then
if arg[1] == "--show" then if arg[2] then lmx.show (arg[2]) end
elseif arg[1] == "--convert" then if arg[2] then lmx.convert(arg[2], arg[3] or "temp.html") end
end
+else
+ return lmx
end
-- Test 1:
diff --git a/tex/context/base/mkiv/trac-pro.lua b/tex/context/base/mkiv/trac-pro.lua
index 897b6a15c..cbaae7f0c 100644
--- a/tex/context/base/mkiv/trac-pro.lua
+++ b/tex/context/base/mkiv/trac-pro.lua
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['trac-pro'] = {
license = "see context related readme files"
}
-local getmetatable, setmetatable, rawset, type = getmetatable, setmetatable, rawset, type
+local getmetatable, setmetatable, rawset, type, next = getmetatable, setmetatable, rawset, type, next
-- The protection implemented here is probably not that tight but good enough to catch
-- problems due to naive usage.
diff --git a/tex/context/base/mkiv/trac-vis.lua b/tex/context/base/mkiv/trac-vis.lua
index 3822aa4a6..e5f657a30 100644
--- a/tex/context/base/mkiv/trac-vis.lua
+++ b/tex/context/base/mkiv/trac-vis.lua
@@ -7,7 +7,7 @@ if not modules then modules = { } end modules ['trac-vis'] = {
}
local node, nodes, attributes, fonts, tex = node, nodes, attributes, fonts, tex
-local type, tonumber = type, tonumber
+local type, tonumber, next = type, tonumber, next
local gmatch = string.gmatch
local formatters = string.formatters
local compactfloat = number.compactfloat
@@ -121,21 +121,22 @@ local bor = bit32.bor
local enableaction = nodes.tasks.enableaction
-local trace_hbox
-local trace_vbox
-local trace_vtop
-local trace_kern
-local trace_glue
-local trace_penalty
-local trace_fontkern
-local trace_strut
-local trace_whatsit
-local trace_user
-local trace_math
-local trace_italic
-local trace_discretionary
-local trace_expansion
-local trace_line
+-- local trace_hbox
+-- local trace_vbox
+-- local trace_vtop
+-- local trace_kern
+-- local trace_glue
+-- local trace_penalty
+-- local trace_fontkern
+-- local trace_strut
+-- local trace_whatsit
+-- local trace_user
+-- local trace_math
+-- local trace_italic
+-- local trace_discretionary
+-- local trace_expansion
+-- local trace_line
+-- local trace_space
local report_visualize = logs.reporter("visualize")
@@ -162,10 +163,11 @@ local modes = {
discretionary = 32768,
expansion = 65536,
line = 131072,
+ space = 262144,
}
local usedfont, exheight, emwidth
-local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_whatsit, l_glyph, l_user, l_math, l_italic, l_origin, l_discretionary, l_expansion, l_line
+local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_whatsit, l_glyph, l_user, l_math, l_italic, l_origin, l_discretionary, l_expansion, l_line, l_space
local enabled = false
local layers = { }
@@ -219,6 +221,7 @@ local function enable()
l_discretionary = layers.discretionary
l_expansion = layers.expansion
l_line = layers.line
+ l_space = layers.space
enableaction("shipouts","nodes.visualizers.handler")
report_visualize("enabled")
enabled = true
@@ -362,6 +365,7 @@ local c_negative = "trace:r"
local c_zero = "trace:g"
local c_text = "trace:s"
local c_space = "trace:y"
+local c_space_x = "trace:m"
local c_skip_a = "trace:c"
local c_skip_b = "trace:m"
local c_glyph = "trace:o"
@@ -377,6 +381,7 @@ local c_negative_d = "trace:dr"
local c_zero_d = "trace:dg"
local c_text_d = "trace:ds"
local c_space_d = "trace:dy"
+local c_space_x_d = "trace:dm"
local c_skip_a_d = "trace:dc"
local c_skip_b_d = "trace:dm"
local c_glyph_d = "trace:do"
@@ -405,7 +410,7 @@ local function sometext(str,layer,color,textcolor,lap) -- we can just paste verb
if lap then
info = new_hlist(setlink(new_kern(-width),info))
else
- info = new_hlist(info)
+ info = new_hlist(info) -- a bit overkill: double wrapped
end
if layer then
setattr(info,a_layer,layer)
@@ -413,6 +418,28 @@ local function sometext(str,layer,color,textcolor,lap) -- we can just paste verb
return info, width
end
+local function someblob(str,layer,color,textcolor,width)
+ local text = hpack_string(str,usedfont)
+ local size = getwidth(text)
+ local rule = new_rule(width,2*exheight,exheight/2)
+ local kern = new_kern(-width + (width-size)/2)
+ if color then
+ setcolor(rule,color)
+ end
+ if textcolor then
+ setlistcolor(getlist(text),textcolor)
+ end
+ local info = setlink(rule,kern,text)
+ setlisttransparency(info,c_zero)
+ info = hpack_nodes(info)
+ local width = getwidth(info)
+ info = new_hlist(info)
+ if layer then
+ setattr(info,a_layer,layer)
+ end
+ return info, width
+end
+
local caches = setmetatableindex("table")
local fontkern, italickern do
@@ -898,8 +925,8 @@ local ruledglue do
local gluecodes = nodes.gluecodes
local cleaders_code = gluecodes.cleaders
local userskip_code = gluecodes.userskip
- local space_code = gluecodes.space
- local xspace_code = gluecodes.xspace
+ local space_code = gluecodes.spaceskip
+ local xspace_code = gluecodes.xspaceskip
local leftskip_code = gluecodes.leftskip
local rightskip_code = gluecodes.rightskip
@@ -908,28 +935,28 @@ local ruledglue do
local tags = {
-- userskip = "US",
- lineskip = "LS",
- baselineskip = "BS",
- parskip = "PS",
- abovedisplayskip = "DA",
- belowdisplayskip = "DB",
- abovedisplayshortskip = "SA",
- belowdisplayshortskip = "SB",
- leftskip = "LS",
- rightskip = "RS",
- topskip = "TS",
- splittopskip = "ST",
- tabskip = "AS",
- spaceskip = "SS",
- xspaceskip = "XS",
- parfillskip = "PF",
- thinmuskip = "MS",
- medmuskip = "MM",
- thickmuskip = "ML",
- leaders = "NL",
- cleaders = "CL",
- xleaders = "XL",
- gleaders = "GL",
+ [gluecodes.lineskip] = "LS",
+ [gluecodes.baselineskip] = "BS",
+ [gluecodes.parskip] = "PS",
+ [gluecodes.abovedisplayskip] = "DA",
+ [gluecodes.belowdisplayskip] = "DB",
+ [gluecodes.abovedisplayshortskip] = "SA",
+ [gluecodes.belowdisplayshortskip] = "SB",
+ [gluecodes.leftskip] = "LS",
+ [gluecodes.rightskip] = "RS",
+ [gluecodes.topskip] = "TS",
+ [gluecodes.splittopskip] = "ST",
+ [gluecodes.tabskip] = "AS",
+ [gluecodes.spaceskip] = "SP",
+ [gluecodes.xspaceskip] = "XS",
+ [gluecodes.parfillskip] = "PF",
+ [gluecodes.thinmuskip] = "MS",
+ [gluecodes.medmuskip] = "MM",
+ [gluecodes.thickmuskip] = "ML",
+ [gluecodes.leaders] = "NL",
+ [gluecodes.cleaders] = "CL",
+ [gluecodes.xleaders] = "XL",
+ [gluecodes.gleaders] = "GL",
-- true = "VS",
-- false = "HS",
}
@@ -944,7 +971,7 @@ local ruledglue do
if info then
-- print("glue hit")
else
- if subtype == space_code or subtype == xspace_code then -- not yet all space
+ if subtype == space_code or subtype == xspace_code then
info = sometext(amount,l_glue,c_space)
elseif subtype == leftskip_code or subtype == rightskip_code then
info = sometext(amount,l_glue,c_skip_a)
@@ -969,6 +996,55 @@ local ruledglue do
return head, getnext(current)
end
+ -- ruledspace = function(head,current,parent)
+ -- local subtype = getsubtype(current)
+ -- if subtype == space_code or subtype == xspace_code then
+ -- local width = effectiveglue(current,parent)
+ -- local amount = formatters["%s:%0.3f"](tags[subtype] or "HS",width*pt_factor)
+ -- local info = g_cache_h[amount]
+ -- if info then
+ -- -- print("space hit")
+ -- else
+ -- info = sometext(amount,l_glue,c_space)
+ -- g_cache_h[amount] = info
+ -- end
+ -- info = copy_list(info)
+ -- head, current = insert_node_before(head,current,info)
+ -- return head, getnext(current)
+ -- else
+ -- return head, current
+ -- end
+ -- end
+
+ local g_cache_s = caches["space"]
+ local g_cache_x = caches["xspace"]
+
+ ruledspace = function(head,current,parent)
+ local subtype = getsubtype(current)
+ if subtype == space_code or subtype == xspace_code then -- not yet all space
+ local width = effectiveglue(current,parent)
+ local info
+ if subtype == space_code then
+ info = g_cache_s[width]
+ if not info then
+ info = someblob("SP",l_glue,c_space,nil,width)
+ g_cache_s[width] = info
+ end
+ else
+ info = g_cache_x[width]
+ if not info then
+ info = someblob("XS",l_glue,c_space_x,nil,width)
+ g_cache_x[width] = info
+ end
+ end
+ info = copy_list(info)
+ head, current = insert_node_before(head,current,info)
+ return head, getnext(current)
+ else
+ return head, current
+ end
+ end
+
end
local ruledkern do
@@ -1103,24 +1179,28 @@ do
local line_code = listcodes.line
local function visualize(head,vertical,forced,parent)
- local trace_hbox = false
- local trace_vbox = false
- local trace_vtop = false
- local trace_kern = false
- local trace_glue = false
- local trace_penalty = false
- local trace_fontkern = false
- local trace_strut = false
- local trace_whatsit = false
- local trace_glyph = false
- local trace_simple = false
- local trace_user = false
- local trace_math = false
- local trace_italic = false
- local trace_origin = false
- local current = head
- local previous = nil
- local attr = unsetvalue
+ local trace_hbox = false
+ local trace_vbox = false
+ local trace_vtop = false
+ local trace_kern = false
+ local trace_glue = false
+ local trace_penalty = false
+ local trace_fontkern = false
+ local trace_strut = false
+ local trace_whatsit = false
+ local trace_glyph = false
+ local trace_simple = false
+ local trace_user = false
+ local trace_math = false
+ local trace_italic = false
+ local trace_origin = false
+ local trace_discretionary = false
+ local trace_expansion = false
+ local trace_line = false
+ local trace_space = false
+ local current = head
+ local previous = nil
+ local attr = unsetvalue
local prev_trace_fontkern = nil
local prev_trace_italic = nil
local prev_trace_expansion = nil
@@ -1150,6 +1230,7 @@ do
trace_discretionary = false
trace_expansion = false
trace_line = false
+ trace_space = false
else -- dead slow:
trace_hbox = band(a, 1) ~= 0
trace_vbox = band(a, 2) ~= 0
@@ -1169,6 +1250,7 @@ do
trace_discretionary = band(a, 32768) ~= 0
trace_expansion = band(a, 65536) ~= 0
trace_line = band(a,131072) ~= 0
+ trace_space = band(a,262144) ~= 0
end
attr = a
end
@@ -1222,6 +1304,8 @@ do
setleader(current,visualize(content,false,nil,parent))
elseif trace_glue then
head, current = ruledglue(head,current,vertical,parent)
+ elseif trace_space then
+ head, current = ruledspace(head,current,parent)
end
elseif id == penalty_code then
if trace_penalty then
diff --git a/tex/context/base/mkiv/typo-dir.mkiv b/tex/context/base/mkiv/typo-dir.mkiv
index 03d2b4717..18914d37b 100644
--- a/tex/context/base/mkiv/typo-dir.mkiv
+++ b/tex/context/base/mkiv/typo-dir.mkiv
@@ -137,7 +137,7 @@
end
\stopluacode
-\def\biditest#1#2#3% font text raw
+\unexpanded\def\biditest#1#2#3% font text raw
{\dontleavehmode\hbox
{\framed[offset=overlay]{\tttf#2}\quad
\enabletrackers[typesetters.directions]%
diff --git a/tex/context/base/mkiv/typo-krn.lua b/tex/context/base/mkiv/typo-krn.lua
index 0a913f8ab..71d9736a4 100644
--- a/tex/context/base/mkiv/typo-krn.lua
+++ b/tex/context/base/mkiv/typo-krn.lua
@@ -446,24 +446,24 @@ function kerns.handler(head)
elseif id == disc_code then
local prev, next, pglyph, nglyph -- delayed till needed
local subtype = getsubtype(start)
- if subtype == automatic_code then
- -- this is kind of special, as we have already injected the
- -- previous kern
- local prev = getprev(start)
- local pglyph = prev and getid(prev) == glyph_code
- languages.expand(start,pglyph and prev)
- -- we can have a different start now
- elseif subtype ~= discretionary_code then
- prev = getprev(start)
- pglyph = prev and getid(prev) == glyph_code
- languages.expand(start,pglyph and prev)
- end
+ -- if subtype == automatic_code then
+ -- -- this is kind of special, as we have already injected the
+ -- -- previous kern
+ -- local prev = getprev(start)
+ -- local pglyph = prev and getid(prev) == glyph_code
+ -- languages.expand(start,pglyph and prev)
+ -- -- we can have a different start now
+ -- elseif subtype ~= discretionary_code then
+ -- prev = getprev(start)
+ -- pglyph = prev and getid(prev) == glyph_code
+ -- languages.expand(start,pglyph and prev)
+ -- end
local pre, post, replace = getdisc(start)
local indeed = false
if pre then
local okay = false
if not prev then
- prev = prev or getprev(start)
+ prev = getprev(start)
pglyph = prev and getid(prev) == glyph_code
end
if pglyph then
@@ -491,7 +491,7 @@ function kerns.handler(head)
if replace then
local okay = false
if not prev then
- prev = prev or getprev(start)
+ prev = getprev(start)
pglyph = prev and getid(prev) == glyph_code
end
if pglyph then
diff --git a/tex/context/base/mkiv/typo-pnc.lua b/tex/context/base/mkiv/typo-pnc.lua
new file mode 100644
index 000000000..1ed8d9940
--- /dev/null
+++ b/tex/context/base/mkiv/typo-pnc.lua
@@ -0,0 +1,169 @@
+if not modules then modules = { } end modules ['typo-pnc'] = {
+ version = 1.001,
+ comment = "companion to typo-pnc.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local nodes = nodes
+local fonts = fonts
+
+local prependaction = nodes.tasks.prependaction
+local enableaction = nodes.tasks.enableaction
+
+local nuts = nodes.nuts
+local tonut = nodes.tonut
+
+local nodecodes = nodes.nodecodes
+local gluecodes = nodes.gluecodes
+local glyph_code = nodecodes.glyph
+local glue_code = nodecodes.glue
+local spaceskip_code = gluecodes.spaceskip
+
+local new_kern = nuts.pool.kern
+local insert_after = nuts.insert_after
+local traverse_id = nuts.traverse_id
+
+local getchar = nuts.getchar
+local getfont = nuts.getfont
+local getboth = nuts.getboth
+local getnext = nuts.getnext
+local getattr = nuts.getattr
+local getid = nuts.getid
+local getsubtype = nuts.getsubtype
+local getwidth = nuts.getwidth
+local setwidth = nuts.setwidth
+
+local parameters = fonts.hashes.parameters
+local categories = characters.categories
+
+local texsetattribute = tex.setattribute
+local unsetvalue = attributes.unsetvalue
+
+local period = 0x2E
+local factor = 0.5
+
+-- alternative: tex.getlccode and tex.getuccode
+
+typesetters = typesetters or { }
+local typesetters = typesetters
+
+local periodkerns = typesetters.periodkerns or { }
+typesetters.periodkerns = periodkerns
+
+local report = logs.reporter("period kerns")
+local trace = false
+
+trackers.register("typesetters.periodkerns",function(v) trace = v end)
+
+periodkerns.mapping = periodkerns.mapping or { }
+periodkerns.factors = periodkerns.factors or { }
+local a_periodkern = attributes.private("periodkern")
+
+storage.register("typesetters/periodkerns/mapping", periodkerns.mapping, "typesetters.periodkerns.mapping")
+storage.register("typesetters/periodkerns/factors", periodkerns.factors, "typesetters.periodkerns.factors")
+
+local mapping = periodkerns.mapping
+local factors = periodkerns.factors
+
+function periodkerns.handler(head)
+ local done = false
+ local hnut = tonut(head)
+ for current in traverse_id(glyph_code,tonut(hnut)) do
+ if getchar(current) == period then
+ local a = getattr(current,a_periodkern)
+ if a then
+ local factor = mapping[a]
+ if factor then
+ local prev, next = getboth(current)
+ if prev and next and getid(prev) == glyph_code and getid(next) == glyph_code then
+ local pchar = getchar(prev)
+ local pcode = categories[getchar(prev)]
+ if pcode == "lu" or pcode == "ll" then
+ local nchar = getchar(next)
+ local ncode = categories[getchar(next)]
+ if ncode == "lu" or ncode == "ll" then
+ local next2 = getnext(next)
+ if next2 and getid(next2) == glyph_code and getchar(next2) == period then
+ -- A.B.
+ local fontspace, inserted
+ if factor ~= 0 then
+ fontspace = parameters[getfont(current)].space -- can be sped up
+ inserted = factor * fontspace
+ insert_after(hnut,current,new_kern(inserted))
+ if trace then
+ report("inserting space at %C . [%p] %C .",pchar,inserted,nchar)
+ end
+ done = true
+ end
+ local next3 = getnext(next2)
+ if next3 and getid(next3) == glue_code and getsubtype(next3) == spaceskip_code then
+ local width = getwidth(next3)
+ local space = fontspace or parameters[getfont(current)].space -- can be sped up
+ if width > space then -- space + extraspace
+ local next4 = getnext(next3)
+ if next4 and getid(next4) == glyph_code then
+ local fchar = getchar(next4)
+ if categories[fchar] ~= "lu" then
+ -- A.B.<glue>X
+ if trace then
+ if inserted then
+ report("reverting space at %C . [%p] %C . [%p->%p] %C",pchar,inserted,nchar,width,space,fchar)
+ else
+ report("reverting space at %C . %C . [%p->%p] %C",pchar,nchar,width,space,fchar)
+ end
+ end
+ setwidth(next3,space)
+ done = true
+ else
+ if trace then
+ if inserted then
+ report("keeping space at %C . [%p] %C . [%p] %C",pchar,inserted,nchar,width,fchar)
+ else
+ report("keeping space at %C . %C . [%p] %C",pchar,nchar,width,fchar)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ return head, done
+end
+
+local enabled = false
+
+function periodkerns.set(factor)
+ factor = tonumber(factor) or 0
+ if not enabled then
+ prependaction("processors","normalizers","typesetters.periodkerns.handler")
+ enableaction("processors","typesetters.periodkerns.handler")
+ enabled = true
+ end
+ local a = factors[factor]
+ if not a then
+ a = #mapping + 1
+ factors[factors], mapping[a] = a, factor
+ end
+ factor = a
+ texsetattribute(a_periodkern,factor)
+ return factor
+end
+
+-- interface
+
+interfaces.implement {
+ name = "setperiodkerning",
+ actions = periodkerns.set,
+ arguments = "string"
+}
+
+
diff --git a/tex/context/base/mkiv/typo-pnc.mkiv b/tex/context/base/mkiv/typo-pnc.mkiv
new file mode 100644
index 000000000..39d0c85f4
--- /dev/null
+++ b/tex/context/base/mkiv/typo-pnc.mkiv
@@ -0,0 +1,55 @@
+%D \module
+%D [ file=typo-pnc,
+%D version=2017.06.23, % experiment in project
+%D title=\CONTEXT\ Typesetting Macros,
+%D subtitle=Punctuation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Typesetting Macros / Punctuation}
+
+\unprotect
+
+% In manuals we often have "foo e.g. bar" where we then have to compensate spaces
+% with "foo e.g.\ bar" so let's see if we can automate that and at the same time
+% inject spaces between the snippets. It gets boring writing this kind of code.
+
+\registerctxluafile{typo-pnc}{}
+
+\definesystemattribute[periodkern][public,global]
+
+\installcorenamespace{periodkerning}
+
+\installcommandhandler \??periodkerning {periodkerning} \??periodkerning
+
+\unexpanded\def\setperiodkerning[#1]%
+ {\edef\currentperiodkerning{#1}%
+ \ifx\currentperiodkerning\s!reset
+ \resetperiodkerning
+ \else
+ \typo_periodkerning_set
+ \fi}
+
+\def\typo_periodkerning_set
+ {\clf_setperiodkerning{\periodkerningparameter\c!factor}}
+
+\unexpanded\def\resetperiodkerning % fast one
+ {\attribute\periodkernattribute\attributeunsetvalue}
+
+\appendtoks
+ \resetperiodkerning
+\to \everyresettypesetting
+
+\defineperiodkerning [zerospaceperiods] [\c!factor=0]
+\defineperiodkerning [smallspaceperiods] [\c!factor=.25]
+\defineperiodkerning [halfspaceperiods] [\c!factor=.5]
+
+% If we ever need a command, see typo-krn.mkiv but it doesn't make much sense
+% to have it.
+
+\protect
diff --git a/tex/context/base/mkiv/typo-sus.lua b/tex/context/base/mkiv/typo-sus.lua
index 502c90417..2d3037bdc 100644
--- a/tex/context/base/mkiv/typo-sus.lua
+++ b/tex/context/base/mkiv/typo-sus.lua
@@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['typo-sus'] = {
license = "see context related readme files"
}
+local next = next
+
local punctuation = {
po = true,
}
diff --git a/tex/context/base/mkiv/typo-tal.lua b/tex/context/base/mkiv/typo-tal.lua
index 67380f24b..870d006cc 100644
--- a/tex/context/base/mkiv/typo-tal.lua
+++ b/tex/context/base/mkiv/typo-tal.lua
@@ -14,7 +14,7 @@ if not modules then modules = { } end modules ['typo-tal'] = {
-- We can speed up by saving the current fontcharacters[font] + lastfont.
-local next, type = next, type
+local next, type, tonumber = next, type, tonumber
local div = math.div
local utfbyte = utf.byte
@@ -38,6 +38,7 @@ local tonode = nuts.tonode
local getnext = nuts.getnext
local getprev = nuts.getprev
+local getboth = nuts.getboth
local getid = nuts.getid
local getfont = nuts.getfont
local getchar = nuts.getchar
@@ -100,7 +101,7 @@ local validsigns = {
-- If needed we can have more modes which then also means a faster simple handler
-- for non numbers.
-local function setcharacteralign(column,separator)
+local function setcharacteralign(column,separator,before,after)
if not enabled then
enableaction("processors","typesetters.characteralign.handler")
enabled = true
@@ -123,11 +124,14 @@ local function setcharacteralign(column,separator)
separator = comma
method = v_number
end
+ local before = tonumber(before) or 0
+ local after = tonumber(after) or 0
dataset = {
separator = separator,
list = { },
- maxafter = 0,
- maxbefore = 0,
+ maxbefore = before,
+ maxafter = after,
+ predefined = before > 0 or after > 0,
collected = false,
method = method,
separators = validseparators,
@@ -153,6 +157,12 @@ implement {
}
implement {
+ name = "setcharacteraligndetail",
+ actions = setcharacteralign,
+ arguments = { "integer", "string", "dimension", "dimension" }
+}
+
+implement {
name = "resetcharacteralign",
actions = resetcharacteralign
}
@@ -257,10 +267,9 @@ function characteralign.handler(originalhead,where)
elseif (b_start or a_start) and id == glue_code then
-- maybe only in number mode
-- somewhat inefficient
- local next = getnext(current)
- local prev = getprev(current)
+ local prev, next = getboth(current)
if next and prev and getid(next) == glyph_code and getid(prev) == glyph_code then -- too much checking
- local width = fontcharacters[getfont(b_start)][separator or period].width
+ local width = fontcharacters[getfont(b_start or a_start)][separator or period].width
setglue(current,width)
setattr(current,a_character,punctuationspace)
if a_start then
@@ -310,8 +319,25 @@ function characteralign.handler(originalhead,where)
current = getnext(current)
end
end
- local entry = list[row]
- if entry then
+ local predefined = dataset.predefined
+ local before, after
+ if predefined then
+ before = b_start and list_dimensions(b_start,getnext(b_stop)) or 0
+ after = a_start and list_dimensions(a_start,getnext(a_stop)) or 0
+ else
+ local entry = list[row]
+ if entry then
+ before = entry.before or 0
+ after = entry.after or 0
+ else
+ before = b_start and list_dimensions(b_start,getnext(b_stop)) or 0
+ after = a_start and list_dimensions(a_start,getnext(a_stop)) or 0
+ list[row] = {
+ before = before,
+ after = after,
+ }
+ return tonode(head), true
+ end
if not dataset.collected then
-- print("[maxbefore] [maxafter]")
local maxbefore = 0
@@ -330,61 +356,53 @@ function characteralign.handler(originalhead,where)
dataset.maxafter = maxafter
dataset.collected = true
end
- local maxbefore = dataset.maxbefore
- local maxafter = dataset.maxafter
- local before = entry.before or 0
- local after = entry.after or 0
- local new_kern = trace_split and traced_kern or new_kern
- if b_start then
- if before < maxbefore then
- head = insert_node_before(head,b_start,new_kern(maxbefore-before))
- end
- if not c then
- -- print("[before]")
- if dataset.hasseparator then
- local width = fontcharacters[getfont(b_stop)][separator].width
- insert_node_after(head,b_stop,new_kern(maxafter+width))
- end
- elseif a_start then
- -- print("[before] [separator] [after]")
- if after < maxafter then
- insert_node_after(head,a_stop,new_kern(maxafter-after))
- end
- else
- -- print("[before] [separator]")
- if maxafter > 0 then
- insert_node_after(head,c,new_kern(maxafter))
- end
+ end
+ local maxbefore = dataset.maxbefore
+ local maxafter = dataset.maxafter
+ local new_kern = trace_split and traced_kern or new_kern
+ if b_start then
+ if before < maxbefore then
+ head = insert_node_before(head,b_start,new_kern(maxbefore-before))
+ end
+ if not c then
+ -- print("[before]")
+ if dataset.hasseparator then
+ local width = fontcharacters[getfont(b_start)][separator].width
+ insert_node_after(head,b_stop,new_kern(maxafter+width))
end
elseif a_start then
- if c then
- -- print("[separator] [after]")
- if maxbefore > 0 then
- head = insert_node_before(head,c,new_kern(maxbefore))
- end
- else
- -- print("[after]")
- local width = fontcharacters[getfont(b_stop)][separator].width
- head = insert_node_before(head,a_start,new_kern(maxbefore+width))
- end
+ -- print("[before] [separator] [after]")
if after < maxafter then
insert_node_after(head,a_stop,new_kern(maxafter-after))
end
- elseif c then
- -- print("[separator]")
- if maxbefore > 0 then
- head = insert_node_before(head,c,new_kern(maxbefore))
- end
+ else
+ -- print("[before] [separator]")
if maxafter > 0 then
insert_node_after(head,c,new_kern(maxafter))
end
end
- else
- entry = {
- before = b_start and list_dimensions(b_start,getnext(b_stop)) or 0,
- after = a_start and list_dimensions(a_start,getnext(a_stop)) or 0,
- }
- list[row] = entry
+ elseif a_start then
+ if c then
+ -- print("[separator] [after]")
+ if maxbefore > 0 then
+ head = insert_node_before(head,c,new_kern(maxbefore))
+ end
+ else
+ -- print("[after]")
+ local width = fontcharacters[getfont(b_stop)][separator].width
+ head = insert_node_before(head,a_start,new_kern(maxbefore+width))
+ end
+ if after < maxafter then
+ insert_node_after(head,a_stop,new_kern(maxafter-after))
+ end
+ elseif c then
+ -- print("[separator]")
+ if maxbefore > 0 then
+ head = insert_node_before(head,c,new_kern(maxbefore))
+ end
+ if maxafter > 0 then
+ insert_node_after(head,c,new_kern(maxafter))
+ end
end
return tonode(head), true
end
diff --git a/tex/context/base/mkiv/typo-tal.mkiv b/tex/context/base/mkiv/typo-tal.mkiv
index 5ac0eeea4..7170578d1 100644
--- a/tex/context/base/mkiv/typo-tal.mkiv
+++ b/tex/context/base/mkiv/typo-tal.mkiv
@@ -56,10 +56,11 @@
% D
% D \typebuffer \blank \getbuffer \blank
-\unexpanded\def\signalcharacteralign#1#2{\attribute\characteralignattribute\numexpr#1*\maxcardminusone+#2\relax} % 0xFFFF
-\unexpanded\def\setcharacteralign #1#2{\clf_setcharacteralign#1{#2}}
-\unexpanded\def\resetcharacteralign {\clf_resetcharacteralign}
-\unexpanded\def\nocharacteralign {\attribute\characteralignattribute\attributeunsetvalue}
+\unexpanded\def\signalcharacteralign #1#2{\attribute\characteralignattribute\numexpr#1*\maxcardminusone+#2\relax} % 0xFFFF
+\unexpanded\def\setcharacteralign #1#2{\clf_setcharacteralign#1{#2}}
+\unexpanded\def\resetcharacteralign {\clf_resetcharacteralign}
+\unexpanded\def\nocharacteralign {\attribute\characteralignattribute\attributeunsetvalue}
+\unexpanded\def\setcharacteraligndetail#1#2#3#4{\clf_setcharacteraligndetail#1{#2}#3#4\relax}
%D Mostly downward compatible:
%D
@@ -73,18 +74,54 @@
%D \stopbuffer
%D
%D \typebuffer \blank \getbuffer \blank
-
+%D
+%D \startbuffer
+%D \startcharacteralign[leftsample=123.456,rightsample=00,character={,}]
+%D \checkcharacteralign{123.456,78}\par
+%D \checkcharacteralign {456}\par
+%D \checkcharacteralign {23.456}\par
+%D \checkcharacteralign {78,9}\par
+%D \checkcharacteralign {78}\par
+%D \stopcharacteralign
+%D \stopbuffer
+%D
+%D \typebuffer \blank \getbuffer \blank
+%D
+%D \startbuffer
+%D \startcharacteralign[leftwidth=123.456,rightwidth=00,character={,}]
+%D \checkcharacteralign{123.456,78}\par
+%D \checkcharacteralign {456}\par
+%D \checkcharacteralign {23.456}\par
+%D \checkcharacteralign {78,9}\par
+%D \checkcharacteralign {78}\par
+%D \stopcharacteralign
+%D \stopbuffer
+%D
+%D \typebuffer \blank \getbuffer \blank
+%D
%D We have (currently) two modes: \type {text} and \type {number}. The handler tries
%D to determine the mode automatically. When using periods and commas as separators
%D the \type {number} mode is chosen. If you use for instance a \type {-} as
%D separator, \type {text} is chosen, but you can enforce \type {number} with \type
-%D {number->-} (as with other mechanisms, the arrow indicates a methot to apply).
+%D {number->-} (as with other mechanisms, the arrow indicates a method to apply).
%D
%D One can use \type {\nocharacteralign} to disable this mechanism, for instance in
%D a table cell.
\def\alignmentcharacter{,}
+\installcorenamespace{characteralign}
+
+\installparameterhandler\??characteralign {characteralign}
+\installsetuphandler \??characteralign {characteralign}
+
+\setupcharacteralign
+ [\c!leftwidth =\zeropoint,
+ \c!rightwidth =\zeropoint,
+ \c!leftsample =,
+ \c!rightsample=,
+ \c!character =\alignmentcharacter]
+
\unexpanded\def\typo_charalign_pass_one
{\advance\scratchcounter\plusone
\setbox\scratchbox\typo_charalign_pass}
@@ -99,13 +136,71 @@
\unexpanded\def\startcharacteralign
{\dosingleempty\typo_charalign_start}
-\def\typo_charalign_start[#1]#2\stopcharacteralign
+\def\typo_charalign_start[#1]%
+ {\doifelseassignment{#1}\typo_charalign_start_one\typo_charalign_start_two{#1}}
+
+\def\typo_charalign_start_one#1#2\stopcharacteralign
+ {\bgroup
+ % for now no instances
+ \setupcurrentcharacteralign[#1]%
+ \edef\p_left {\characteralignparameter\c!leftsample}%
+ \edef\p_right{\characteralignparameter\c!rightsample}%
+ \ifx\p_left\empty
+ \scratchdimenone\dimexpr\characteralignparameter\c!leftwidth\relax
+ \else
+ \setbox\scratchbox\hbox{\p_left}%
+ \scratchdimenone\wd\scratchbox
+ \fi
+ \ifx\p_right\empty
+ \scratchdimentwo\dimexpr\characteralignparameter\c!rightwidth\relax
+ \else
+ \setbox\scratchbox\hbox{\p_right}%
+ \scratchdimentwo\wd\scratchbox
+ \fi
+ \ifzeropt\scratchdimenone
+ \ifzeropt\scratchdimentwo
+ \donefalse
+ \else
+ \donetrue
+ \fi
+ \else
+ \donetrue
+ \fi
+ \edef\alignmentcharacter{\characteralignparameter\c!character}%
+ \ifdone
+ \clf_setcharacteraligndetail
+ \plusone
+ \alignmentcharacter
+ \scratchdimenone
+ \scratchdimentwo
+ \else
+ \clf_setcharacteralign
+ \plusone
+ \alignmentcharacter
+ \begingroup
+ \scratchcounter\zerocount
+ \let\checkcharacteralign\typo_charalign_pass_one
+ \settrialtypesetting
+ #2\relax
+ \endgroup
+ \fi
+ \begingroup
+ \scratchcounter\zerocount
+ \let\checkcharacteralign\typo_charalign_pass_two
+ #2\relax
+ \endgroup
+ \resetcharacteralign
+ \egroup}
+
+\def\typo_charalign_start_two#1#2\stopcharacteralign
{\bgroup
\edef\m_temp{#1}%
\ifx\m_temp\empty \else
\let\alignmentcharacter\m_temp
\fi
- \setcharacteralign\plusone\alignmentcharacter
+ \clf_setcharacteralign
+ \plusone
+ \alignmentcharacter
\begingroup
\scratchcounter\zerocount
\let\checkcharacteralign\typo_charalign_pass_one
diff --git a/tex/context/base/mkiv/util-evo-imp-server.lua b/tex/context/base/mkiv/util-evo-imp-server.lua
new file mode 100644
index 000000000..31d779102
--- /dev/null
+++ b/tex/context/base/mkiv/util-evo-imp-server.lua
@@ -0,0 +1,127 @@
+if not modules then modules = { } end modules ['util-imp-evohome-server'] = {
+ version = 1.002,
+ comment = "simple server for simple evohome extensions",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE",
+ license = "see context related readme files"
+}
+
+local P, C, patterns, lpegmatch = lpeg.P, lpeg.C, lpeg.patterns, lpeg.match
+local urlhashed, urlquery, urlunescapeget = url.hashed, url.query, url.unescapeget
+local ioflush = io.flush
+
+local newline = patterns.newline
+local spacer = patterns.spacer
+local whitespace = patterns.whitespace
+local method = P("GET")
+ + P("POST")
+local identify = (1-method)^0
+ * C(method)
+ * spacer^1
+ * C((1-spacer)^1)
+ * spacer^1
+ * P("HTTP/")
+ * (1-whitespace)^0
+ * C(P(1)^0)
+
+do
+
+ local loaded = package.loaded
+
+ if not loaded.socket then loaded.socket = loaded["socket.core"] end
+ if not loaded.mime then loaded.mime = loaded["mime.core"] end
+
+end
+
+local evohome = require("util-evo")
+ require("trac-lmx")
+
+local report = logs.reporter("evohome","server")
+local convert = lmx.convert
+
+function evohome.server(specification)
+
+ local filename = specification.filename
+
+ if not filename then
+ report("unable to run server, no filename given")
+ return
+ end
+
+ local step, process, presets = evohome.actions.poller(filename)
+
+ if not (step and process and presets) then
+ report("unable to run server, invalid presets")
+ return
+ end
+
+ local template = presets.files.template
+
+ if not template then
+ report("unable to run server, no template given")
+ return
+ end
+
+ local port = specification.port or (presets.server and presets.server.port) or 806
+ local host = specification.host or (presets.server and presets.server.host) or "*"
+
+ package.extraluapath(presets.filepath)
+
+ local socket = socket or require("socket")
+ local copas = copas or require("copas")
+
+ local function copashttp(skt)
+ local client = copas.wrap(skt)
+ local request, e = client:receive()
+ if not e then
+ local method, fullurl, body = lpegmatch(identify,request)
+ if method ~= "" and fullurl ~= "" then
+ local fullurl = urlunescapeget(fullurl)
+ local hashed = urlhashed(fullurl)
+ process(hashed.queries or { })
+ ioflush()
+ end
+ -- todo: split off css and use that instead of general one, now too much
+ local content = convert(presets.results and presets.results.template or template,false,presets)
+ if not content then
+ report("error in converting template")
+ content = "error in template"
+ end
+ client:send("HTTP/1.1 200 OK\r\n")
+ client:send("Connection: close\r\n")
+ client:send("Content-Length: " .. #content .. "\r\n")
+ client:send("Content-Type: text/html\r\n")
+ client:send("Location: " .. host .. "\r\n")
+ client:send("Cache-Control: no-cache, no-store, must-revalidate, max-age=0\r\n")
+ client:send("\r\n")
+ client:send(content)
+ client:send("\r\n")
+ client:close()
+ end
+ end
+
+ local function copaspoll()
+ while step do
+ local delay = step()
+ if type(delay) == "number" then
+ copas.sleep(delay or 0)
+ end
+ end
+ end
+
+ local server = socket.bind(host,port)
+
+ if server then
+ report("server started at %s:%s",host,port)
+ ioflush()
+ copas.addserver(server,copashttp)
+ copas.addthread(copaspoll)
+ copas.loop()
+ else
+ report("unable to start server at %s:%s",host,port)
+ os.exit()
+ end
+
+end
+
+return evohome
diff --git a/tex/context/base/mkiv/util-evo.lua b/tex/context/base/mkiv/util-evo.lua
index eeaad5843..25ad7f94d 100644
--- a/tex/context/base/mkiv/util-evo.lua
+++ b/tex/context/base/mkiv/util-evo.lua
@@ -14,88 +14,176 @@ if not modules then modules = { } end modules ['util-evo'] = {
-- later). Anyway, apart from integrating it into my home automation setup so that I
-- can add control based on someone present in a zone, I wanted to be able to render
-- statistics. So that's why we have a module in ConTeXt for doing that. It's also
--- an example of Lua.
+-- an example of Lua and abusing LuaTeX for something not related to typesetting.
--
-- As with other scripts, it assumes that mtxrun is used so that we have the usual
--- libraries present.
+-- Lua libraries present.
--
-- The code is not that complex but figuring out the right request takes bit of
-- searching the web. There is an api specification at:
--
--- https://developer.honeywell.com/api-methods?field_smart_method_tags_tid=All
+-- https://developer.honeywell.com/api-methods?field_smart_method_tags_tid=All
--
--- Details like the application id can be found in several places. There are
--- snippets of (often partial or old) code on discussion platforms so in the one can
--- get there.
+-- Details like the application id can be found in several places. There are snippets
+-- of (often partial or old) code on the web but still one needs to experiment and
+-- combine information. We assume unique zone names and ids across gateways; I only
+-- have one installed anyway.
+--
+-- The original application was to just get the right information for generating
+-- statistics but in the meantime I also use this code to add additional functionality
+-- to the system, for instance switching between rooms (office, living room, attic) and
+-- absence for one or more rooms.
--- todo: load everything and keep it in mem and only save it when there are changes
--- todo: use a temp files per month
-- todo: %path% in filenames
require("util-jsn")
+local next, type, setmetatable, rawset, rawget = next, type, setmetatable, rawset, rawget
local json = utilities.json
local formatters = string.formatters
local floor, div = math.floor, math.div
local resultof, ostime, osdate, ossleep = os.resultof, os.time, os.date, os.sleep
local jsontolua, jsontostring = json.tolua, json.tostring
-local savetable, loadtable = table.save, table.load
-local setmetatableindex = table.setmetatableindex
+local savetable, loadtable, sortedkeys = table.save, table.load, table.sortedkeys
+local setmetatableindex, setmetatablenewindex = table.setmetatableindex, table.setmetatablenewindex
local replacer = utilities.templates.replacer
+local lower = string.lower -- no utf support yet (encoding needs checking in evohome)
local applicationid = "b013aa26-9724-4dbd-8897-048b9aada249"
----- applicationid = "91db1612-73fd-4500-91b2-e63b069b185c"
local report = logs.reporter("evohome")
+local trace = false
+
+trackers.register("evohome.trace",function(v) trace = v end) -- not yet used
local defaultpresets = {
interval = 30 * 60,
+ files = {
+ everything = "evohome-everything.lua",
+ history = "evohome-history.lua",
+ latest = "evohome-latest.lua",
+ schedules = "evohome-schedules.lua",
+ actions = "evohome-actions.lua",
+ template = "evohome.lmx",
+ },
credentials = {
-- username = "unset",
-- password = "unset",
-- accesstoken = "unset",
-- userid = "unset",
},
- -- everything = "evohome-everything",
- -- history = "evohome-history",
}
+local function validfile(presets,filename)
+ if lfs.isfile(filename) then
+ -- we're okay
+ return filename
+ end
+ if file.pathpart(filename) ~= "" then
+ -- can be a file that has to be created
+ return filename
+ end
+ local presetsname = presets.filename
+ if not presetsname then
+ -- hope for the best
+ return filename
+ end
+ -- we now have the full path
+ return file.join(file.pathpart(presetsname),filename)
+end
+
local function validpresets(presets)
- if type(presets == "table") and presets.credentials then
- setmetatableindex(presets,defaultpresets)
- setmetatableindex(presets.credentials,defaultpresets.credentials)
- return presets
- else
- report("invalid presets")
+ if type(presets) ~= "table" then
+ report("invalid presets, no table")
+ return
+ end
+ local credentials = presets.credentials
+ if not credentials then
+ report("invalid presets, no credentials")
+ return
+ end
+ local gateways = presets.gateways
+ if not gateways then
+ report("invalid presets, no gateways")
+ return
+ end
+ local files = presets.files
+ if not files then
+ report("invalid presets, no files")
+ return
+ end
+ for k, v in next, files do
+ files[k] = validfile(presets,v) or v
end
+ local data = presets.data
+ if not data then
+ data = { }
+ presets.data = data
+ end
+ local g = data.gateways
+ if not g then
+ local g = { }
+ data.gateways = g
+ for i=1,#gateways do
+ local gi = gateways[i]
+ g[gi.macaddress] = gi
+ end
+ end
+ local zones = data.zones
+ if not zones then
+ zones = { }
+ data.zones = zones
+ setmetatablenewindex(zones,function(t,k,v) rawset(t,lower(k),v) end)
+ setmetatableindex (zones,function(t,k) return rawget(t,lower(k)) end)
+ end
+ local states = data.states
+ if not states then
+ states = { }
+ data.states = states
+ setmetatablenewindex(states,function(t,k,v) rawset(t,lower(k),v) end)
+ setmetatableindex (states,function(t,k) return rawget(t,lower(k)) end)
+ end
+ setmetatableindex(presets,defaultpresets)
+ setmetatableindex(credentials,defaultpresets.credentials)
+ setmetatableindex(files,defaultpresets.files)
+ return presets
end
local function loadedtable(filename)
- for i=1,10 do
- local t = loadtable(filename)
- if t then
- return t
- else
- ossleep(1/4)
+ if type(filename) == "string" then
+ for i=1,10 do
+ local t = loadtable(filename)
+ if t then
+ return t
+ else
+ ossleep(1/4)
+ end
end
end
return { }
end
local function loadpresets(filename)
- return loadtable(filename)
+ local presets = loadtable(filename)
+ if presets then
+ presets.filename = filename
+ presets.filepath = file.expandname(file.pathpart(filename))
+ -- package.extraluapath(presets.filepath) -- better do that elsewhere and once
+ end
+ return presets
end
local function loadhistory(filename)
- if type(filename) == "table" then
- filename = filename.history
+ if type(filename) == "table" and validpresets(filename) then
+ filename = filename.files and filename.files.history
end
return loadedtable(filename)
end
local function loadeverything(filename)
- if type(filename) == "table" then
- filename = filename.everything
+ if type(filename) == "table" and validpresets(filename) then
+ filename = filename.files and filename.files.everything
end
return loadedtable(filename)
end
@@ -137,9 +225,9 @@ local function getaccesstoken(presets)
}
local r = s and resultof(s)
local t = r and jsontolua(r)
- return result(t,"getting access token: %s")
+ return result(t,"getting access token %a")
end
- return result(false,"getting access token: %s")
+ return result(false,"getting access token %a")
end
local f = replacer (
@@ -160,9 +248,9 @@ local function getuserinfo(presets)
}
local r = s and resultof(s)
local t = r and jsontolua(r)
- return result(t,"getting user info: %s")
+ return result(t,"getting user info for %a")
end
- return result(false,"getting user info: %s")
+ return result(false,"getting user info for %a")
end
local f = replacer (
@@ -184,9 +272,9 @@ local function getlocationinfo(presets)
}
local r = s and resultof(s)
local t = r and jsontolua(r)
- return result(t,"getting location info: %s")
+ return result(t,"getting location info for %a")
end
- return result(false,"getting location info: %s")
+ return result(false,"getting location info for %a")
end
local f = replacer (
@@ -198,19 +286,22 @@ local f = replacer (
[["https://tccna.honeywell.com/WebAPI/emea/api/v1/temperatureZone/%zoneid%/schedule"]]
)
-local function getschedule(presets,zoneid,zonename)
- if zoneid and validpresets(presets) then
- local c = presets.credentials
- local s = c and f {
- accesstoken = c.accesstoken,
- applicationid = applicationid,
- zoneid = zoneid,
- }
- local r = s and resultof(s)
- local t = r and jsontolua(r)
- return result(t,"getting schedule for zone %s: %s",zonename or "?")
+local function getschedule(presets,zonename)
+ if validpresets(presets) then
+ local zoneid = presets.data.zones[zonename].zoneId
+ if zoneid then
+ local c = presets.credentials
+ local s = c and f {
+ accesstoken = c.accesstoken,
+ applicationid = applicationid,
+ zoneid = zoneid,
+ }
+ local r = s and resultof(s)
+ local t = r and jsontolua(r)
+ return result(t,"getting schedule for zone %a, %s",zonename or "?")
+ end
end
- return result(false,"getting schedule for zone %s: %s",zonename or "?")
+ return result(false,"getting schedule for zone %a, %s",zonename or "?")
end
local f = replacer (
@@ -232,29 +323,128 @@ local function getstatus(presets,locationid,locationname)
}
local r = s and resultof(s)
local t = r and jsontolua(r)
- return result(t and t.gateways and t,"getting status for location %s: %s",locationname or "?")
+ return result(t and t.gateways and t,"getting status for location %a, %s",locationname or "?")
end
- return result(false,"getting status for location %s: %s",locationname or "?")
+ return result(false,"getting status for location %a, %s",locationname or "?")
end
local function validated(presets)
if validpresets(presets) then
- local data = getaccesstoken(presets)
- if data then
- presets.credentials.accesstoken = data.access_token
- local data = getuserinfo(presets)
+ local data = getlocationinfo(presets)
+ if data and type(data) == "table" and data[1] and data[1].locationInfo then
+ return true
+ else
+ local data = getaccesstoken(presets)
if data then
- presets.credentials.userid = data.userId
- return true
+ presets.credentials.accesstoken = data.access_token
+ local data = getuserinfo(presets)
+ if data then
+ presets.credentials.userid = data.userId
+ return true
+ end
+ end
+ end
+ end
+end
+
+local function findzone(presets,name)
+ if not presets then
+ return
+ end
+ local data = presets.data
+ if not data then
+ return
+ end
+ local usedzones = data.zones
+ return usedzones and usedzones[name]
+end
+
+local function gettargets(zone) -- maybe also for a day
+ local schedule = zone.schedule
+ local min = false
+ local max = false
+ if schedule then
+ local schedules = schedule.dailySchedules
+ if schedules then
+ for i=1,#schedules do
+ local switchpoints = schedules[i].switchpoints
+ for i=1,#switchpoints do
+ local m = switchpoints[i].temperature
+ if not min or m < min then
+ min = m
+ end
+ if not max or m > max then
+ max = m
+ end
+ end
+ end
+ else
+ report("zone %a has no schedule",name)
+ end
+ end
+ return min, max
+end
+
+local function updatezone(presets,name,zone)
+ if not zone then
+ zone = findzone(presets,name)
+ end
+ if zone then
+ local oldtarget = presets.data.states[name]
+ local min = zone.heatSetpointCapabilities.minHeatSetpoint or 5
+ local max = zone.heatSetpointCapabilities.maxHeatSetpoint or 12
+ local mintarget, maxtarget = gettargets(zone)
+ -- todo: maybe get these from presets
+ if mintarget == false then
+ if min < 5 then
+ mintarget = 5
+ -- report("zone %a, min target limited to %a",name,mintarget)
+ else
+ mintarget = min
+ end
+ end
+ if maxtarget == false then
+ if max > 18.5 then
+ maxtarget = 18.5
+ -- report("zone %a, max target limited to %a",name,maxtarget)
+ else
+ maxtarget = max
end
end
+ local current = zone.temperatureStatus.temperature or 0
+ local target = zone.heatSetpointStatus.targetTemperature
+ local mode = zone.heatSetpointStatus.setpointMode
+ local state = (mode == "FollowSchedule" and "schedule" ) or
+ (mode == "PermanentOverride" and target <= mintarget and "permanent") or
+ (mode == "TemporaryOverride" and target <= mintarget and "off" ) or
+ (mode == "TemporaryOverride" and target >= maxtarget and "on" ) or
+ ( "unknown" )
+ local t = {
+ name = zone.name,
+ id = zone.zoneId,
+ schedule = zone.schedule,
+ mode = mode,
+ current = current,
+ target = target,
+ min = min,
+ max = max,
+ state = state,
+ lowest = mintarget,
+ highest = maxtarget,
+ }
+ -- report("zone %a, current %a, target %a",name,current,target)
+ presets.data.states[name] = t
+ return t
end
end
-local function geteverything(presets,filename)
+
+local function geteverything(presets,noschedules)
if validated(presets) then
local data = getlocationinfo(presets)
if data then
+ local usedgateways = presets.data.gateways
+ local usedzones = presets.data.zones
for i=1,#data do
local gateways = data[i].gateways
local locationinfo = data[i].locationInfo
@@ -263,48 +453,63 @@ local function geteverything(presets,filename)
local status = getstatus(presets,locationid,locationinfo.name)
if status then
for i=1,#gateways do
- local g = status.gateways[i]
- local gateway = gateways[i]
- local systems = gateway.temperatureControlSystems
- if systems then
- local s = g.temperatureControlSystems
- for i=1,#systems do
- local zones = systems[i].zones
- if zones then
- local z = s[i].zones
- for i=1,#zones do
- local zone = zones[i]
- if zone.zoneType == "ZoneTemperatureControl" then
- local z = z[i]
- zone.schedule = getschedule(presets,zone.zoneId,zone.name)
- if z.name == zone.name then
- zone.heatSetpointStatus = z.heatSetpointStatus
- zone.temperatureStatus = z.temperatureStatus
+ local gatewaystatus = status.gateways[i]
+ local gatewayinfo = gateways[i]
+ local gatewaysystems = gatewayinfo.temperatureControlSystems
+ local info = gatewayinfo.gatewayInfo
+ local statussystems = gatewaystatus.temperatureControlSystems
+ if gatewaysystems and statussystems and info then
+ local mac = info.mac
+ if usedgateways[mac] then
+ report("%s gateway with mac address %a","using",mac)
+ for j=1,#gatewaysystems do
+ local gatewayzones = gatewaysystems[j].zones
+ local zonestatus = statussystems[j].zones
+ if gatewayzones and zonestatus then
+ for k=1,#gatewayzones do
+ local zonestatus = zonestatus[k]
+ local gatewayzone = gatewayzones[k]
+ if zonestatus and gatewayzone then
+ local zonename = zonestatus.name
+ local zoneid = zonestatus.zoneId
+ if gatewayzone.zoneType == "ZoneTemperatureControl" and zonename == gatewayzone.name then
+ gatewayzone.heatSetpointStatus = zonestatus.heatSetpointStatus
+ gatewayzone.temperatureStatus = zonestatus.temperatureStatus
+ local zonestatus = usedzones[zonename] -- findzone(states,zonename)
+ local schedule = zonestatus and zonestatus.schedule
+ usedzones[zonename] = gatewayzone
+ if schedule and noschedules then
+ gatewayzone.schedule = schedule
+ else
+ gatewayzone.schedule = getschedule(presets,zonename)
+ end
+ updatezone(presets,zonename,gatewayzone)
+ end
end
end
end
end
+ else
+ report("%s gateway with mac address %a","skipping",mac)
end
end
end
end
end
end
- if not filename then
- filename = presets.everything
- end
- if filename then
- savetable(filename,data)
- end
- return result(data,"getting everything: %s")
+ savetable(presets.files.everything,data)
+ return result(data,"getting everything, %s")
end
end
- return result(false,"getting everything: %s")
+ return result(false,"getting everything, %s")
end
-local function gettemperatures(presets,filename)
+local function gettemperatures(presets)
if validated(presets) then
- local data = loadeverything(filename or presets)
+ local data = loadeverything(presets)
+ if not data or not next(data) then
+ data = geteverything(presets)
+ end
if data then
local updated = false
for i=1,#data do
@@ -341,14 +546,14 @@ local function gettemperatures(presets,filename)
end
end
end
- if updated and filename then
+ if updated then
data.time = ostime()
- savetable(filename,data)
+ savetable(presets.files.latest,data)
end
- return result(data,"getting temperatures: %s")
+ return result(data,"getting temperatures, %s")
end
end
- return result(false,"getting temperatures: %s")
+ return result(false,"getting temperatures, %s")
end
local function setmoment(target,time,data)
@@ -389,98 +594,72 @@ local function setmoment(target,time,data)
}
end
-local function loadtemperatures(filename)
- local status = loadeverything(filename)
- if status then
- setmetatable(status,mt)
- local zones = status[1].gateways[1].temperatureControlSystems[1].zones
- if zones then
- local summary = { time = status.time }
- for i=1,#zones do
- local zone = zones[i]
- if zone.modelType == "HeatingZone" then
- local temperatureStatus = zone.temperatureStatus
- local heatSetpointCapabilities = zone.heatSetpointCapabilities
- local heatSetpointStatus = zone.heatSetpointStatus
- summary[#summary+1] = {
- name = zone.name,
- current = temperatureStatus and temperatureStatus .temperature or 0,
- min = heatSetpointCapabilities and heatSetpointCapabilities.minHeatSetpoint or 0,
- max = heatSetpointCapabilities and heatSetpointCapabilities.maxHeatSetpoint or 0,
- target = heatSetpointStatus and heatSetpointStatus .targetTemperature or 0,
- }
+local function loadtemperatures(presets)
+ if validpresets(presets) then
+ local status = loadeverything(presets)
+ if status then
+ local usedgateways = presets.data.gateways
+ for i=1,#status do
+ local gateways = status[i].gateways
+ if gateways then
+ for i=1,#gateways do
+ local gatewayinfo = gateways[i]
+ local systems = gatewayinfo.temperatureControlSystems
+ local info = gatewayinfo.gatewayInfo
+ if systems and info and usedgateways[info.mac] then
+ for i=1,#systems do
+ local zones = systems[i].zones
+ if zones then
+ local summary = { time = status.time }
+ for i=1,#zones do
+ local zone = zones[i]
+ if zone.zoneType == "ZoneTemperatureControl" then
+ summary[#summary+1] = updatezone(presets,zone.name,zone)
+ end
+ end
+ return result(summary,"loading temperatures, %s")
+ end
+ end
+ end
+ end
end
end
- return result(summary,"loading temperatures: %s")
end
end
- return result(false,"loading temperatures: %s")
+ return result(false,"loading temperatures, %s")
end
-local function updatetemperatures(presets,filename,historyname)
+local function updatetemperatures(presets)
if validpresets(presets) then
- if not filename then
- filename = presets.everything
- end
- if not historyname then
- historyname = presets.history
- end
- gettemperatures(presets,filename)
- local t = loadtemperatures(filename)
- if t then
- local data = { }
- for i=1,#t do
- local ti = t[i]
- data[ti.name] = ti.current
- end
- local history = loadhistory(historyname) or { }
- setmoment(history,ostime(),data)
- savetable(historyname,history)
- return result(t,"updating temperatures: %s")
- end
- end
- return result(false,"updating temperatures: %s")
-end
-
-local mt = { __index = { [1] = { gateways = { [1] = { temperatureControlSystems = { [1] = { } } } } } } }
-
-local function findzone(status,name)
- if status then
- setmetatable(status,mt)
- local zones = status[1].gateways[1].temperatureControlSystems[1].zones
- if zones then
- for i=1,#zones do
- local zone = zones[i]
- if zone.modelType == "HeatingZone" and zone.name == name then
- return zone
+ local everythingname = presets.files.everything
+ local historyname = presets.files.history
+ if everythingname and historyname then
+ gettemperatures(presets,everythingname)
+ local t = loadtemperatures(presets)
+ if t then
+ local data = { }
+ for i=1,#t do
+ local ti = t[i]
+ data[ti.name] = ti.current
end
+ local history = loadhistory(historyname) or { }
+ setmoment(history,ostime(),data)
+ savetable(historyname,history)
+ return result(t,"updating temperatures, %s")
end
end
end
+ return result(false,"updating temperatures, %s")
end
-local function getzonestate(filename,name)
- local status = loadeverything(filename)
- local zone = findzone(status,name)
- if zone then
- local t = {
- name = zone.name,
- current = zone.temperatureStatus.temperature or 0,
- min = zone.heatSetpointCapabilities.minHeatSetpoint,
- max = zone.heatSetpointCapabilities.maxHeatSetpoint,
- target = zone.heatSetpointStatus.targetTemperature,
- mode = zone.heatSetpointStatus.setpointMode,
- schedule = zone.schedule,
- }
- return result(t,"getting state of zone %s: %s",name)
- end
- return result(false,"getting state of zone %s: %s",name)
+local function getzonestate(presets,name)
+ return validpresets(presets) and presets.data.states[name]
end
local f = replacer (
[[curl ]] ..
- [[-X PUT ]] ..
[[--silent --insecure ]] ..
+ [[-X PUT ]] ..
[[-H "Authorization: bearer %accesstoken%" ]] ..
[[-H "Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml" ]] ..
[[-H "applicationId: %applicationid%" ]] ..
@@ -489,62 +668,330 @@ local f = replacer (
[["https://tccna.honeywell.com/WebAPI/emea/api/v1/temperatureZone/%zoneid%/heatSetpoint"]]
)
-local function setzonestate(presets,name,temperature)
- if validated(presets) then
- local data = loadeverything(presets)
- local zone = findzone(data,name)
- if zone then
- local m = type(temperature) == "number" and temperature > 0 and
- {
+local function untilmidnight()
+ local t = osdate("*t")
+ t.hour = 23
+ t.min = 59
+ t.sec = 59
+ return osdate("%Y-%m-%dT%H:%M:%SZ",ostime(t))
+end
+
+local followschedule = {
+ -- HeatSetpointValue = 0,
+ SetpointMode = "FollowSchedule",
+}
+
+local function setzonestate(presets,name,temperature,permanent)
+ local zone = findzone(presets,name)
+ if zone then
+ local m = followschedule
+ if type(temperature) == "number" and temperature > 0 then
+ if permanent then
+ m = {
HeatSetpointValue = temperature,
- SetpointMode = "TemporaryOverride",
- TimeUntil = osdate("%Y-%m-%dT%H:%M:%SZ",os.time() + 60*60),
+ SetpointMode = "PermanentOverride",
}
- or
- {
- HeatSetpointValue = 0,
- SetpointMode = "FollowSchedule",
+ else
+ m = {
+ HeatSetpointValue = temperature,
+ SetpointMode = "TemporaryOverride",
+ TimeUntil = untilmidnight(),
}
+ end
+ end
+ local s = f {
+ accesstoken = presets.credentials.accesstoken,
+ applicationid = applicationid,
+ zoneid = zone.zoneId,
+ settings = jsontostring(m),
+ }
+ local r = s and resultof(s)
+ local t = r and jsontolua(r)
+-- inspect(r)
+-- inspect(t)
+ return result(t,"setting state of zone %a, %s",name)
+ end
+ return result(false,"setting state of zone %a, %s",name)
+end
- local s = f {
- accesstoken = presets.credentials.accesstoken,
- applicationid = applicationid,
- zoneid = zone.zoneId,
- settings = jsontostring(m),
+local function resetzonestate(presets,name)
+ setzonestate(presets,name)
+end
+
+--
+
+local function update(presets,noschedules)
+ local everything = geteverything(presets,noschedules)
+ if everything then
+ presets.data.everything = everything
+ return presets
+ end
+end
+
+local function initialize(filename)
+ local presets = loadpresets(filename)
+ if presets then
+ return update(presets)
+ end
+end
+
+local function off(presets,name)
+ local zone = presets and getzonestate(presets,name)
+ if zone then
+ setzonestate(presets,name,zone.lowest)
+ end
+end
+
+local function on(presets,name)
+ local zone = presets and getzonestate(presets,name)
+ if zone then
+ setzonestate(presets,name,zone.highest)
+ end
+end
+
+local function schedule(presets,name)
+ local zone = presets and getzonestate(presets,name)
+ if zone then
+ resetzonestate(presets,name)
+ end
+end
+
+local function permanent(presets,name)
+ local zone = presets and getzonestate(presets,name)
+ if zone then
+ setzonestate(presets,name,zone.lowest,true)
+ end
+end
+
+-- tasks
+
+local function settask(presets,when,tag,action)
+ if when == "tomorrow" then
+ local list = presets.scheduled
+ if not list then
+ list = loadtable(presets.files.schedules) or { }
+ presets.scheduled = list
+ end
+ if action then
+ list[tag] = {
+ time = ostime() + 24*60*60,
+ done = false,
+ category = category,
+ action = action,
}
- local r = s and resultof(s)
- local t = r and jsontolua(r)
- return result(t,"setting state of zone %s: %s",name)
+ else
+ list[tag] = nil
+ end
+ savetable(presets.files.schedules,list)
+ end
+end
+
+local function gettask(presets,when,tag)
+ if when == "tomorrow" then
+ local list = presets.scheduled
+ if not list then
+ list = loadtable(presets.files.schedules) or { }
+ presets.scheduled = list
+ end
+ return list[tag]
+ end
+end
+
+local function resettask(presets,when,tag)
+ settask(presets,when,tag)
+end
+
+local function checktasks(presets)
+ local list = presets.scheduled
+ if not list then
+ list = loadtable(presets.files.schedules) or { }
+ presets.scheduled = list
+ end
+ if list then
+ local t = osdate("*t")
+ local q = { }
+ for k, v in next, list do
+ local d = osdate("*t",v.time)
+ if not v.done and d.year == t.year and d.month == t.month and d.day == t.day then
+ local a = v.action
+ if type(a) == "function" then
+ a()
+ end
+ v.done = true
+ end
+ if d.year <= t.year and d.month <= t.month and d.day < t.day then
+ q[k] = true
+ end
end
+ if next(q) then
+ for k, v in next, q do
+ list[q] = nil
+ end
+ savetable(presets.files.schedules,list)
+ end
+ return list
end
- return result(false,"setting state of zone %s: %s",name)
end
-local evohome = {
+-- predefined tasks
+
+local function settomorrow(presets,tag,action)
+ settask(presets,"tomorrow",tag,action)
+end
+
+local function resettomorrow(presets,tag)
+ settask(presets,"tomorrow",tag)
+end
+
+local function tomorrowset(presets,tag)
+ return gettask(presets,"tomorrow",tag) and true or false
+end
+
+--
+
+local evohome
+
+local function poller(presets)
+ --
+ if type(presets) ~= "string" then
+ report("invalid presets file")
+ os.exit()
+ end
+ report("loading presets from %a",presets)
+ local presets = loadpresets(presets)
+ if not validpresets(presets) then
+ report("invalid presets, aborting")
+ os.exit()
+ end
+ --
+ local actions = presets.files.actions
+ if type(actions) ~= "string" then
+ report("invalid actions file")
+ os.exit()
+ end
+ report("loading actions from %a",actions)
+ local actions = loadtable(actions)
+ if type(actions) ~= "table" then
+ report("invalid actions, aborting")
+ os.exit()
+ end
+ actions = actions.actions
+ if type(actions) ~= "table" then
+ report("invalid actions file, no actions subtable")
+ os.exit()
+ end
+ --
+ report("updating device status")
+ update(presets)
+ --
+ presets.report = report
+ presets.evohome = evohome
+ presets.results = { }
+ --
+ function presets.getstate(name)
+ return getzonestate(presets,name)
+ end
+ function presets.tomorrowset(name)
+ return tomorrowset(presets,name)
+ end
+ --
+ local template = actions.template or presets.files.template
+ --
+ local process = function(t)
+ local category = t.category
+ local action = t.action
+ if category and action then
+ local c = actions[category]
+ if c then
+ local a = c[action]
+ if type(a) == "function" then
+ report("category %a, action %a, executing",category,action)
+ presets.results.template = template -- can be overloaded by action
+ a(presets)
+ update(presets,true)
+ else
+ report("category %a, action %a, invalid action, known: %, t",category,action,sortedkeys(c))
+ end
+ else
+ report("category %a, action %a, invalid category, known categories: %, t",category,action,sortedkeys(actions))
+ end
+ else
+ -- logs.report("invalid category and action")
+ end
+ end
+ --
+ local delay = presets.delay or 10
+ local interval = 15 * 60 -- 15 minutes
+ local interval = 60 * 60 -- 60 minutes
+ local refresh = 5 * 60
+ local passed = 0
+ local step = function()
+ if passed > interval then
+ report("refreshing states, every %i seconds",interval)
+ -- todo: update stepwise as this also updates the schedules that we don't really
+ -- change often and definitely not in the middle of the night, so maybe just
+ -- update 9:00 12:00 15:00 18:00 21:00
+ update(presets)
+ passed = 0
+ else
+ passed = passed + delay
+ end
+ checktasks(presets)
+ return delay
+ end
+ --
+ presets.refreshtime = refresh
+ --
+ return step, process, presets
+end
+
+--
+
+evohome = {
helpers = {
- getaccesstoken = getaccesstoken,
- getuserinfo = getuserinfo,
- getlocationinfo = getlocationinfo,
- getschedule = getschedule,
+ getaccesstoken = getaccesstoken, -- presets
+ getuserinfo = getuserinfo, -- presets
+ getlocationinfo = getlocationinfo, -- presets
+ getschedule = getschedule, -- presets, name
+ --
+ geteverything = geteverything, -- presets, noschedules
+ gettemperatures = gettemperatures, -- presets
+ getzonestate = getzonestate, -- presets, name
+ setzonestate = setzonestate, -- presets, name, temperature
+ resetzonestate = resetzonestate, -- presets, name
+ getzonedata = findzone, -- presets, name
+ --
+ loadpresets = loadpresets, -- filename
+ loadhistory = loadhistory, -- presets | filename
+ loadeverything = loadeverything, -- presets | filename
+ loadtemperatures = loadtemperatures, -- presets | filename
+ --
+ updatetemperatures = updatetemperatures, -- presets
},
- geteverything = geteverything,
- gettemperatures = gettemperatures,
- getzonestate = getzonestate,
- setzonestate = setzonestate,
- loadtemperatures = loadtemperatures,
- updatetemperatures = updatetemperatures,
- loadpresets = loadpresets,
- loadhistory = loadhistory,
- loadeverything = loadeverything,
+ actions= {
+ initialize = initialize, -- filename
+ update = update, -- presets
+ --
+ off = off, -- presets, name
+ on = on, -- presets, name
+ schedule = schedule, -- presets, name
+ permanent = permanent, -- presets, name
+ --
+ settomorrow = settomorrow, -- presets, tag, function
+ resettomorrow = resettomorrow, -- presets, tag
+ tomorrowset = tomorrowset, -- presets, tag
+ --
+ poller = poller, -- presets
+ }
}
if utilities then
utilities.evohome = evohome
end
--- local presets = evohome.loadpresets("c:/data/develop/domotica/code/evohome-presets.lua")
--- evohome.setzonestate(presets,"Voorkamer",22)
--- evohome.setzonestate(presets,"Voorkamer")
+-- local presets = evohome.helpers.loadpresets("c:/data/develop/domotica/code/evohome-presets.lua")
+-- evohome.helpers.setzonestate(presets,"Voorkamer",22)
+-- evohome.helpers.setzonestate(presets,"Voorkamer")
return evohome
diff --git a/tex/context/base/mkiv/util-jsn.lua b/tex/context/base/mkiv/util-jsn.lua
index e75b5cf5d..e5f83e06c 100644
--- a/tex/context/base/mkiv/util-jsn.lua
+++ b/tex/context/base/mkiv/util-jsn.lua
@@ -21,7 +21,7 @@ local format = string.format
local utfchar = utf.char
local concat = table.concat
-local tonumber, tostring, rawset, type = tonumber, tostring, rawset, type
+local tonumber, tostring, rawset, type, next = tonumber, tostring, rawset, type, next
local json = utilities.json or { }
utilities.json = json
diff --git a/tex/context/base/mkiv/util-prs.lua b/tex/context/base/mkiv/util-prs.lua
index 650a7ead6..48d59a9f3 100644
--- a/tex/context/base/mkiv/util-prs.lua
+++ b/tex/context/base/mkiv/util-prs.lua
@@ -566,14 +566,16 @@ function parsers.rfc4180splitter(specification)
local field = escaped + non_escaped + Cc("")
local record = Ct(field * (separator * field)^1)
local headerline = record * Cp()
- local wholeblob = Ct((newline^(specification.strict and -1 or 1) * record)^0)
+ local morerecords = (newline^(specification.strict and -1 or 1) * record)^0
+ local headeryes = Ct(morerecords)
+ local headernop = Ct(record * morerecords)
return function(data,getheader)
if getheader then
local header, position = lpegmatch(headerline,data)
- local data = lpegmatch(wholeblob,data,position)
+ local data = lpegmatch(headeryes,data,position)
return data, header
else
- return lpegmatch(wholeblob,data)
+ return lpegmatch(headernop,data)
end
end
end
@@ -604,10 +606,10 @@ local cardinal = lpegpatterns.cardinal / tonumber
local spacers = lpegpatterns.spacer^0
local endofstring = lpegpatterns.endofstring
-local stepper = spacers * ( C(cardinal) * ( spacers * S(":-") * spacers * ( C(cardinal) + Cc(true) ) + Cc(false) )
+local stepper = spacers * ( cardinal * ( spacers * S(":-") * spacers * ( cardinal + Cc(true) ) + Cc(false) )
* Carg(1) * Carg(2) / ranger * S(", ")^0 )^1
-local stepper = spacers * ( C(cardinal) * ( spacers * S(":-") * spacers * ( C(cardinal) + (P("*") + endofstring) * Cc(true) ) + Cc(false) )
+local stepper = spacers * ( cardinal * ( spacers * S(":-") * spacers * ( cardinal + (P("*") + endofstring) * Cc(true) ) + Cc(false) )
* Carg(1) * Carg(2) / ranger * S(", ")^0 )^1 * endofstring -- we're sort of strict (could do without endofstring)
function parsers.stepper(str,n,action)
diff --git a/tex/context/base/mkiv/util-str.lua b/tex/context/base/mkiv/util-str.lua
index d938ee449..f15f291ee 100644
--- a/tex/context/base/mkiv/util-str.lua
+++ b/tex/context/base/mkiv/util-str.lua
@@ -12,11 +12,12 @@ local strings = utilities.strings
local format, gsub, rep, sub, find = string.format, string.gsub, string.rep, string.sub, string.find
local load, dump = load, string.dump
-local tonumber, type, tostring = tonumber, type, tostring
+local tonumber, type, tostring, next = tonumber, type, tostring, next
local unpack, concat = table.unpack, table.concat
local P, V, C, S, R, Ct, Cs, Cp, Carg, Cc = lpeg.P, lpeg.V, lpeg.C, lpeg.S, lpeg.R, lpeg.Ct, lpeg.Cs, lpeg.Cp, lpeg.Carg, lpeg.Cc
local patterns, lpegmatch = lpeg.patterns, lpeg.match
-local utfchar, utfbyte = utf.char, utf.byte
+local utfchar, utfbyte, utflen = utf.char, utf.byte, utf.len
+
----- loadstripped = utilities.lua.loadstripped
----- setmetatableindex = table.setmetatableindex
@@ -145,6 +146,18 @@ function strings.tabtospace(str,tab)
return lpegmatch(pattern,str,1,tab or 7)
end
+function string.utfpadding(s,n)
+ if not n or n == 0 then
+ return ""
+ end
+ local l = utflen(s)
+ if n > 0 then
+ return nspaces[n-l]
+ else
+ return nspaces[-n-l]
+ end
+end
+
-- local t = {
-- "1234567123456712345671234567",
-- "\tb\tc",
@@ -281,41 +294,48 @@ end
--
-- More info can be found in cld-mkiv.pdf so here I stick to a simple list.
--
--- integer %...i number
--- integer %...d number
--- unsigned %...u number
--- character %...c number
--- hexadecimal %...x number
--- HEXADECIMAL %...X number
--- octal %...o number
--- string %...s string number
--- float %...f number
--- checked float %...F number
--- exponential %...e number
--- exponential %...E number
--- autofloat %...g number
--- autofloat %...G number
--- utf character %...c number
--- force tostring %...S any
--- force tostring %Q any
--- force tonumber %N number (strip leading zeros)
--- signed number %I number
--- rounded number %r number
--- 0xhexadecimal %...h character number
--- 0xHEXADECIMAL %...H character number
--- U+hexadecimal %...u character number
--- U+HEXADECIMAL %...U character number
--- points %p number (scaled points)
--- basepoints %b number (scaled points)
--- table concat %...t table
--- table concat %{.}t table
--- serialize %...T sequenced (no nested tables)
--- serialize %{.}T sequenced (no nested tables)
--- boolean (logic) %l boolean
--- BOOLEAN %L boolean
--- whitespace %...w
--- automatic %...a 'whatever' (string, table, ...)
--- automatic %...A "whatever" (string, table, ...)
+-- integer %...i number
+-- integer %...d number
+-- unsigned %...u number
+-- character %...c number
+-- hexadecimal %...x number
+-- HEXADECIMAL %...X number
+-- octal %...o number
+-- string %...s string number
+-- float %...f number
+-- checked float %...F number
+-- exponential %...e number
+-- exponential %...E number
+-- stripped e %...j number
+-- stripped E %...J number
+-- autofloat %...g number
+-- autofloat %...G number
+-- utf character %...c number
+-- force tostring %...S any
+-- force tostring %Q any
+-- force tonumber %N number (strip leading zeros)
+-- signed number %I number
+-- rounded number %r number
+-- 0xhexadecimal %...h character number
+-- 0xHEXADECIMAL %...H character number
+-- U+hexadecimal %...u character number
+-- U+HEXADECIMAL %...U character number
+-- points %p number (scaled points)
+-- basepoints %b number (scaled points)
+-- table concat %...t table
+-- table concat %{.}t table
+-- serialize %...T sequenced (no nested tables)
+-- serialize %{.}T sequenced (no nested tables)
+-- boolean (logic) %l boolean
+-- BOOLEAN %L boolean
+-- whitespace %...w number
+-- whitespace %...W (fixed)
+-- automatic %...a 'whatever' (string, table, ...)
+-- automatic %...A "whatever" (string, table, ...)
+-- zap %...z skip
+-- comma/period real %...m
+-- period/comma real %...M
+-- formatted float %...k n.m
local n = 0
@@ -520,6 +540,7 @@ local utfchar=utf.char
local utfbyte=utf.byte
local lpegmatch=lpeg.match
local nspaces=string.nspaces
+local utfpadding=string.utfpadding
local tracedchar=string.tracedchar
local autosingle=string.autosingle
local autodouble=string.autodouble
@@ -546,6 +567,7 @@ else
utfbyte = utf.byte,
lpegmatch = lpeg.match,
nspaces = string.nspaces,
+ utfpadding = string.utfpadding,
tracedchar = string.tracedchar,
autosingle = string.autosingle,
autodouble = string.autodouble,
@@ -597,6 +619,31 @@ local format_S = function(f) -- can be optimized
end
end
+local format_right = function(f)
+ n = n + 1
+ f = tonumber(f)
+ if not f or f == 0 then
+ return format("(a%s or '')",n)
+ elseif f > 0 then
+ return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
+end
+
+local format_left = function(f)
+ n = n + 1
+ f = tonumber(f)
+ if not f or f == 0 then
+ return format("(a%s or '')",n)
+ end
+ if f < 0 then
+ return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
+end
+
local format_q = function()
n = n + 1
return format("(a%s and format('%%q',a%s) or '')",n,n) -- goodie: nil check (maybe separate lpeg, not faster)
@@ -928,6 +975,9 @@ local builder = Cs { "start",
+ V("m") + V("M") -- new (formatted number)
+ V("z") -- new
--
+ + V(">") -- left padding
+ + V("<") -- right padding
+ --
-- + V("?") -- ignored, probably messed up %
)
+ V("*")
@@ -978,11 +1028,14 @@ local builder = Cs { "start",
["m"] = (prefix_tab * P("m")) / format_m, -- %m => xxx.xxx.xxx,xx (optional prefix instead of .)
["M"] = (prefix_tab * P("M")) / format_M, -- %M => xxx,xxx,xxx.xx (optional prefix instead of ,)
--
- ["z"] = (prefix_any * P("z")) / format_z, -- %M => xxx,xxx,xxx.xx (optional prefix instead of ,)
+ ["z"] = (prefix_any * P("z")) / format_z, -- %z => skip n arguments
--
["a"] = (prefix_any * P("a")) / format_a, -- %a => '...' (forces tostring)
["A"] = (prefix_any * P("A")) / format_A, -- %A => "..." (forces tostring)
--
+ ["<"] = (prefix_any * P("<")) / format_left,
+ [">"] = (prefix_any * P(">")) / format_right,
+ --
["*"] = Cs(((1-P("%"))^1 + P("%%")/"%%")^1) / format_rest, -- rest (including %%)
["?"] = Cs(((1-P("%"))^1 )^1) / format_rest, -- rest (including %%)
--
diff --git a/tex/context/base/mkiv/util-tpl.lua b/tex/context/base/mkiv/util-tpl.lua
index 468dd429c..5e75a151b 100644
--- a/tex/context/base/mkiv/util-tpl.lua
+++ b/tex/context/base/mkiv/util-tpl.lua
@@ -16,7 +16,7 @@ local templates = utilities.templates
local trace_template = false trackers.register("templates.trace",function(v) trace_template = v end)
local report_template = logs.reporter("template")
-local tostring = tostring
+local tostring, next = tostring, next
local format, sub, byte = string.format, string.sub, string.byte
local P, C, R, Cs, Cc, Carg, lpegmatch, lpegpatterns = lpeg.P, lpeg.C, lpeg.R, lpeg.Cs, lpeg.Cc, lpeg.Carg, lpeg.match, lpeg.patterns
diff --git a/tex/context/base/mkiv/util-you.lua b/tex/context/base/mkiv/util-you.lua
index 79a0e83e7..32a7e07d4 100644
--- a/tex/context/base/mkiv/util-you.lua
+++ b/tex/context/base/mkiv/util-you.lua
@@ -30,22 +30,43 @@ utilities.youless = youless
local lpegmatch = lpeg.match
local formatters = string.formatters
+local sortedhash = table.sortedhash
+
+local tonumber, type, next = tonumber, type, next
+
+local round, div = math.round, math.div
+local osdate, ostime = os.date, os.time
+
+local report = logs.reporter("youless")
+local trace = false
-- dofile("http.lua")
local http = socket.http
-local f_normal = formatters["http://%s/V?%s=%i&f=j"]
-local f_password = formatters["http://%s/L?w=%s"]
+-- f=j : json
+
+local f_password = formatters["http://%s/L?w=%s"]
-local function fetch(url,password,what,i)
- local url = f_normal(url,what,i)
- local data, h = http.request(url)
- local result = data and utilities.json.tolua(data)
- return result
+local f_fetchers = {
+ electricity = formatters["http://%s/V?%s=%i&f=j"],
+ gas = formatters["http://%s/W?%s=%i&f=j"],
+ pulse = formatters["http://%s/Z?%s=%i&f=j"],
+}
+
+local function fetch(url,password,what,i,category)
+ local fetcher = f_fetchers[category or "electricity"]
+ if not fetcher then
+ report("invalid fetcher %a",category)
+ else
+ local url = fetcher(url,what,i)
+ local data, h = http.request(url)
+ local result = data and utilities.json.tolua(data)
+ return result
+ end
end
--- "123" " 1,234"
+-- "123" " 23" " 1,234"
local tovalue = lpeg.Cs((lpeg.R("09") + lpeg.P(1)/"")^1) / tonumber
@@ -58,48 +79,99 @@ local totime = (lpeg.C(4) / tonumber) * lpeg.P("-")
* (lpeg.C(2) / tonumber) * lpeg.P(":")
* (lpeg.C(2) / tonumber)
-local function get(url,password,what,i,data,average,variant)
+local function collapsed(data,dirty)
+ for list, parent in next, dirty do
+ local t, n = { }, { }
+ for k, v in next, list do
+ local d = div(k,10) * 10
+ t[d] = (t[d] or 0) + v
+ n[d] = (n[d] or 0) + 1
+ end
+ for k, v in next, t do
+ t[k] = round(t[k]/n[k])
+ end
+ parent[1][parent[2]] = t
+ end
+ return data
+end
+
+local function get(url,password,what,step,data,option,category)
if not data then
data = { }
end
+ local dirty = { }
while true do
- local d = fetch(url,password,what,i)
- if d and next(d) then
+ local d = fetch(url,password,what,step,category)
+ local v = d and d.val
+ if v and #v > 0 then
local c_year, c_month, c_day, c_hour, c_minute, c_seconds = lpegmatch(totime,d.tm)
if c_year and c_seconds then
local delta = tonumber(d.dt)
- local tnum = os.time { year = c_year, month = c_month, day = c_day, hour = c_hour, minute = c_minute }
- local v = d.val
+ local tnum = ostime {
+ year = c_year,
+ month = c_month,
+ day = c_day,
+ hour = c_hour,
+ min = c_minute,
+ sec = c_seconds,
+ }
for i=1,#v do
- local newvalue = lpegmatch(tovalue,v[i])
- if newvalue then
- local t = tnum + (i-1)*delta
- local current = os.date("%Y-%m-%dT%H:%M:%S",t)
- local c_year, c_month, c_day, c_hour, c_minute, c_seconds = lpegmatch(totime,current)
- if c_year and c_seconds then
- local years = data.years if not years then years = { } data.years = years end
- local d_year = years[c_year] if not d_year then d_year = { } years[c_year] = d_year end
- local months = d_year.months if not months then months = { } d_year.months = months end
- local d_month = months[c_month] if not d_month then d_month = { } months[c_month] = d_month end
- local days = d_month.days if not days then days = { } d_month.days = days end
- local d_day = days[c_day] if not d_day then d_day = { } days[c_day] = d_day end
- if average then
- d_day.average = newvalue
- else
- local hours = d_day.hours if not hours then hours = { } d_day.hours = hours end
- local d_hour = hours[c_hour] if not d_hour then d_hour = { } hours[c_hour] = d_hour end
- d_hour[c_minute] = newvalue
+ local vi = v[i]
+ if vi ~= "*" then
+ local newvalue = lpegmatch(tovalue,vi)
+ if newvalue then
+ local t = tnum + (i-1)*delta
+ -- local current = osdate("%Y-%m-%dT%H:%M:%S",t)
+ -- local c_year, c_month, c_day, c_hour, c_minute, c_seconds = lpegmatch(totime,current)
+ local c = osdate("*t",tnum + (i-1)*delta)
+ local c_year = c.year
+ local c_month = c.month
+ local c_day = c.day
+ local c_hour = c.hour
+ local c_minute = c.min
+ local c_seconds = c.sec
+ if c_year and c_seconds then
+ local years = data.years if not years then years = { } data.years = years end
+ local d_year = years[c_year] if not d_year then d_year = { } years[c_year] = d_year end
+ local months = d_year.months if not months then months = { } d_year.months = months end
+ local d_month = months[c_month] if not d_month then d_month = { } months[c_month] = d_month end
+ local days = d_month.days if not days then days = { } d_month.days = days end
+ local d_day = days[c_day] if not d_day then d_day = { } days[c_day] = d_day end
+ if option == "average" or option == "total" then
+ if trace then
+ local oldvalue = d_day[option]
+ if oldvalue and oldvalue ~= newvalue then
+ report("category %s, step %i, time %s: old %s %s updated to %s",category,step,osdate("%Y-%m-%dT%H:%M:%S",t),option,oldvalue,newvalue)
+ end
+ end
+ d_day[option] = newvalue
+ elseif option == "value" then
+ local hours = d_day.hours if not hours then hours = { } d_day.hours = hours end
+ local d_hour = hours[c_hour] if not d_hour then d_hour = { } hours[c_hour] = d_hour end
+ if trace then
+ local oldvalue = d_hour[c_minute]
+ if oldvalue and oldvalue ~= newvalue then
+ report("category %s, step %i, time %s: old %s %s updated to %s",category,step,osdate("%Y-%m-%dT%H:%M:%S",t),"value",oldvalue,newvalue)
+ end
+ end
+ d_hour[c_minute] = newvalue
+ if not dirty[d_hour] then
+ dirty[d_hour] = { hours, c_hour }
+ end
+ else
+ -- can't happen
+ end
end
end
end
end
end
else
- return data
+ return collapsed(data,dirty)
end
- i = i + 1
+ step = step + 1
end
- return data
+ return collapsed(data,dirty)
end
-- day of month (kwh)
@@ -132,6 +204,7 @@ function youless.collect(specification)
local detail = specification.detail or false
local nobackup = specification.nobackup or false
local password = specification.password or ""
+ local oldstuff = false
if host == "" then
return
end
@@ -140,13 +213,36 @@ function youless.collect(specification)
else
data = table.load(filename) or data
end
- if variant == "kwh" then
- get(host,password,"m",1,data,true)
- elseif variant == "watt" then
- get(host,password,"d",0,data,true)
- get(host,password,"w",1,data)
+ if variant == "electricity" then
+ get(host,password,"m",1,data,"total","electricity")
+ if oldstuff then
+ get(host,password,"d",1,data,"average","electricity")
+ end
+ get(host,password,"w",1,data,"value","electricity")
if detail then
- get(host,password,"h",1,data) -- todo: get this for calculating the precise max
+ get(host,password,"h",1,data,"value","electricity") -- todo: get this for calculating the precise max
+ end
+ elseif variant == "pulse" then
+ -- It looks like the 'd' option returns the wrong values or at least not the same sort
+ -- as the other ones, so we calculate the means ourselves. And 'w' is not consistent with
+ -- that too, so ...
+ get(host,password,"m",1,data,"total","pulse")
+ if oldstuff then
+ get(host,password,"d",1,data,"average","pulse")
+ end
+ detail = true
+ get(host,password,"w",1,data,"value","pulse")
+ if detail then
+ get(host,password,"h",1,data,"value","pulse")
+ end
+ elseif variant == "gas" then
+ get(host,password,"m",1,data,"total","gas")
+ if oldstuff then
+ get(host,password,"d",1,data,"average","gas")
+ end
+ get(host,password,"w",1,data,"value","gas")
+ if detail then
+ get(host,password,"h",1,data,"value","gas")
end
else
return
@@ -164,15 +260,21 @@ function youless.collect(specification)
if type(check) == "table" then
local keepname = file.replacesuffix(filename,"old")
os.remove(keepname)
- if not lfs.isfile(keepname) then
+ if lfs.isfile(keepname) then
+ report("error in removing %a",keepname)
+ else
os.rename(filename,keepname)
os.rename(tempname,filename)
end
+ else
+ report("error in saving %a",tempname)
end
else
local keepname = file.join(path,formatters["%s-%s"](os.date("%Y-%m-%d-%H-%M-%S",os.time()),base))
os.rename(filename,keepname)
- if not lfs.isfile(filename) then
+ if lfs.isfile(filename) then
+ report("error in renaming %a",filename)
+ else
table.save(filename,data)
end
end
@@ -181,76 +283,111 @@ end
-- local data = youless.collect {
-- host = "192.168.2.50",
--- variant = "watt",
--- filename = "youless-watt.lua"
+-- variant = "electricity",
+-- category = "electricity",
+-- filename = "youless-electricity.lua"
-- }
-
+--
-- inspect(data)
-- local data = youless.collect {
--- host = "192.168.2.50",
--- variant = "kwh",
--- filename = "youless-kwh.lua"
+-- host = "192.168.2.50",
+-- variant = "pulse",
+-- category = "electricity",
+-- filename = "youless-pulse.lua"
-- }
+--
+-- inspect(data)
+-- local data = youless.collect {
+-- host = "192.168.2.50",
+-- variant = "gas",
+-- category = "gas",
+-- filename = "youless-gas.lua"
+-- }
+--
-- inspect(data)
+-- We remain compatible so we stick to electricity and not unit fields.
+
function youless.analyze(data)
- if data and data.variant == "watt" and data.years then
- for y, year in next, data.years do
- local a_year, n_year, m_year = 0, 0, 0
- if year.months then
- for m, month in next, year.months do
- local a_month, n_month = 0, 0
- if month.days then
- for d, day in next, month.days do
- local a_day, n_day = 0, 0
- if day.hours then
- for h, hour in next, day.hours do
- local a_hour, n_hour, m_hour = 0, 0, 0
- for k, v in next, hour do
- if type(k) == "number" then
- a_hour = a_hour + v
- n_hour = n_hour + 1
- if v > m_hour then
- m_hour = v
- end
+ if type(data) == "string" then
+ data = table.load(data)
+ end
+ if type(data) ~= "table" then
+ return false, "no data"
+ end
+ if not data.years then
+ return false, "no years"
+ end
+ local variant = data.variant
+ local unit, maxunit
+ if variant == "electricity" or variant == "watt" then
+ unit = "watt"
+ maxunit = "maxwatt"
+ elseif variant == "gas" then
+ unit = "liters"
+ maxunit = "maxliters"
+ elseif variant == "pulse" then
+ unit = "watt"
+ maxunit = "maxwatt"
+ else
+ return false, "invalid variant"
+ end
+ for y, year in next, data.years do
+ local a_year, n_year, m_year = 0, 0, 0
+ if year.months then
+ for m, month in next, year.months do
+ local a_month, n_month = 0, 0
+ if month.days then
+ for d, day in next, month.days do
+ local a_day, n_day = 0, 0
+ if day.hours then
+ for h, hour in next, day.hours do
+ local a_hour, n_hour, m_hour = 0, 0, 0
+ for k, v in next, hour do
+ if type(k) == "number" then
+ a_hour = a_hour + v
+ n_hour = n_hour + 1
+ if v > m_hour then
+ m_hour = v
end
end
- n_day = n_day + n_hour
- a_day = a_day + a_hour
- hour.maxwatt = m_hour
- hour.watt = a_hour / n_hour
- if m_hour > m_year then
- m_year = m_hour
- end
end
- end
- if n_day > 0 then
- a_month = a_month + a_day
- n_month = n_month + n_day
- day.watt = a_day / n_day
- else
- day.watt = 0
+ n_day = n_day + n_hour
+ a_day = a_day + a_hour
+ hour[maxunit] = m_hour
+ hour[unit] = a_hour / n_hour
+ if m_hour > m_year then
+ m_year = m_hour
+ end
end
end
- end
- if n_month > 0 then
- a_year = a_year + a_month
- n_year = n_year + n_month
- month.watt = a_month / n_month
- else
- month.watt = 0
+ if n_day > 0 then
+ a_month = a_month + a_day
+ n_month = n_month + n_day
+ day[unit] = a_day / n_day
+ else
+ day[unit] = 0
+ end
end
end
- end
- if n_year > 0 then
- year.watt = a_year / n_year
- year.maxwatt = m_year
- else
- year.watt = 0
- year.maxwatt = 0
+ if n_month > 0 then
+ a_year = a_year + a_month
+ n_year = n_year + n_month
+ month[unit] = a_month / n_month
+ else
+ month[unit] = 0
+ end
end
end
+ if n_year > 0 then
+ year[unit] = a_year / n_year
+ year[maxunit] = m_year
+ else
+ year[unit] = 0
+ year[maxunit] = 0
+ end
end
+ return data
end
diff --git a/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv b/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv
index cd474242f..bba07f41d 100644
--- a/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv
+++ b/tex/context/fonts/mkiv/type-imp-ebgaramond.mkiv
@@ -40,8 +40,8 @@
\starttypescript[ebgaramond]
\definetypeface [ebgaramond] [rm] [serif] [ebgaramond] [default] [designsize=auto]
- \definetypeface [ebgaramond] [tt] [mono] [dejavu] [default]
- \definetypeface [ebgaramond] [mm] [math] [bonum] [default]
+ \definetypeface [ebgaramond] [tt] [mono] [dejavu] [default] [rscale=0.8] % rather arbitrary but seldom mixed anyway
+ \definetypeface [ebgaramond] [mm] [math] [bonum] [default] [rscale=0.8] % rather arbitrary but seldom mixed anyway
\stoptypescript
\stoptypescriptcollection
diff --git a/tex/context/interface/mkii/keys-cs.xml b/tex/context/interface/mkii/keys-cs.xml
index 93e6bb477..97c22dec7 100644
--- a/tex/context/interface/mkii/keys-cs.xml
+++ b/tex/context/interface/mkii/keys-cs.xml
@@ -627,6 +627,10 @@
<cd:constant name='align' value='zarovnani'/>
<cd:constant name='aligncharacter' value='aligncharacter'/>
<cd:constant name='alignmentcharacter' value='alignmentcharacter'/>
+ <cd:constant name='alignmentleftsample' value='alignmentleftsample'/>
+ <cd:constant name='alignmentleftwidth' value='alignmentleftwidth'/>
+ <cd:constant name='alignmentrightsample' value='alignmentrightsample'/>
+ <cd:constant name='alignmentrightwidth' value='alignmentrightwidth'/>
<cd:constant name='alignsymbol' value='alignsymbol'/>
<cd:constant name='aligntitle' value='zarovnejtitul'/>
<cd:constant name='alternative' value='alternativa'/>
@@ -913,6 +917,7 @@
<cd:constant name='leftoffset' value='levyoffset'/>
<cd:constant name='leftquotation' value='citacevlevo'/>
<cd:constant name='leftquote' value='citovatvlevo'/>
+ <cd:constant name='leftsample' value='leftsample'/>
<cd:constant name='leftsentence' value='vetavlevo'/>
<cd:constant name='leftspeech' value='leftspeech'/>
<cd:constant name='leftstyle' value='stylvlevo'/>
@@ -985,6 +990,7 @@
<cd:constant name='nlines' value='nradky'/>
<cd:constant name='norm' value='norm'/>
<cd:constant name='note' value='note'/>
+ <cd:constant name='notes' value='notes'/>
<cd:constant name='nr' value='nr'/>
<cd:constant name='nright' value='nvpravo'/>
<cd:constant name='ntop' value='nvrsek'/>
@@ -1115,6 +1121,7 @@
<cd:constant name='rightoffset' value='pravyoffset'/>
<cd:constant name='rightquotation' value='citacevpravo'/>
<cd:constant name='rightquote' value='citovatvpravo'/>
+ <cd:constant name='rightsample' value='rightsample'/>
<cd:constant name='rightsentence' value='vetavpravo'/>
<cd:constant name='rightspeech' value='rightspeech'/>
<cd:constant name='rightstyle' value='stylvpravo'/>
diff --git a/tex/context/interface/mkii/keys-de.xml b/tex/context/interface/mkii/keys-de.xml
index 99b58bc74..070844355 100644
--- a/tex/context/interface/mkii/keys-de.xml
+++ b/tex/context/interface/mkii/keys-de.xml
@@ -379,6 +379,7 @@
<cd:variable name='norepeat' value='norepeat'/>
<cd:variable name='normal' value='normal'/>
<cd:variable name='nospacing' value='nospacing'/>
+ <cd:variable name='nostopper' value='nostopper'/>
<cd:variable name='not' value='nicht'/>
<cd:variable name='notation' value='notation'/>
<cd:variable name='note' value='note'/>
@@ -627,6 +628,10 @@
<cd:constant name='align' value='ausrichtung'/>
<cd:constant name='aligncharacter' value='aligncharacter'/>
<cd:constant name='alignmentcharacter' value='alignmentcharacter'/>
+ <cd:constant name='alignmentleftsample' value='alignmentleftsample'/>
+ <cd:constant name='alignmentleftwidth' value='alignmentleftwidth'/>
+ <cd:constant name='alignmentrightsample' value='alignmentrightsample'/>
+ <cd:constant name='alignmentrightwidth' value='alignmentrightwidth'/>
<cd:constant name='alignsymbol' value='alignsymbol'/>
<cd:constant name='aligntitle' value='titelausrichten'/>
<cd:constant name='alternative' value='alternative'/>
@@ -913,6 +918,7 @@
<cd:constant name='leftoffset' value='linkeroffset'/>
<cd:constant name='leftquotation' value='linkerzitat'/>
<cd:constant name='leftquote' value='linkerzitieren'/>
+ <cd:constant name='leftsample' value='leftsample'/>
<cd:constant name='leftsentence' value='linkersatz'/>
<cd:constant name='leftspeech' value='leftspeech'/>
<cd:constant name='leftstyle' value='linkerstil'/>
@@ -985,6 +991,7 @@
<cd:constant name='nlines' value='zzeile'/>
<cd:constant name='norm' value='norm'/>
<cd:constant name='note' value='note'/>
+ <cd:constant name='notes' value='notes'/>
<cd:constant name='nr' value='nr'/>
<cd:constant name='nright' value='nrechts'/>
<cd:constant name='ntop' value='noben'/>
@@ -1115,6 +1122,7 @@
<cd:constant name='rightoffset' value='rechterabstand'/>
<cd:constant name='rightquotation' value='rechterzitat'/>
<cd:constant name='rightquote' value='rechterzitieren'/>
+ <cd:constant name='rightsample' value='rightsample'/>
<cd:constant name='rightsentence' value='rechtersatz'/>
<cd:constant name='rightspeech' value='rightspeech'/>
<cd:constant name='rightstyle' value='rechterstil'/>
@@ -1171,7 +1179,9 @@
<cd:constant name='source' value='quelle'/>
<cd:constant name='space' value='spatium'/>
<cd:constant name='spaceafter' value='nachspatium'/>
+ <cd:constant name='spaceafterside' value='spaceafterside'/>
<cd:constant name='spacebefore' value='vorspatium'/>
+ <cd:constant name='spacebeforeside' value='spacebeforeside'/>
<cd:constant name='spaceinbetween' value='spaceinbetween'/>
<cd:constant name='spacing' value='spatiumausgleich'/>
<cd:constant name='specification' value='specification'/>
diff --git a/tex/context/interface/mkii/keys-en.xml b/tex/context/interface/mkii/keys-en.xml
index 3ac165945..d091a8fff 100644
--- a/tex/context/interface/mkii/keys-en.xml
+++ b/tex/context/interface/mkii/keys-en.xml
@@ -379,6 +379,7 @@
<cd:variable name='norepeat' value='norepeat'/>
<cd:variable name='normal' value='normal'/>
<cd:variable name='nospacing' value='nospacing'/>
+ <cd:variable name='nostopper' value='nostopper'/>
<cd:variable name='not' value='not'/>
<cd:variable name='notation' value='notation'/>
<cd:variable name='note' value='note'/>
@@ -627,6 +628,10 @@
<cd:constant name='align' value='align'/>
<cd:constant name='aligncharacter' value='aligncharacter'/>
<cd:constant name='alignmentcharacter' value='alignmentcharacter'/>
+ <cd:constant name='alignmentleftsample' value='alignmentleftsample'/>
+ <cd:constant name='alignmentleftwidth' value='alignmentleftwidth'/>
+ <cd:constant name='alignmentrightsample' value='alignmentrightsample'/>
+ <cd:constant name='alignmentrightwidth' value='alignmentrightwidth'/>
<cd:constant name='alignsymbol' value='alignsymbol'/>
<cd:constant name='aligntitle' value='aligntitle'/>
<cd:constant name='alternative' value='alternative'/>
@@ -913,6 +918,7 @@
<cd:constant name='leftoffset' value='leftoffset'/>
<cd:constant name='leftquotation' value='leftquotation'/>
<cd:constant name='leftquote' value='leftquote'/>
+ <cd:constant name='leftsample' value='leftsample'/>
<cd:constant name='leftsentence' value='leftsentence'/>
<cd:constant name='leftspeech' value='leftspeech'/>
<cd:constant name='leftstyle' value='leftstyle'/>
@@ -985,6 +991,7 @@
<cd:constant name='nlines' value='nlines'/>
<cd:constant name='norm' value='norm'/>
<cd:constant name='note' value='note'/>
+ <cd:constant name='notes' value='notes'/>
<cd:constant name='nr' value='nr'/>
<cd:constant name='nright' value='nright'/>
<cd:constant name='ntop' value='ntop'/>
@@ -1004,6 +1011,7 @@
<cd:constant name='numberset' value='numberset'/>
<cd:constant name='numberstarter' value='numberstarter'/>
<cd:constant name='numberstopper' value='numberstopper'/>
+ <cd:constant name='numberstrut' value='numberstrut'/>
<cd:constant name='numberstyle' value='numberstyle'/>
<cd:constant name='numberwidth' value='numberwidth'/>
<cd:constant name='nx' value='nx'/>
@@ -1115,6 +1123,7 @@
<cd:constant name='rightoffset' value='rightoffset'/>
<cd:constant name='rightquotation' value='rightquotation'/>
<cd:constant name='rightquote' value='rightquote'/>
+ <cd:constant name='rightsample' value='rightsample'/>
<cd:constant name='rightsentence' value='rightsentence'/>
<cd:constant name='rightspeech' value='rightspeech'/>
<cd:constant name='rightstyle' value='rightstyle'/>
@@ -1171,7 +1180,9 @@
<cd:constant name='source' value='source'/>
<cd:constant name='space' value='space'/>
<cd:constant name='spaceafter' value='spaceafter'/>
+ <cd:constant name='spaceafterside' value='spaceafterside'/>
<cd:constant name='spacebefore' value='spacebefore'/>
+ <cd:constant name='spacebeforeside' value='spacebeforeside'/>
<cd:constant name='spaceinbetween' value='spaceinbetween'/>
<cd:constant name='spacing' value='spacing'/>
<cd:constant name='specification' value='specification'/>
@@ -1236,6 +1247,7 @@
<cd:constant name='titledistance' value='titledistance'/>
<cd:constant name='titleleft' value='titleleft'/>
<cd:constant name='titleright' value='titleright'/>
+ <cd:constant name='titlestrut' value='titlestrut'/>
<cd:constant name='titlestyle' value='titlestyle'/>
<cd:constant name='to' value='to'/>
<cd:constant name='toffset' value='toffset'/>
diff --git a/tex/context/interface/mkii/keys-fr.xml b/tex/context/interface/mkii/keys-fr.xml
index 5c5d2f0fb..2b2256d46 100644
--- a/tex/context/interface/mkii/keys-fr.xml
+++ b/tex/context/interface/mkii/keys-fr.xml
@@ -627,6 +627,10 @@
<cd:constant name='align' value='alignement'/>
<cd:constant name='aligncharacter' value='caracterealigne'/>
<cd:constant name='alignmentcharacter' value='alignementcaractere'/>
+ <cd:constant name='alignmentleftsample' value='alignmentleftsample'/>
+ <cd:constant name='alignmentleftwidth' value='alignmentleftwidth'/>
+ <cd:constant name='alignmentrightsample' value='alignmentrightsample'/>
+ <cd:constant name='alignmentrightwidth' value='alignmentrightwidth'/>
<cd:constant name='alignsymbol' value='alignsymbol'/>
<cd:constant name='aligntitle' value='alignementtitre'/>
<cd:constant name='alternative' value='alternative'/>
@@ -913,6 +917,7 @@
<cd:constant name='leftoffset' value='decalagegauche'/>
<cd:constant name='leftquotation' value='citationgauche'/>
<cd:constant name='leftquote' value='citergauche'/>
+ <cd:constant name='leftsample' value='leftsample'/>
<cd:constant name='leftsentence' value='phrasegauche'/>
<cd:constant name='leftspeech' value='leftspeech'/>
<cd:constant name='leftstyle' value='leftstyle'/>
@@ -985,6 +990,7 @@
<cd:constant name='nlines' value='nlignes'/>
<cd:constant name='norm' value='norme'/>
<cd:constant name='note' value='note'/>
+ <cd:constant name='notes' value='notes'/>
<cd:constant name='nr' value='nr'/>
<cd:constant name='nright' value='ndroite'/>
<cd:constant name='ntop' value='nsup'/>
@@ -1115,6 +1121,7 @@
<cd:constant name='rightoffset' value='rightoffset'/>
<cd:constant name='rightquotation' value='citationdroite'/>
<cd:constant name='rightquote' value='citerdroite'/>
+ <cd:constant name='rightsample' value='rightsample'/>
<cd:constant name='rightsentence' value='phrasedroite'/>
<cd:constant name='rightspeech' value='rightspeech'/>
<cd:constant name='rightstyle' value='styledroit'/>
diff --git a/tex/context/interface/mkii/keys-it.xml b/tex/context/interface/mkii/keys-it.xml
index b70b455d8..4ad49cc05 100644
--- a/tex/context/interface/mkii/keys-it.xml
+++ b/tex/context/interface/mkii/keys-it.xml
@@ -379,6 +379,7 @@
<cd:variable name='norepeat' value='norepeat'/>
<cd:variable name='normal' value='normale'/>
<cd:variable name='nospacing' value='nospacing'/>
+ <cd:variable name='nostopper' value='nostopper'/>
<cd:variable name='not' value='non'/>
<cd:variable name='notation' value='notation'/>
<cd:variable name='note' value='note'/>
@@ -627,6 +628,10 @@
<cd:constant name='align' value='allinea'/>
<cd:constant name='aligncharacter' value='allineacarattere'/>
<cd:constant name='alignmentcharacter' value='carattereallineamento'/>
+ <cd:constant name='alignmentleftsample' value='alignmentleftsample'/>
+ <cd:constant name='alignmentleftwidth' value='alignmentleftwidth'/>
+ <cd:constant name='alignmentrightsample' value='alignmentrightsample'/>
+ <cd:constant name='alignmentrightwidth' value='alignmentrightwidth'/>
<cd:constant name='alignsymbol' value='alignsymbol'/>
<cd:constant name='aligntitle' value='allineatitolo'/>
<cd:constant name='alternative' value='alternativa'/>
@@ -913,6 +918,7 @@
<cd:constant name='leftoffset' value='offsetsinistro'/>
<cd:constant name='leftquotation' value='citazionesinistra'/>
<cd:constant name='leftquote' value='menzionesinistra'/>
+ <cd:constant name='leftsample' value='leftsample'/>
<cd:constant name='leftsentence' value='frasesinistra'/>
<cd:constant name='leftspeech' value='leftspeech'/>
<cd:constant name='leftstyle' value='stilesinistra'/>
@@ -985,6 +991,7 @@
<cd:constant name='nlines' value='nrighe'/>
<cd:constant name='norm' value='norma'/>
<cd:constant name='note' value='note'/>
+ <cd:constant name='notes' value='notes'/>
<cd:constant name='nr' value='nr'/>
<cd:constant name='nright' value='ndestra'/>
<cd:constant name='ntop' value='ncima'/>
@@ -1004,6 +1011,7 @@
<cd:constant name='numberset' value='numberset'/>
<cd:constant name='numberstarter' value='numberstarter'/>
<cd:constant name='numberstopper' value='numberstopper'/>
+ <cd:constant name='numberstrut' value='numberstrut'/>
<cd:constant name='numberstyle' value='stilenumero'/>
<cd:constant name='numberwidth' value='numberwidth'/>
<cd:constant name='nx' value='nx'/>
@@ -1115,6 +1123,7 @@
<cd:constant name='rightoffset' value='offsetdestro'/>
<cd:constant name='rightquotation' value='citazionedestra'/>
<cd:constant name='rightquote' value='menzionedestra'/>
+ <cd:constant name='rightsample' value='rightsample'/>
<cd:constant name='rightsentence' value='frasedestra'/>
<cd:constant name='rightspeech' value='rightspeech'/>
<cd:constant name='rightstyle' value='stiledestra'/>
@@ -1171,7 +1180,9 @@
<cd:constant name='source' value='origine'/>
<cd:constant name='space' value='spazio'/>
<cd:constant name='spaceafter' value='spaziodopo'/>
+ <cd:constant name='spaceafterside' value='spaceafterside'/>
<cd:constant name='spacebefore' value='spazioprima'/>
+ <cd:constant name='spacebeforeside' value='spacebeforeside'/>
<cd:constant name='spaceinbetween' value='spaceinbetween'/>
<cd:constant name='spacing' value='spaziatura'/>
<cd:constant name='specification' value='specification'/>
@@ -1236,6 +1247,7 @@
<cd:constant name='titledistance' value='distanzatitolo'/>
<cd:constant name='titleleft' value='titleleft'/>
<cd:constant name='titleright' value='titleright'/>
+ <cd:constant name='titlestrut' value='titlestrut'/>
<cd:constant name='titlestyle' value='stiletitolo'/>
<cd:constant name='to' value='verso'/>
<cd:constant name='toffset' value='toffset'/>
diff --git a/tex/context/interface/mkii/keys-pe.xml b/tex/context/interface/mkii/keys-pe.xml
index 9d1416601..d6d1bc047 100644
--- a/tex/context/interface/mkii/keys-pe.xml
+++ b/tex/context/interface/mkii/keys-pe.xml
@@ -627,6 +627,10 @@
<cd:constant name='align' value='تنظیم'/>
<cd:constant name='aligncharacter' value='حرف‌تنظیم'/>
<cd:constant name='alignmentcharacter' value='حرف‌تنظیم‌کردن'/>
+ <cd:constant name='alignmentleftsample' value='alignmentleftsample'/>
+ <cd:constant name='alignmentleftwidth' value='alignmentleftwidth'/>
+ <cd:constant name='alignmentrightsample' value='alignmentrightsample'/>
+ <cd:constant name='alignmentrightwidth' value='alignmentrightwidth'/>
<cd:constant name='alignsymbol' value='alignsymbol'/>
<cd:constant name='aligntitle' value='عنوان‌تنظیم'/>
<cd:constant name='alternative' value='جایگزین'/>
@@ -913,6 +917,7 @@
<cd:constant name='leftoffset' value='آفست‌چپ'/>
<cd:constant name='leftquotation' value='نقل‌قول‌چپ'/>
<cd:constant name='leftquote' value='نقل‌چپ'/>
+ <cd:constant name='leftsample' value='leftsample'/>
<cd:constant name='leftsentence' value='جمله‌چپ'/>
<cd:constant name='leftspeech' value='سخنرانی‌چپ'/>
<cd:constant name='leftstyle' value='سبک‌چپ'/>
@@ -985,6 +990,7 @@
<cd:constant name='nlines' value='nlines'/>
<cd:constant name='norm' value='norm'/>
<cd:constant name='note' value='note'/>
+ <cd:constant name='notes' value='notes'/>
<cd:constant name='nr' value='nr'/>
<cd:constant name='nright' value='nright'/>
<cd:constant name='ntop' value='ntop'/>
@@ -1115,6 +1121,7 @@
<cd:constant name='rightoffset' value='آفست‌راست'/>
<cd:constant name='rightquotation' value='نقل‌قول‌راست'/>
<cd:constant name='rightquote' value='نقل‌راست'/>
+ <cd:constant name='rightsample' value='rightsample'/>
<cd:constant name='rightsentence' value='جمله‌راست'/>
<cd:constant name='rightspeech' value='سخنرانی‌راست'/>
<cd:constant name='rightstyle' value='سبک‌راست'/>
@@ -1171,7 +1178,9 @@
<cd:constant name='source' value='منبع'/>
<cd:constant name='space' value='فضا'/>
<cd:constant name='spaceafter' value='فضا‌بعداز'/>
+ <cd:constant name='spaceafterside' value='spaceafterside'/>
<cd:constant name='spacebefore' value='فضا‌قبل‌از'/>
+ <cd:constant name='spacebeforeside' value='spacebeforeside'/>
<cd:constant name='spaceinbetween' value='فضا‌دربین'/>
<cd:constant name='spacing' value='فضاگذاری'/>
<cd:constant name='specification' value='specification'/>
diff --git a/tex/context/interface/mkii/keys-ro.xml b/tex/context/interface/mkii/keys-ro.xml
index 3e868e1aa..5fcab2cae 100644
--- a/tex/context/interface/mkii/keys-ro.xml
+++ b/tex/context/interface/mkii/keys-ro.xml
@@ -379,6 +379,7 @@
<cd:variable name='norepeat' value='norepeat'/>
<cd:variable name='normal' value='normal'/>
<cd:variable name='nospacing' value='nospacing'/>
+ <cd:variable name='nostopper' value='nostopper'/>
<cd:variable name='not' value='nu'/>
<cd:variable name='notation' value='notation'/>
<cd:variable name='note' value='note'/>
@@ -627,6 +628,10 @@
<cd:constant name='align' value='aliniere'/>
<cd:constant name='aligncharacter' value='aliniazacaracter'/>
<cd:constant name='alignmentcharacter' value='alierecaracter'/>
+ <cd:constant name='alignmentleftsample' value='alignmentleftsample'/>
+ <cd:constant name='alignmentleftwidth' value='alignmentleftwidth'/>
+ <cd:constant name='alignmentrightsample' value='alignmentrightsample'/>
+ <cd:constant name='alignmentrightwidth' value='alignmentrightwidth'/>
<cd:constant name='alignsymbol' value='alignsymbol'/>
<cd:constant name='aligntitle' value='alinieretitlu'/>
<cd:constant name='alternative' value='alternativ'/>
@@ -913,6 +918,7 @@
<cd:constant name='leftoffset' value='offsetstanga'/>
<cd:constant name='leftquotation' value='citatstanga'/>
<cd:constant name='leftquote' value='minicitatstanga'/>
+ <cd:constant name='leftsample' value='leftsample'/>
<cd:constant name='leftsentence' value='propozitiestanga'/>
<cd:constant name='leftspeech' value='leftspeech'/>
<cd:constant name='leftstyle' value='stilstanga'/>
@@ -985,6 +991,7 @@
<cd:constant name='nlines' value='nlinii'/>
<cd:constant name='norm' value='norm'/>
<cd:constant name='note' value='note'/>
+ <cd:constant name='notes' value='notes'/>
<cd:constant name='nr' value='nr'/>
<cd:constant name='nright' value='ndreapta'/>
<cd:constant name='ntop' value='nsus'/>
@@ -1004,6 +1011,7 @@
<cd:constant name='numberset' value='numberset'/>
<cd:constant name='numberstarter' value='numberstarter'/>
<cd:constant name='numberstopper' value='numberstopper'/>
+ <cd:constant name='numberstrut' value='numberstrut'/>
<cd:constant name='numberstyle' value='stilnumar'/>
<cd:constant name='numberwidth' value='numberwidth'/>
<cd:constant name='nx' value='nx'/>
@@ -1115,6 +1123,7 @@
<cd:constant name='rightoffset' value='offsetdreapta'/>
<cd:constant name='rightquotation' value='citatdreapta'/>
<cd:constant name='rightquote' value='minicitatdreapta'/>
+ <cd:constant name='rightsample' value='rightsample'/>
<cd:constant name='rightsentence' value='propozitiedreapta'/>
<cd:constant name='rightspeech' value='rightspeech'/>
<cd:constant name='rightstyle' value='stildreapta'/>
@@ -1171,7 +1180,9 @@
<cd:constant name='source' value='sursa'/>
<cd:constant name='space' value='spatiu'/>
<cd:constant name='spaceafter' value='spatiudupa'/>
+ <cd:constant name='spaceafterside' value='spaceafterside'/>
<cd:constant name='spacebefore' value='spatiuinainte'/>
+ <cd:constant name='spacebeforeside' value='spacebeforeside'/>
<cd:constant name='spaceinbetween' value='spaceinbetween'/>
<cd:constant name='spacing' value='spatiere'/>
<cd:constant name='specification' value='specification'/>
@@ -1236,6 +1247,7 @@
<cd:constant name='titledistance' value='distantatitlu'/>
<cd:constant name='titleleft' value='titleleft'/>
<cd:constant name='titleright' value='titleright'/>
+ <cd:constant name='titlestrut' value='titlestrut'/>
<cd:constant name='titlestyle' value='stiltitlu'/>
<cd:constant name='to' value='catre'/>
<cd:constant name='toffset' value='toffset'/>
diff --git a/tex/context/interface/mkiv/context-en.xml b/tex/context/interface/mkiv/context-en.xml
index 9f47a1f53..e39caba78 100644
--- a/tex/context/interface/mkiv/context-en.xml
+++ b/tex/context/interface/mkiv/context-en.xml
@@ -10078,6 +10078,14 @@
<cd:constant type="none"/>
<cd:inherit name="blank"/>
</cd:parameter>
+ <cd:parameter name="spacebeforeside">
+ <cd:constant type="none"/>
+ <cd:inherit name="blank"/>
+ </cd:parameter>
+ <cd:parameter name="spaceafterside">
+ <cd:constant type="none"/>
+ <cd:inherit name="blank"/>
+ </cd:parameter>
<cd:parameter name="sidethreshold">
<cd:constant type="old"/>
<cd:constant default="yes" type="dimension"/>
@@ -15744,7 +15752,7 @@
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command _error_="category=&quot;fonts&quot; file=&quot;typo-drp.mkiv&quot;" level="style" name="setupinitial">
+ <cd:command category="fonts" file="typo-drp.mkiv" level="style" name="setupinitial">
<cd:arguments>
<cd:keywords list="yes" optional="yes">
<cd:constant type="cd:name"/>
@@ -17105,6 +17113,7 @@
<cd:constant type="joinedup"/>
<cd:constant type="serried"/>
<cd:constant type="stopper"/>
+ <cd:constant type="nostopper"/>
<cd:constant type="unpacked"/>
<cd:constant type="repeat"/>
<cd:constant type="norepeat"/>
@@ -34026,6 +34035,7 @@
<cd:constant type="no"/>
<cd:constant type="hidden"/>
<cd:constant type="empty"/>
+ <cd:constant type="section"/>
</cd:parameter>
<cd:parameter name="number">
<cd:constant default="yes" type="yes"/>
@@ -35808,6 +35818,7 @@
<cd:command file="supp-box.mkiv" level="system" name="strutht"/>
<cd:command file="supp-box.mkiv" level="system" name="strutwd"/>
<cd:command file="supp-box.mkiv" level="system" name="struthtdp"/>
+ <cd:command file="supp-box.mkiv" level="system" name="strutgap"/>
<cd:command file="spac-ver.mkiv" level="style" name="setupstruts">
<cd:arguments>
<cd:keywords optional="yes">
diff --git a/tex/context/interface/mkiv/i-backend.xml b/tex/context/interface/mkiv/i-backend.xml
index ff52eed7d..5db77b5bd 100644
--- a/tex/context/interface/mkiv/i-backend.xml
+++ b/tex/context/interface/mkiv/i-backend.xml
@@ -86,4 +86,4 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+</cd:interface>
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index 4301961ca..0dfec2ab9 100644
--- a/tex/context/interface/mkiv/i-context.pdf
+++ b/tex/context/interface/mkiv/i-context.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-floats.xml b/tex/context/interface/mkiv/i-floats.xml
index c05fae69f..977ed3aa7 100644
--- a/tex/context/interface/mkiv/i-floats.xml
+++ b/tex/context/interface/mkiv/i-floats.xml
@@ -170,6 +170,14 @@
<cd:constant type="none"/>
<cd:inherit name="blank"/>
</cd:parameter>
+ <cd:parameter name="spacebeforeside">
+ <cd:constant type="none"/>
+ <cd:inherit name="blank"/>
+ </cd:parameter>
+ <cd:parameter name="spaceafterside">
+ <cd:constant type="none"/>
+ <cd:inherit name="blank"/>
+ </cd:parameter>
<cd:parameter name="sidethreshold">
<cd:constant type="old"/>
<cd:constant type="dimension" default="yes"/> <!-- value=".5\strutdp" -->
@@ -782,4 +790,4 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+</cd:interface>
diff --git a/tex/context/interface/mkiv/i-initial.xml b/tex/context/interface/mkiv/i-initial.xml
index 7f0993acc..6c0dd7657 100644
--- a/tex/context/interface/mkiv/i-initial.xml
+++ b/tex/context/interface/mkiv/i-initial.xml
@@ -14,7 +14,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupinitial" level="style"category="fonts" file="typo-drp.mkiv">
+ <cd:command name="setupinitial" level="style" category="fonts" file="typo-drp.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name-list-optional"/>
<cd:assignments list="yes">
@@ -78,4 +78,4 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+</cd:interface>
diff --git a/tex/context/interface/mkiv/i-itemgroup.xml b/tex/context/interface/mkiv/i-itemgroup.xml
index b811592be..84cae20bb 100644
--- a/tex/context/interface/mkiv/i-itemgroup.xml
+++ b/tex/context/interface/mkiv/i-itemgroup.xml
@@ -43,6 +43,7 @@
<cd:constant type="joinedup"/>
<cd:constant type="serried"/>
<cd:constant type="stopper"/>
+ <cd:constant type="nostopper"/>
<cd:constant type="unpacked"/>
<cd:constant type="repeat"/>
<cd:constant type="norepeat"/>
@@ -599,4 +600,4 @@
-->
-</cd:interface> \ No newline at end of file
+</cd:interface>
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index 95cf9aa50..d98590aeb 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-section.xml b/tex/context/interface/mkiv/i-section.xml
index c2c8bbdd5..f3cf13d3e 100644
--- a/tex/context/interface/mkiv/i-section.xml
+++ b/tex/context/interface/mkiv/i-section.xml
@@ -112,6 +112,7 @@
<cd:constant type="no"/>
<cd:constant type="hidden"/>
<cd:constant type="empty"/>
+ <cd:constant type="section"/>
</cd:parameter>
<cd:parameter name="number">
<cd:constant type="yes" default="yes"/>
diff --git a/tex/context/interface/mkiv/i-strut.xml b/tex/context/interface/mkiv/i-strut.xml
index ff200e4db..0653dd214 100644
--- a/tex/context/interface/mkiv/i-strut.xml
+++ b/tex/context/interface/mkiv/i-strut.xml
@@ -12,6 +12,8 @@
<cd:command name="struthtdp" level="system" file="supp-box.mkiv"/>
+ <cd:command name="strutgap" level="system" file="supp-box.mkiv"/>
+
<cd:command name="setupstruts" level="style" file="spac-ver.mkiv">
<cd:arguments>
<cd:keywords optional="yes">
@@ -60,4 +62,4 @@
<cd:command name="strut" type="environment" begin="beg" end="end" level="system" file="spac-ver.mkiv"/>
-</cd:interface> \ No newline at end of file
+</cd:interface>
diff --git a/tex/context/interface/mkiv/i-todo.xml b/tex/context/interface/mkiv/i-todo.xml
new file mode 100644
index 000000000..a3d17515f
--- /dev/null
+++ b/tex/context/interface/mkiv/i-todo.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" ?>
+
+<!--
+
+ page-ffl.mkiv:
+
+ \startfacingfloat[tag] ... \stopfacingfloat
+ \definefacingfloat
+ \setupfacingfloat
+
+ keywords: spaceinbetween inbetween style color page
+
+ typo-pnc.mkiv
+
+ \setperiodkerning
+ \resetperiodkerning
+ \defineperiodkerning
+
+ keywords: factor
+
+-->
diff --git a/tex/context/modules/mkiv/m-timing.mkiv b/tex/context/modules/mkiv/m-timing.mkiv
index 5502768f6..404d5bae0 100644
--- a/tex/context/modules/mkiv/m-timing.mkiv
+++ b/tex/context/modules/mkiv/m-timing.mkiv
@@ -31,7 +31,7 @@
\definecolor[usage:time] [darkblue]
\definecolor[usage:frame][darkgray]
-\ctxloadluafile{trac-tim}{}
+\ctxloadluafile{trac-tim}
\startluacode
local progress = moduledata.progress
diff --git a/tex/context/modules/mkiv/m-typesetting.mkiv b/tex/context/modules/mkiv/m-typesetting.mkiv
index 34713fa38..56cf85bbe 100644
--- a/tex/context/modules/mkiv/m-typesetting.mkiv
+++ b/tex/context/modules/mkiv/m-typesetting.mkiv
@@ -21,19 +21,30 @@
\definecombination
[fourpages]
+ [twopages]
[distance=.5\bodyfontsize,
width=\textwidth]
\definecombination
[sixpages]
+ [twopages]
[distance=.5\bodyfontsize,
width=\textwidth]
+\definemeasure[firstpages][\dimexpr\dimexpr\textwidth-1 \bodyfontsize\relax/2\relax]
\definemeasure[twopages] [\dimexpr\dimexpr\textwidth-3 \bodyfontsize\relax/4\relax]
\definemeasure[fourpages] [\dimexpr\dimexpr\textwidth-3 \bodyfontsize\relax/4\relax]
\definemeasure[sixpages] [\dimexpr\dimexpr\textwidth-2.5\bodyfontsize\relax/6\relax]
\definemeasure[eightpages][\dimexpr\dimexpr\textwidth-3 \bodyfontsize\relax/4\relax]
+\starttexdefinition unexpanded WhenValidPage#1
+ \ifnum#1>\noffigurepages\relax
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi
+\stoptexdefinition
+
\starttexdefinition unexpanded OnePage #1
\startlinecorrection[blank]
\startcombination[twopages][1*1]
@@ -42,6 +53,15 @@
\stoplinecorrection
\stoptexdefinition
+\starttexdefinition unexpanded FirstPages #1
+ \startlinecorrection[blank]
+ \startcombination[twopages][2*1]
+ {\typesetfile[#1.tex][page=1,width=\measure{firstpages}]} {1}
+ {\typesetfile[#1.tex][page=2,width=\measure{firstpages}]} {2}
+ \stopcombination
+ \stoplinecorrection
+\stoptexdefinition
+
\starttexdefinition unexpanded OneSpread #1
\startlinecorrection[blank]
\startcombination[twopages][1*1]
@@ -71,10 +91,10 @@
\starttexdefinition unexpanded FourPages #1
\startlinecorrection[blank]
\startcombination[fourpages][4*1]
- {\typesetfile[#1.tex][page=1,width=\measure{fourpages}]} {1}
- {\typesetfile[#1.tex][page=2,width=\measure{fourpages}]} {2}
- {\typesetfile[#1.tex][page=3,width=\measure{fourpages}]} {3}
- {\typesetfile[#1.tex][page=4,width=\measure{fourpages}]} {4}
+ {\typesetfile[#1.tex][page=1,width=\measure{fourpages}]} {1}
+ {\WhenValidPage{2}{\typesetfile[#1.tex][page=2,width=\measure{fourpages}]}} {\WhenValidPage{2}{2}}
+ {\WhenValidPage{3}{\typesetfile[#1.tex][page=3,width=\measure{fourpages}]}} {\WhenValidPage{3}{3}}
+ {\WhenValidPage{4}{\typesetfile[#1.tex][page=4,width=\measure{fourpages}]}} {\WhenValidPage{4}{4}}
\stopcombination
\stoplinecorrection
\stoptexdefinition
@@ -82,10 +102,10 @@
\starttexdefinition unexpanded FourSpread #1
\startlinecorrection[blank]
\startcombination[fourpages][4*1]
- {\typesetfile[#1.tex][page=2,width=\measure{fourpages}]} {2}
- {\typesetfile[#1.tex][page=3,width=\measure{fourpages}]} {3}
- {\typesetfile[#1.tex][page=4,width=\measure{fourpages}]} {4}
- {\typesetfile[#1.tex][page=5,width=\measure{fourpages}]} {5}
+ {\typesetfile[#1.tex][page=2,width=\measure{fourpages}]} {2}
+ {\WhenValidPage{3}{\typesetfile[#1.tex][page=3,width=\measure{fourpages}]}} {\WhenValidPage{3}{3}}
+ {\WhenValidPage{4}{\typesetfile[#1.tex][page=4,width=\measure{fourpages}]}} {\WhenValidPage{4}{4}}
+ {\WhenValidPage{5}{\typesetfile[#1.tex][page=5,width=\measure{fourpages}]}} {\WhenValidPage{5}{5}}
\stopcombination
\stoplinecorrection
\stoptexdefinition
@@ -93,12 +113,12 @@
\starttexdefinition unexpanded SixPages #1
\startlinecorrection[blank]
\startcombination[sixpages][6*1]
- {\typesetfile[#1.tex][page=1,width=\measure{sixpages}]} {1}
- {\typesetfile[#1.tex][page=2,width=\measure{sixpages}]} {2}
- {\typesetfile[#1.tex][page=3,width=\measure{sixpages}]} {3}
- {\typesetfile[#1.tex][page=4,width=\measure{sixpages}]} {4}
- {\typesetfile[#1.tex][page=5,width=\measure{sixpages}]} {5}
- {\typesetfile[#1.tex][page=6,width=\measure{sixpages}]} {6}
+ {\typesetfile[#1.tex][page=1,width=\measure{sixpages}]} {1}
+ {\WhenValidPage{2}{\typesetfile[#1.tex][page=2,width=\measure{sixpages}]}} {\WhenValidPage{2}{2}}
+ {\WhenValidPage{3}{\typesetfile[#1.tex][page=3,width=\measure{sixpages}]}} {\WhenValidPage{3}{3}}
+ {\WhenValidPage{4}{\typesetfile[#1.tex][page=4,width=\measure{sixpages}]}} {\WhenValidPage{4}{4}}
+ {\WhenValidPage{5}{\typesetfile[#1.tex][page=5,width=\measure{sixpages}]}} {\WhenValidPage{5}{5}}
+ {\WhenValidPage{6}{\typesetfile[#1.tex][page=6,width=\measure{sixpages}]}} {\WhenValidPage{6}{6}}
\stopcombination
\stoplinecorrection
\stoptexdefinition
@@ -106,12 +126,12 @@
\starttexdefinition unexpanded SixSpread #1
\startlinecorrection[blank]
\startcombination[sixpages][6*1]
- {\typesetfile[#1.tex][page=2,width=\measure{sixpages}]} {2}
- {\typesetfile[#1.tex][page=3,width=\measure{sixpages}]} {3}
- {\typesetfile[#1.tex][page=4,width=\measure{sixpages}]} {4}
- {\typesetfile[#1.tex][page=5,width=\measure{sixpages}]} {5}
- {\typesetfile[#1.tex][page=6,width=\measure{sixpages}]} {6}
- {\typesetfile[#1.tex][page=7,width=\measure{sixpages}]} {7}
+ {\typesetfile[#1.tex][page=2,width=\measure{sixpages}]} {2}
+ {\WhenValidPage{3}{\typesetfile[#1.tex][page=3,width=\measure{sixpages}]}} {\WhenValidPage{3}{3}}
+ {\WhenValidPage{4}{\typesetfile[#1.tex][page=4,width=\measure{sixpages}]}} {\WhenValidPage{4}{4}}
+ {\WhenValidPage{5}{\typesetfile[#1.tex][page=5,width=\measure{sixpages}]}} {\WhenValidPage{5}{5}}
+ {\WhenValidPage{6}{\typesetfile[#1.tex][page=6,width=\measure{sixpages}]}} {\WhenValidPage{6}{6}}
+ {\WhenValidPage{7}{\typesetfile[#1.tex][page=7,width=\measure{sixpages}]}} {\WhenValidPage{7}{7}}
\stopcombination
\stoplinecorrection
\stoptexdefinition
@@ -119,14 +139,14 @@
\starttexdefinition unexpanded EightPages #1
\startlinecorrection[blank]
\startcombination[fourpages][4*2]
- {\typesetfile[#1.tex][page=1,width=\measure{eightpages}]} {#1 / 1}
- {\typesetfile[#1.tex][page=2,width=\measure{eightpages}]} {#1 / 2}
- {\typesetfile[#1.tex][page=3,width=\measure{eightpages}]} {#1 / 3}
- {\typesetfile[#1.tex][page=4,width=\measure{eightpages}]} {#1 / 4}
- {\typesetfile[#1.tex][page=5,width=\measure{eightpages}]} {#1 / 5}
- {\typesetfile[#1.tex][page=6,width=\measure{eightpages}]} {#1 / 6}
- {\typesetfile[#1.tex][page=7,width=\measure{eightpages}]} {#1 / 7}
- {\typesetfile[#1.tex][page=8,width=\measure{eightpages}]} {#1 / 8}
+ {\typesetfile[#1.tex][page=1,width=\measure{eightpages}]} {#1 / 1}
+ {\WhenValidPage{2}{\typesetfile[#1.tex][page=2,width=\measure{eightpages}]}} {\WhenValidPage{2}{#1 / 2}}
+ {\WhenValidPage{3}{\typesetfile[#1.tex][page=3,width=\measure{eightpages}]}} {\WhenValidPage{3}{#1 / 3}}
+ {\WhenValidPage{4}{\typesetfile[#1.tex][page=4,width=\measure{eightpages}]}} {\WhenValidPage{4}{#1 / 4}}
+ {\WhenValidPage{5}{\typesetfile[#1.tex][page=5,width=\measure{eightpages}]}} {\WhenValidPage{5}{#1 / 5}}
+ {\WhenValidPage{6}{\typesetfile[#1.tex][page=6,width=\measure{eightpages}]}} {\WhenValidPage{6}{#1 / 6}}
+ {\WhenValidPage{7}{\typesetfile[#1.tex][page=7,width=\measure{eightpages}]}} {\WhenValidPage{7}{#1 / 7}}
+ {\WhenValidPage{8}{\typesetfile[#1.tex][page=8,width=\measure{eightpages}]}} {\WhenValidPage{8}{#1 / 8}}
\stopcombination
\stoplinecorrection
\stoptexdefinition
@@ -134,14 +154,14 @@
\starttexdefinition unexpanded EightSpread #1
\startlinecorrection[blank]
\startcombination[fourpages][4*2]
- {\typesetfile[#1.tex][page=2,width=\measure{eightpages}]} {#1 / 2}
- {\typesetfile[#1.tex][page=3,width=\measure{eightpages}]} {#1 / 3}
- {\typesetfile[#1.tex][page=4,width=\measure{eightpages}]} {#1 / 4}
- {\typesetfile[#1.tex][page=5,width=\measure{eightpages}]} {#1 / 5}
- {\typesetfile[#1.tex][page=6,width=\measure{eightpages}]} {#1 / 6}
- {\typesetfile[#1.tex][page=7,width=\measure{eightpages}]} {#1 / 7}
- {\typesetfile[#1.tex][page=8,width=\measure{eightpages}]} {#1 / 8}
- {\typesetfile[#1.tex][page=9,width=\measure{eightpages}]} {#1 / 9}
+ {\typesetfile[#1.tex][page=2,width=\measure{eightpages}]} {#1 / 2}
+ {\WhenValidPage{3}{\typesetfile[#1.tex][page=3,width=\measure{eightpages}]}} {\WhenValidPage{3}{#1 / 3}}
+ {\WhenValidPage{4}{\typesetfile[#1.tex][page=4,width=\measure{eightpages}]}} {\WhenValidPage{4}{#1 / 4}}
+ {\WhenValidPage{5}{\typesetfile[#1.tex][page=5,width=\measure{eightpages}]}} {\WhenValidPage{5}{#1 / 5}}
+ {\WhenValidPage{6}{\typesetfile[#1.tex][page=6,width=\measure{eightpages}]}} {\WhenValidPage{6}{#1 / 6}}
+ {\WhenValidPage{7}{\typesetfile[#1.tex][page=7,width=\measure{eightpages}]}} {\WhenValidPage{7}{#1 / 7}}
+ {\WhenValidPage{8}{\typesetfile[#1.tex][page=8,width=\measure{eightpages}]}} {\WhenValidPage{8}{#1 / 8}}
+ {\WhenValidPage{9}{\typesetfile[#1.tex][page=9,width=\measure{eightpages}]}} {\WhenValidPage{9}{#1 / 9}}
\stopcombination
\stoplinecorrection
\stoptexdefinition
diff --git a/tex/context/modules/mkiv/s-evohome.mkiv b/tex/context/modules/mkiv/s-evohome.mkiv
index e5c2ae6bb..1b1dc2c81 100644
--- a/tex/context/modules/mkiv/s-evohome.mkiv
+++ b/tex/context/modules/mkiv/s-evohome.mkiv
@@ -11,25 +11,20 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-% in cronjob on one of the servers:
-%
-% mtxrun --script youless --collect --host=192.168.2.50 --watt youless-watt.lua
-% mtxrun --script youless --collect --host=192.168.2.50 --kwk youless-kwh.lua
-
\setupbodyfont[dejavu]
\starttext
\startluacode
-require("util-evo")
+local evohome = require("util-evo")
moduledata.evohome = { }
function moduledata.evohome.status(specification)
- local presets = utilities.evohome.loadpresets(specification.presets)
- local zones = utilities.evohome.loadtemperatures(presets)
+ local presets = evohome.helpers.loadpresets(specification.presets)
+ local zones = evohome.helpers.loadtemperatures(presets)
-- todo : time
@@ -65,8 +60,9 @@ function moduledata.evohome.status(specification)
for i=1,#zones do
local zone = zones[i]
- local data = utilities.evohome.getzonestate(presets,zone.name)
- local schedule = data.schedule or { }
+-- evohome.helpers.updatezone(presets,zone.name)
+ local data = evohome.helpers.getzonestate(presets,zone.name)
+ local schedule = data and data.schedule or { }
context.startsubject { title = zone.name }
context.starttabulate { "|l|c|c|" }
context.BC() context("day")
@@ -101,8 +97,8 @@ end
function moduledata.evohome.history(specification)
- local presets = utilities.evohome.loadpresets(specification.presets)
- local zones = utilities.evohome.loadtemperatures(presets)
+ local presets = evohome.helpers.loadpresets(specification.presets)
+ local zones = evohome.helpers.loadtemperatures(presets)
if not zones then
context("no zones")
@@ -110,7 +106,7 @@ function moduledata.evohome.history(specification)
return
end
- local data = utilities.evohome.loadhistory(presets)
+ local data = evohome.helpers.loadhistory(presets)
if not zones then
context("no history")
@@ -279,7 +275,7 @@ end
local specification = {
year = 2017,
-- month = 11,
- presets = "c:/data/develop/domotica/code/evohome-presets.lua",
+ presets = "c:/data/develop/domotica/evohome/evohome-presets.lua",
}
moduledata.evohome.status (specification)
diff --git a/tex/context/modules/mkiv/s-fonts-ligatures.mkiv b/tex/context/modules/mkiv/s-fonts-ligatures.mkiv
index fc49ec5c5..6a5da48ea 100644
--- a/tex/context/modules/mkiv/s-fonts-ligatures.mkiv
+++ b/tex/context/modules/mkiv/s-fonts-ligatures.mkiv
@@ -156,12 +156,12 @@
\stoptexdefinition
\starttexdefinition showotfligaturesexample #1#2
- \ctxlua{document.currentdiscexpansion = fonts.getdiscexpansion()}%
+ % \ctxlua{document.currentdiscexpansion = fonts.getdiscexpansion()}%
\showotfligaturescaptions {#1}
\showotfligatureslines {#2}
\showotfligaturesparagraphs{#2}
\showotfligaturesextremes {#2}
- \ctxlua{fonts.setdiscexpansion(document.currentdiscexpansion)}%
+ % \ctxlua{fonts.setdiscexpansion(document.currentdiscexpansion)}%
\stoptexdefinition
% todo: n -> and split in lua
diff --git a/tex/context/modules/mkiv/s-fonts-variable.mkiv b/tex/context/modules/mkiv/s-fonts-variable.mkiv
index 1a826314d..5c9d53d33 100644
--- a/tex/context/modules/mkiv/s-fonts-variable.mkiv
+++ b/tex/context/modules/mkiv/s-fonts-variable.mkiv
@@ -73,10 +73,6 @@
\stopbuffer
\showfontvariations
- [font=file:VotoSerifGX.ttf,
- ]% max=6]
-
- \showfontvariations
[font=file:adobevfprototype.otf]
\showfontvariations
@@ -85,9 +81,9 @@
\showfontvariations
[font=file:DecoVar-VF.ttf]
- \showfontvariations
- [font=file:VotoSerifGX.ttf,
- max=15]
+ % \showfontvariations
+ % [font=file:VotoSerifGX.ttf,
+ % max=15]
\showfontvariations
[font=file:Selawik-Variable.ttf]
@@ -109,6 +105,6 @@
% [font=file:AmstelvarAlpha-VF.ttf]
\showfontvariations
- [font=file:bahnshrift.ttf]
+ [font=file:bahnschrift.ttf]
\stoptext
diff --git a/tex/context/modules/mkiv/s-youless.mkiv b/tex/context/modules/mkiv/s-youless.mkiv
index e15973b9c..d8b6e2ff6 100644
--- a/tex/context/modules/mkiv/s-youless.mkiv
+++ b/tex/context/modules/mkiv/s-youless.mkiv
@@ -23,125 +23,165 @@
% in cronjob on one of the servers:
%
-% mtxrun --script youless --collect --host=192.168.2.50 --watt youless-watt.lua
-% mtxrun --script youless --collect --host=192.168.2.50 --kwk youless-kwh.lua
+% mtxrun --script youless --collect --host=192.168.2.50 --nobackup --electricity youless-electricity.lua
\startluacode
require("util-you")
- moduledata.youless = { }
+ local round = math.round
- function moduledata.youless.kwh(specification)
- -- todo
- end
+ moduledata.youless = { }
- function moduledata.youless.watt(specification)
+ local function process(specification)
- local year = tonumber(specification.year) or os.today().year
- local data = table.load(specification.filename or "youless-watt.lua")
+ local data, message = utilities.youless.analyze(specification.filename or "youless-electricity.lua")
- if not data or data.variant ~= "watt" then
- context("invalid variant")
+ if not data then
+ context(message)
return
end
- utilities.youless.analyze(data)
-
- -- for the moment no specific font scaling
-
- local years = data.years
-
- if not years then
- context("no years")
- return
+ local year = tonumber(specification.year) or os.today().year
+ local years = data.years
+ local variant = data.variant
+ local unit = specification.unit
+ local maxunit = specification.maxunit
+
+ local max = specification[maxunit]
+
+ if not max then
+ if unit == "watt" then
+ max = 10000
+ elseif unit == "liters" then
+ max = 1000
+ else
+ max = 5000 -- can't happen
+ end
end
- for y=year,year do
-
- local year = years[y]
- local scale = 20
- local mark = 3
- local maxwatt = specification.maxwatt or year.maxwatt
-
- for m=1,12 do
- local month = year.months[m]
- if month then
- context.startMPpage { offset = "10pt" }
- context("linecap := butt; pickup pencircle scaled .5")
+ local max = max
+ local delta = round(max/10)
+ local scale = round(delta/20)
+ local mark = 3
- for i=0,(math.div(maxwatt,1000)+1)*1000,100 do
- context("draw (%s,%s) -- (%s,%s) withcolor .6white ;",0,i/scale,31 * 24,i/scale)
- end
+ for y=year,year do
+ local year = years[y]
+ if year then
+ local grand = 0
+ for m=1,12 do
+ local month = year.months[m]
+ if month then
+ context.startMPpage { offset = "10pt" }
+ context("linecap := butt; pickup pencircle scaled .5")
+
+ for i=0,(math.div(max,delta)+1)*delta,delta/10 do
+ context("draw (%s,%s) -- (%s,%s) withcolor .6white ;",0,i/scale,31 * 24,i/scale)
+ end
- context("draw (0,%s) -- (31 * 24,%s) dashed dashpattern(on 6 off 6) withcolor darkgreen withpen pencircle scaled 1 ;",year.watt /scale,year.watt /scale)
- context("draw (0,%s) -- (31 * 24,%s) dashed dashpattern(off 6 on 6) withcolor darkred withpen pencircle scaled 1 ;",month.watt/scale,month.watt/scale)
-
- local days = month.days
- if days then
- local nd = os.nofdays(y,m)
- for d=1,nd do
- local day = days[d]
- local xoffset = (d-1) * 24
- local wd = os.weekday(d,m,y)
- local weekend = wd == 1 or wd == 7
- if not weekend then
- -- okay
- elseif mark == 1 then
- context("draw (%s,%s) -- (%s,%s) ; ",xoffset, -17.5,xoffset, -32.5)
- context("draw (%s,%s) -- (%s,%s) ; ",xoffset+24,-17.5,xoffset+24,-32.5)
- elseif mark == 2 then
- context("draw (%s,%s) -- (%s,%s) ; ",xoffset, -17.5,xoffset+24,-17.5)
- context("draw (%s,%s) -- (%s,%s) ; ",xoffset, -32.5,xoffset+24,-32.5)
- elseif mark == 3 then
- context("draw unitsquare xysized (%s,%s) shifted (%s,%s) ; ",24,15,xoffset,-32.5)
- end
- context([[draw textext("%s") shifted (%s,%s) ; ]],d,xoffset + 12,-25)
- if day then
- for h=0,23 do
- local hours = day.hours
- if hours then
- local hour = hours[h]
- if hour then
- local dx = xoffset + h
- local dy = hour.watt/scale
- local dm = hour.maxwatt/scale
- context("draw (%s,%s) -- (%s,%s) withcolor %s ; ",dx, 0,dx,dy,weekend and "darkmagenta" or "darkblue")
- context("draw (%s,%s) -- (%s,%s) withcolor %s ; ",dx,dy,dx,dm,"darkgray")
+ context("draw (0,%s) -- (31 * 24,%s) dashed dashpattern(on 6 off 6) withcolor darkgreen withpen pencircle scaled 1 ;",year [unit]/scale,year [unit]/scale)
+ context("draw (0,%s) -- (31 * 24,%s) dashed dashpattern(off 6 on 6) withcolor darkred withpen pencircle scaled 1 ;",month[unit]/scale,month[unit]/scale)
+
+ local days = month.days
+ local total = 0
+ if days then
+ local nd = os.nofdays(y,m)
+ for d=1,nd do
+ local day = days[d]
+ local xoffset = (d-1) * 24
+ local wd = os.weekday(d,m,y)
+ local weekend = wd == 1 or wd == 7
+ if not weekend then
+ -- okay
+ elseif mark == 1 then
+ context("draw (%s,%s) -- (%s,%s) ; ",xoffset, -17.5,xoffset, -32.5)
+ context("draw (%s,%s) -- (%s,%s) ; ",xoffset+24,-17.5,xoffset+24,-32.5)
+ elseif mark == 2 then
+ context("draw (%s,%s) -- (%s,%s) ;",xoffset, -17.5,xoffset+24,-17.5)
+ context("draw (%s,%s) -- (%s,%s) ;",xoffset, -32.5,xoffset+24,-32.5)
+ elseif mark == 3 then
+ context("draw unitsquare xysized (%s,%s) shifted (%s,%s) ;",24,15,xoffset,-32.5)
+ end
+ context([[draw textext("\strut%s") shifted (%s,%s) ;]],d,xoffset + 12,-25)
+ if day then
+ for h=0,23 do
+ local hours = day.hours
+ if hours then
+ local hour = hours[h]
+ if hour then
+ local dx = xoffset + h
+ local dy = hour[unit]/scale
+ local dm = hour[maxunit]/scale
+ context("draw (%s,%s) -- (%s,%s) withcolor %s ;",dx, 0,dx,dy,weekend and "darkmagenta" or "darkblue")
+ context("draw (%s,%s) -- (%s,%s) withcolor %s ;",dx,dy,dx,dm,"darkgray")
+ end
end
end
+ local use = day.total
+ if use then
+ context([[draw textext("\strut\small\small\small%0.1f") shifted (%s,%s) ;]],use/1000,xoffset + 12,-7.5)
+ total = total + use
+ end
end
end
+ for d=0,30 do
+ local xoffset = d * 24
+ context("draw (%s,%s) -- (%s,%s) withcolor darkgray ;",xoffset+ 0,0,xoffset+ 0,-10)
+ context("draw (%s,%s) -- (%s,%s) withcolor darkgray ;",xoffset+ 6,0,xoffset+ 6,-2.5)
+ context("draw (%s,%s) -- (%s,%s) withcolor darkgray ;",xoffset+12,0,xoffset+12,-5)
+ context("draw (%s,%s) -- (%s,%s) withcolor darkgray ;",xoffset+18,0,xoffset+18,-2.5)
+ end
+ local xoffset = 31 * 24
+ context("draw (%s,%s) -- (%s,%s) withcolor darkgray ;",xoffset,0,xoffset,-10)
end
- for d=0,30 do
- local xoffset = d * 24
- context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset+ 0,0,xoffset+ 0,-10)
- context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset+ 6,0,xoffset+ 6,-2.5)
- context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset+12,0,xoffset+12,-5)
- context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset+18,0,xoffset+18,-2.5)
- end
- local xoffset = 31 * 24
- context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset,0,xoffset,-10)
- end
- local max = (math.div(maxwatt,1000)+1)
+ grand = grand + total
- for i=0,max*1000,1000 do
- context([[draw textext.lft("%s") shifted (%s,%s) ; ]],i,-10,i/scale)
- context("draw (%s,%s) -- (%s,%s) withcolor .2white ;",0,i/scale,31 * 24,i/scale)
- end
+ local max = (math.div(max,delta))
+
+ for i=0,max*delta,delta do
+ if i > 0 then
+ context([[draw textext.lft("\hbox to 3.5em{\hss\strut%r}") shifted (%s,%s) ; ]],i,-10,i/scale)
+ end
+ context("draw (%s,%s) -- (%s,%s) withcolor .2white ;",0,i/scale,31 * 24,i/scale)
+ end
- context([[draw textext("\strut\month{%s}\enspace%s") shifted (%s,%s) ; ]],m, y, 31 * 24 / 2, -50)
- context([[draw textext.lft("watt") shifted (%s,%s) ; ]],-10,-25)
+ context([[draw textext ("\strut\Word{%s}\enspace\emdash\enspace\month{%s}\enspace%s") shifted (%s,%s) ; ]],variant, m, y, 31 * 24 / 2, -50)
+ context([[draw textext.lft("\hbox to 3.5em{\hss\strut%s}") shifted (%s,%s) ; ]],unit,-10,-25)
+ context([[draw textext.lft("\hbox to 3.5em{\hss\strut\small\small\small%0.1f %s}") shifted (%s,%s) ;]],total/1000,unit == "watt" and "kWh" or [[m\high{3}]],-10, -7.5)
+ context([[draw textext.lft("\hbox to 3.5em{\hss\strut\small\small\small\Sigma\nbsp%0.1f %s}") shifted (%s,%s) ;]],grand/1000,unit == "watt" and "kWh" or [[m\high{3}]],-10,-50.0)
- context.stopMPpage()
- else
- -- maybe placeholder
+ context.stopMPpage()
+ else
+ -- maybe placeholder
+ end
end
end
-
end
+ end
+
+ function moduledata.youless.kwh(specification)
+ -- todo
+ end
+
+ function moduledata.youless.electricity(specification)
+ specification.unit = "watt"
+ specification.maxunit = "maxwatt"
+ process(specification)
+ end
+
+ moduledata.youless.watt = moduledata.youless.electricity
+
+ function moduledata.youless.gas(specification)
+ specification.unit = "liters"
+ specification.maxunit = "maxliters"
+ process(specification)
+ end
+ function moduledata.youless.pulse(specification)
+ specification.unit = "watt"
+ specification.maxunit = "maxwatt"
+ process(specification)
end
\stopluacode
@@ -160,11 +200,11 @@
\startluacode
- -- os.execute([[mtxrun --script youless --collect --watt "c:/data/system/youless/data/youless-watt.lua"]])
- -- os.execute([[mtxrun --script youless --collect --watt --nobackup "c:/data/system/youless/data/youless-watt.lua"]])
- -- moduledata.youless.watt { year = 2013, filename = "c:/data/system/youless/data/youless-watt.lua" }
+ -- os.execute([[mtxrun --script youless --collect --electricity "c:/data/system/youless/data/youless-electricity.lua"]])
+ -- os.execute([[mtxrun --script youless --collect --electricity --nobackup "c:/data/system/youless/data/youless-electricity.lua"]])
+ -- moduledata.youless.electricity { year = 2017, filename = "c:/data/system/youless/data/youless-electricity.lua" }
- moduledata.youless.watt { year = 2013, filename = "youless-watt.lua" }
+ moduledata.youless.electricity { year = 2017, filename = "youless-electricity.lua" }
\stopluacode
diff --git a/tex/context/modules/mkiv/x-asciimath.lua b/tex/context/modules/mkiv/x-asciimath.lua
index eed69d1f2..794cddbd1 100644
--- a/tex/context/modules/mkiv/x-asciimath.lua
+++ b/tex/context/modules/mkiv/x-asciimath.lua
@@ -35,7 +35,7 @@ if not characters then
require("char-ent")
end
-local type, rawget = type, rawget
+local rawget, next, type = rawget, next, type
local concat, insert, remove = table.concat, table.insert, table.remove
local rep, gmatch, gsub, find = string.rep, string.gmatch, string.gsub, string.find
local utfchar, utfbyte = utf.char, utf.byte
diff --git a/tex/context/modules/mkiv/x-calcmath.lua b/tex/context/modules/mkiv/x-calcmath.lua
index c96d8d0ac..41a43cacd 100644
--- a/tex/context/modules/mkiv/x-calcmath.lua
+++ b/tex/context/modules/mkiv/x-calcmath.lua
@@ -8,6 +8,7 @@ if not modules then modules = { } end modules ['x-calcmath'] = {
-- this really needs to be redone
+local next, type = next, type
local format, lower, upper, gsub, sub = string.format, string.lower, string.upper, string.gsub, string.sub
local concat = table.concat
local lpegmatch = lpeg.match
diff --git a/tex/context/modules/mkiv/x-cals.lua b/tex/context/modules/mkiv/x-cals.lua
index ef85630da..9d54733b8 100644
--- a/tex/context/modules/mkiv/x-cals.lua
+++ b/tex/context/modules/mkiv/x-cals.lua
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['x-cals'] = {
license = "see context related readme files"
}
-local next = next
+local next, type = next, type
local format, lower = string.format, string.lower
local xmlcprint, xmlcollected, xmlelements = xml.cprint, xml.collected, xml.elements
local n_todimen, s_todimen = number.todimen, string.todimen
diff --git a/tex/context/modules/mkiv/x-setups-basics.mkiv b/tex/context/modules/mkiv/x-setups-basics.mkiv
index 0836de76b..be96466b8 100644
--- a/tex/context/modules/mkiv/x-setups-basics.mkiv
+++ b/tex/context/modules/mkiv/x-setups-basics.mkiv
@@ -15,6 +15,14 @@
%D We can make this module a bit cleaner using more recent features or we go \LUA\
%D completely but as this style evolved over 15 years it's a waste of time.
%D
+%D
+%D Thanks to Wolfgang these descriptions have become quite complete! In the process
+%D of covering more commands and expecially different instances of the same command,
+%D either or not generated, the supporting macros became more complex. I must admit
+%D that it's not the nicest code base and whenever I have to add or patch something
+%D I have to suppress the urge to rewrite this file. It needs watching a few
+%D energetic videos (for instance with Simon Phillips drumming) to get going.
+%D
%D As we also have a help server we can make a common framework for this \unknown\
%D but even then, this file is also a test for the the \XML\ processor.
%D
@@ -25,21 +33,46 @@
%D Currently we load the \XML\ file and when not in the english interface we just
%D remap the relevant words to their translation.
-%D Todo: use lua instead of synonyms
+%D \startbuffer
+%D \usemodule[x-setups-basics]
+%D
+%D \loadsetups[context-en]
+%D
+%D \starttext
+%D
+%D \showsetup[starttyping:instance:LUA]
+%D
+%D \showsetup[starttyping:instance:typing]
+%D
+%D \showsetup[starttyping:instance:argument]
+%D
+%D \showsetup [completelistoffloats:instance:chemicals] \blank
+%D \shortsetup[completelistoffloats:instance:chemicals] \blank
+%D \basicsetup[completelistoffloats:instance:chemicals] \blank
+%D
+%D \cmdfullsetup [completelistoffloats:instance:chemicals] \blank
+%D \cmdshortsetup[completelistoffloats:instance:chemicals] \blank
+%D \cmdbasicsetup[completelistoffloats:instance:chemicals] \blank
+%D
+%D % \cmdinternal{...}
+%D
+%D \page \placeeverysetup \page
+%D \page \placeeverysetupname \page
+%D
+%D \stoptext
+%D \stopbuffer
+
+% Todo: use lua instead of synonyms
\unprotect
\defineregister
[texmacro]
-\unexpanded\def\texcommandmeaning#1{}
-\unexpanded\def\texcommandusage #1{}
-
\definesorting
[texcommand]
[texcommands]
- [\texcommandmeaning]
- [\texcommandusage]
+ [\v!none]
\setupsorting
[texcommand]
@@ -77,7 +110,6 @@
\unexpanded\def\setupalwcolor{}
\unexpanded\def\setupoptcolor{darkgray}
-% \unexpanded\def\setupvarword#1{{\sl\detokenize{#1}}}
\unexpanded\def\setupvarword#1{\detokenize{#1}}
\unexpanded\def\setupintword#1{\WORD{\detokenize{#1}}}
\unexpanded\def\setuptxtword#1{\detokenize{#1}}
@@ -150,16 +182,14 @@
\stopxmlsetups
\startxmlsetups xml:setups:register
-% \doif {\xmlatt{#1}{variant}} {instance} {
- \doifcommon {\xmlatt{#1}{variant}} {instance,instance:assignment,instance:ownnumber} {
+ \doifcommon {\xmlatt{#1}{variant}} {instance,instance:assignment,instance:ownnumber,instance:argument} {
\def\docommand##1{
\xmlsetup{#1}{xml:setups:assemblename:instance}
-% \expanded{\texcommand[stp:x:\currentSETUPfullname:##1]{{#1}{##1}}}}%
- \expanded{\texcommand[\currentSETUPfullname:##1]{{#1}{##1}}}}%
+ \expanded{\texcommand[\currentSETUPfullname:##1]{{#1}{##1}}}
+ }%
\processcommacommand[\clf_getinstances{#1}]\docommand
}
\xmlsetup{#1}{xml:setups:assemblename}
-% \expanded{\texcommand[stp:x:\currentSETUPfullname]{{#1}{}}}
\expanded{\texcommand[\currentSETUPfullname]{{#1}{}}}
\stopxmlsetups
@@ -386,7 +416,6 @@
local t = { }
local n = #entries
for i=1,n do
--- t[i] = gsub(entries[i].definition.tag,"^stp:x:","")
t[i] = entries[i].definition.tag
end
table.sort(t)
@@ -488,15 +517,12 @@
\fi}
\def\cmd_show_setup_nop#1% this will trigger 'used'
-% {\registersort[texcommand][stp:x:#1]%
{\registersort[texcommand][#1]%
\ifconditional\c_cmd_show_setup
-% \writestatus{setup}{#1 / \rawsynonymname{texcommand}{stp:x:#1}}%
\writestatus{setup}{#1 / \rawsynonymname{texcommand}{#1}}%
\fi
\startelement[setup][name=#1]%
\startelement[noexport][comment={setup definition #1}]%
-% \edef\cmd_id{\rawsynonymname{texcommand}{stp:x:#1}}%
\edef\cmd_id{\rawsynonymname{texcommand}{#1}}%
\ifx\cmd_id\empty
missing: #1
@@ -517,6 +543,17 @@
\let\placeeverysetup\placeallsetups
+\unexpanded\def\cmd_show_setup_list_basic#1#2#3%
+ {\NC\tttf#2\NC\basicsetup[#2]\NC\NR}
+
+\unexpanded\def\placeeverysetupname
+ {\placelistofsorts
+ [texcommand]
+ [\c!before={\starttabulate[|||]},
+ \c!after=\stoptabulate,
+ \c!criterium=\v!all,
+ \c!command=\cmd_show_setup_list_basic]}
+
%D Typesetting:
\startxmlsetups xml:setups:typeset
@@ -758,24 +795,25 @@
\ignorespaces
\stopxmlsetups
+\startxmlsetups xml:setups:csname \show_setup_component{#1}{csname} \stopxmlsetups
\startxmlsetups xml:setups:content \show_setup_component{#1}{content} \stopxmlsetups
-\startxmlsetups xml:setups:displaymath \show_setup_component{#1}{displaymath}\stopxmlsetups
-\startxmlsetups xml:setups:index \show_setup_component{#1}{index} \stopxmlsetups
-\startxmlsetups xml:setups:math \show_setup_component{#1}{math} \stopxmlsetups
-\startxmlsetups xml:setups:nothing \show_setup_component{#1}{nothing} \stopxmlsetups
-\startxmlsetups xml:setups:file \show_setup_component{#1}{file} \stopxmlsetups
\startxmlsetups xml:setups:position \show_setup_component{#1}{position} \stopxmlsetups
-\startxmlsetups xml:setups:reference \show_setup_component{#1}{reference} \stopxmlsetups
-\startxmlsetups xml:setups:csname \show_setup_component{#1}{csname} \stopxmlsetups
-\startxmlsetups xml:setups:destination \show_setup_component{#1}{destination}\stopxmlsetups
-\startxmlsetups xml:setups:triplet \show_setup_component{#1}{triplet} \stopxmlsetups
-\startxmlsetups xml:setups:word \show_setup_component{#1}{word} \stopxmlsetups
+\startxmlsetups xml:setups:index \show_setup_component{#1}{index} \stopxmlsetups
+\startxmlsetups xml:setups:text \show_setup_component{#1}{text} \stopxmlsetups
+\startxmlsetups xml:setups:apply \show_setup_component{#1}{apply} \stopxmlsetups
\startxmlsetups xml:setups:template \show_setup_component{#1}{template} \stopxmlsetups
+\startxmlsetups xml:setups:triplet \show_setup_component{#1}{triplet} \stopxmlsetups
\startxmlsetups xml:setups:angles \show_setup_component{#1}{angles} \stopxmlsetups
-\startxmlsetups xml:setups:apply \show_setup_component{#1}{apply} \stopxmlsetups
-\startxmlsetups xml:setups:twowords \show_setup_component{#1}{twowords} \stopxmlsetups
-\startxmlsetups xml:setups:threewords \show_setup_component{#1}{threewords} \stopxmlsetups
-\startxmlsetups xml:setups:text \show_setup_component{#1}{text} \stopxmlsetups
+
+%startxmlsetups xml:setups:displaymath \show_setup_component{#1}{displaymath}\stopxmlsetups
+%startxmlsetups xml:setups:math \show_setup_component{#1}{math} \stopxmlsetups
+%startxmlsetups xml:setups:nothing \show_setup_component{#1}{nothing} \stopxmlsetups
+%startxmlsetups xml:setups:file \show_setup_component{#1}{file} \stopxmlsetups
+%startxmlsetups xml:setups:reference \show_setup_component{#1}{reference} \stopxmlsetups
+%startxmlsetups xml:setups:destination \show_setup_component{#1}{destination}\stopxmlsetups
+%startxmlsetups xml:setups:word \show_setup_component{#1}{word} \stopxmlsetups
+%startxmlsetups xml:setups:twowords \show_setup_component{#1}{twowords} \stopxmlsetups
+%startxmlsetups xml:setups:threewords \show_setup_component{#1}{threewords} \stopxmlsetups
% todo: cd:par => \par
% todo: cd:sep => \\
@@ -928,12 +966,12 @@
\stopxmlsetups
\startxmlsetups xml:setups:inherit
-% \cmd_column_two_start{}{}
+ % \cmd_column_two_start{}{}
\rawsetupstring{cd:inherits}:
\enspace
\letterbackslash
\xmlatt{#1}{name}
-% \cmd_column_two_stop
+ % \cmd_column_two_stop
\ignorespaces
\stopxmlsetups
@@ -941,7 +979,7 @@
{\cmd_column_one_start
\cmd_internal_value{#1}%
\cmd_column_one_stop
-% \godown[.75\lineheight]
+ % \godown[.75\lineheight]
\blank[\v!samepage,\v!medium]
\ignorespaces}
@@ -1013,26 +1051,25 @@
% arguments
-\unexpanded\def\show_setup_displaymath#1{\show_setup_any {#1}{displaymath}}
-\unexpanded\def\show_setup_index #1{\show_setup_any {#1}{index}}
-\unexpanded\def\show_setup_math #1{\show_setup_any {#1}{math}}
-\unexpanded\def\show_setup_nothing #1{\show_setup_any {#1}{nothing}}
-\unexpanded\def\show_setup_file #1{\show_setup_any {#1}{file}}
-\unexpanded\def\show_setup_position #1{\show_setup_any {#1}{position}}
-\unexpanded\def\show_setup_template #1{\show_setup_any {#1}{template}}
-\unexpanded\def\show_setup_angles #1{\show_setup_any {#1}{angle}}
-\unexpanded\def\show_setup_reference #1{\show_setup_any {#1}{reference}}
-\unexpanded\def\show_setup_apply #1{\show_setup_any {#1}{apply}}
-\unexpanded\def\show_setup_twowords #1{\show_setup_any {#1}{twowords}}
-\unexpanded\def\show_setup_threewords #1{\show_setup_any {#1}{threewords}}
-\unexpanded\def\show_setup_csname #1{\show_setup_any {#1}{noargument}}
-\unexpanded\def\show_setup_destination#1{\show_setup_any {#1}{destination}}
-\unexpanded\def\show_setup_triplet #1{\show_setup_any {#1}{triplet}}
-\unexpanded\def\show_setup_word #1{\show_setup_any {#1}{word}}
-\unexpanded\def\show_setup_content #1{\show_setup_any {#1}{content}}
-\unexpanded\def\show_setup_text #1{\show_setup_any {#1}{textual}}
-\unexpanded\def\show_setup_to #1{\show_setup_line{#1}{to}}
-\unexpanded\def\show_setup_macro #1{\show_setup_any {#1}{macro}}
+\unexpanded\def\show_setup_csname #1{\show_setup_any{#1}{noargument}}
+\unexpanded\def\show_setup_content #1{\show_setup_any{#1}{content}}
+\unexpanded\def\show_setup_position #1{\show_setup_any{#1}{position}}
+\unexpanded\def\show_setup_index #1{\show_setup_any{#1}{index}}
+\unexpanded\def\show_setup_text #1{\show_setup_any{#1}{textual}}
+\unexpanded\def\show_setup_apply #1{\show_setup_any{#1}{apply}}
+\unexpanded\def\show_setup_template #1{\show_setup_any{#1}{template}}
+\unexpanded\def\show_setup_triplet #1{\show_setup_any{#1}{triplet}}
+\unexpanded\def\show_setup_angles #1{\show_setup_any{#1}{angle}}
+
+%unexpanded\def\show_setup_displaymath#1{\show_setup_any{#1}{displaymath}}
+%unexpanded\def\show_setup_math #1{\show_setup_any{#1}{math}}
+%unexpanded\def\show_setup_nothing #1{\show_setup_any{#1}{nothing}}
+%unexpanded\def\show_setup_file #1{\show_setup_any{#1}{file}}
+%unexpanded\def\show_setup_reference #1{\show_setup_any{#1}{reference}}
+%unexpanded\def\show_setup_destination#1{\show_setup_any{#1}{destination}}
+%unexpanded\def\show_setup_word #1{\show_setup_any{#1}{word}}
+%unexpanded\def\show_setup_twowords #1{\show_setup_any{#1}{twowords}}
+%unexpanded\def\show_setup_threewords #1{\show_setup_any{#1}{threewords}}
% A prelude to a rewrite and some more:
diff --git a/tex/context/modules/mkiv/x-setups-overview.mkiv b/tex/context/modules/mkiv/x-setups-overview.mkiv
index c0047f13a..f6dff12f5 100644
--- a/tex/context/modules/mkiv/x-setups-overview.mkiv
+++ b/tex/context/modules/mkiv/x-setups-overview.mkiv
@@ -1,5 +1,5 @@
%D \module
-%D [ file=setups-basics, % x-set-12,
+%D [ file=setups-overview, % x-set-12,
%D version=2016.04.05, % 2004.10.31,
%D remark=setupx.tex: 1998.07.20 and later,
%D title=\CONTEXT\ Setup Definitions,
@@ -12,10 +12,13 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-% context --interface=en --global --result=setup-en x-setups-overview.mkiv
+% context --interface=en --global --result=setup-en x-setups-overview.mkiv --mode=setups:save
+% context --interface=en --global --result=setup-mapping-en x-setups-overview.mkiv --mode=setups:mapping
% \enablemode[setups:save]
+% \enablemode[setups:mapping]
+
\usemodule[setups-basics]
\unprotect
@@ -80,7 +83,12 @@
\definecolor [darkgray] [s=.1]
\usetypescript[palatino]
-\setupbodyfont[palatino,9pt]
+
+\doifelsemode {setups:mapping} {
+ \setupbodyfont[palatino,8pt]
+} {
+ \setupbodyfont[palatino,9pt]
+}
\defineoverlay
[cover]
@@ -91,28 +99,42 @@
[\hbox to \paperwidth{\reuseMPgraphic{cover+back}\hss}]
\startreusableMPgraphic{cover+back}
- numeric h, w ; path p, q, r ; color f, d ; pair s ;
+ numeric h, w; boolean mapping ; path p, q, r ; color f, d ; pair s ;
h := OverlayHeight ; w := 2*OverlayWidth ;
r := unitsquare xyscaled (w,h) ;
fill r withcolor \MPcolor{lightgray} ;
- set_grid(w,h,w/8,w/16) ;
+ mapping := lua.mp.processingmode("setups:mapping") ;
+ if mapping :
+ set_grid(w,h,w/8,w/160) ;
+ pickup pensquare yscaled (w/80) ;
+ else :
+ set_grid(w,h,w/8,w/16) ;
+ pickup pencircle scaled (w/100) ;
+ fi ;
forever :
s := center r randomized (w,h) ;
if new_on_grid(xpart s, ypart s) :
- s := (dx,dy) ;
- p := fullsquare xyscaled(w/4,w/8) ;
- q := (-4w,ypart ulcorner p) -- .5[ulcorner p, urcorner p] -- (4w,ypart urcorner p) ;
- q := q shifted (0,-w/24) ;
- p := p randomized (w/40,w/40) ;
- q := q randomized (0,w/100) ;
- q := q cutafter (p cutafter point 3 of p) ;
- q := q cutbefore (p cutbefore point 3 of p) ;
d := .5[\MPcolor{LocalColor},\MPcolor{lightgray}] randomized (.5,.9) ;
f := \MPcolor{lightgray} randomized (.5,.9) ;
- pickup pencircle scaled (w/100) ;
- fill p shifted s withcolor f ;
- draw p shifted s withcolor d ;
- draw q shifted s withcolor d ;
+ s := (dx,dy) ;
+ if mapping :
+ p := (-w/4,0) -- (w/4,0) ;
+ p := (-w/4,0) -- origin ;
+ q := origin -- ( w/4,0) ;
+ draw p shifted s withcolor d ;
+ draw q shifted s withcolor f ;
+ else :
+ p := fullsquare xyscaled(w/4,w/8) ;
+ q := (-4w,ypart ulcorner p) -- .5[ulcorner p, urcorner p] -- (4w,ypart urcorner p) ;
+ q := q shifted (0,-w/24) ;
+ p := p randomized (w/40,w/40) ;
+ q := q randomized (0,w/100) ;
+ q := q cutafter (p cutafter point 3 of p) ;
+ q := q cutbefore (p cutbefore point 3 of p) ;
+ fill p shifted s withcolor f ;
+ draw p shifted s withcolor d ;
+ draw q shifted s withcolor d ;
+ fi ;
fi ;
exitif grid_full ;
endfor ;
@@ -137,6 +159,11 @@
\c!width=\v!middle,
\c!height=\v!middle]
+\doifmode {setups:mapping} {
+ \setuplayout
+ [\c!backspace=1cm]
+}
+
\setuppagenumbering
[\c!location=\v!footer,
\c!alternative=\v!doublesided]
@@ -234,7 +261,11 @@
\protect
-\placeeverysetup
+\doifelsemode {setups:mapping} {
+ \placeeverysetupname
+} {
+ \placeeverysetup
+}
\unprotect
diff --git a/tex/generic/context/luatex/luatex-core.lua b/tex/generic/context/luatex/luatex-core.lua
index c13d81257..35005d1c8 100644
--- a/tex/generic/context/luatex/luatex-core.lua
+++ b/tex/generic/context/luatex/luatex-core.lua
@@ -1,11 +1,13 @@
+-- luatex-core security and io overloads ...........
+
-- if not modules then modules = { } end modules ['luatex-core'] = {
--- version = 1.001,
+-- version = 1.005,
-- comment = 'companion to luatex',
-- author = 'Hans Hagen & Luigi Scarso',
-- copyright = 'LuaTeX Development Team',
-- }
-LUATEXCOREVERSION = 1.003
+LUATEXCOREVERSION = 1.005
-- This file overloads some Lua functions. The readline variants provide the same
-- functionality as LuaTeX <= 1.04 and doing it this way permits us to keep the
@@ -71,13 +73,38 @@ local function luatex_io_popen(name,...)
end
end
+-- local function luatex_io_lines(name,how)
+-- if name then
+-- local f = io_open(name,how or 'r')
+-- if f then
+-- return function()
+-- return fio_readline(f)
+-- end
+-- end
+-- else
+-- return io_lines()
+-- end
+-- end
+
+-- For some reason the gc doesn't kick in so we need to close explitly
+-- so that the handle is flushed.
+
+local error, type = error, type
+
local function luatex_io_lines(name,how)
- if name then
+ if type(name) == "string" then
local f = io_open(name,how or 'r')
if f then
return function()
- return fio_readline(f)
+ local l = fio_readline(f)
+ if not l then
+ f:close()
+ end
+ return l
end
+ else
+ -- for those who like it this way:
+ error("patched 'io.lines' can't open '" .. name .. "'")
end
else
return io_lines()
@@ -331,6 +358,17 @@ else
end
+-- this is needed for getting require("socket") right
+
+do
+
+ local loaded = package.loaded
+
+ if not loaded.socket then loaded.socket = loaded["socket.core"] end
+ if not loaded.mime then loaded.mime = loaded["mime.core"] end
+
+end
+
-- so far
if utilities and utilities.merger and utilities.merger.compact then
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index ef0152436..e828c3023 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 11/22/17 13:35:39
+-- merge date : 01/08/18 23:03:13
do -- begin closure to overcome local limits and interference
@@ -11,6 +11,7 @@ if not modules then modules={} end modules ['l-lua']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
+local next,type,tonumber=next,type,tonumber
LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
LUAMAJORVERSION=tonumber(LUAMAJORVERSION) or 5
LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1
@@ -3648,6 +3649,25 @@ function unicode.toutf32string(n)
char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
end
end
+local len=utf.len
+local rep=rep
+function string.utfpadd(s,n)
+ if n and n~=0 then
+ local l=len(s)
+ if n>0 then
+ local d=n-l
+ if d>0 then
+ return rep(c or " ",d)..s
+ end
+ else
+ local d=- n-l
+ if d>0 then
+ return s..rep(c or " ",d)
+ end
+ end
+ end
+ return s
+end
end -- closure
@@ -3665,11 +3685,11 @@ utilities.strings=utilities.strings or {}
local strings=utilities.strings
local format,gsub,rep,sub,find=string.format,string.gsub,string.rep,string.sub,string.find
local load,dump=load,string.dump
-local tonumber,type,tostring=tonumber,type,tostring
+local tonumber,type,tostring,next=tonumber,type,tostring,next
local unpack,concat=table.unpack,table.concat
local P,V,C,S,R,Ct,Cs,Cp,Carg,Cc=lpeg.P,lpeg.V,lpeg.C,lpeg.S,lpeg.R,lpeg.Ct,lpeg.Cs,lpeg.Cp,lpeg.Carg,lpeg.Cc
local patterns,lpegmatch=lpeg.patterns,lpeg.match
-local utfchar,utfbyte=utf.char,utf.byte
+local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len
local loadstripped=nil
if LUAVERSION<5.2 then
loadstripped=function(str,shortcuts)
@@ -3759,6 +3779,17 @@ local pattern=Carg(1)/function(t)
function strings.tabtospace(str,tab)
return lpegmatch(pattern,str,1,tab or 7)
end
+function string.utfpadding(s,n)
+ if not n or n==0 then
+ return ""
+ end
+ local l=utflen(s)
+ if n>0 then
+ return nspaces[n-l]
+ else
+ return nspaces[-n-l]
+ end
+end
local space=spacer^0
local nospace=space/""
local endofline=nospace*newline
@@ -3947,6 +3978,7 @@ local utfchar=utf.char
local utfbyte=utf.byte
local lpegmatch=lpeg.match
local nspaces=string.nspaces
+local utfpadding=string.utfpadding
local tracedchar=string.tracedchar
local autosingle=string.autosingle
local autodouble=string.autodouble
@@ -3971,6 +4003,7 @@ else
utfbyte=utf.byte,
lpegmatch=lpeg.match,
nspaces=string.nspaces,
+ utfpadding=string.utfpadding,
tracedchar=string.tracedchar,
autosingle=string.autosingle,
autodouble=string.autodouble,
@@ -4006,6 +4039,29 @@ local format_S=function(f)
return format("tostring(a%s)",n)
end
end
+local format_right=function(f)
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ elseif f>0 then
+ return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
+end
+local format_left=function(f)
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ end
+ if f<0 then
+ return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
+end
local format_q=function()
n=n+1
return format("(a%s and format('%%q',a%s) or '')",n,n)
@@ -4260,6 +4316,8 @@ local builder=Cs { "start",
+V("j")+V("J")
+V("m")+V("M")
+V("z")
++V(">")
++V("<")
)+V("*")
)*(P(-1)+Carg(1))
)^0,
@@ -4303,6 +4361,8 @@ local builder=Cs { "start",
["z"]=(prefix_any*P("z"))/format_z,
["a"]=(prefix_any*P("a"))/format_a,
["A"]=(prefix_any*P("A"))/format_A,
+ ["<"]=(prefix_any*P("<"))/format_left,
+ [">"]=(prefix_any*P(">"))/format_right,
["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
@@ -7714,6 +7774,7 @@ local sortedkeys,sortedhash,serialize,fastcopy=table.sortedkeys,table.sortedhash
local derivetable=table.derive
local ioflush=io.flush
local round=math.round
+local setmetatable,getmetatable,rawget,rawset=setmetatable,getmetatable,rawget,rawset
local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end)
local report_defining=logs.reporter("fonts","defining")
@@ -7841,27 +7902,62 @@ function constructors.trytosharefont(target,tfmdata)
end
end
end
+local synonyms={
+ exheight="x_height",
+ xheight="x_height",
+ ex="x_height",
+ emwidth="quad",
+ em="quad",
+ spacestretch="space_stretch",
+ stretch="space_stretch",
+ spaceshrink="space_shrink",
+ shrink="space_shrink",
+ extraspace="extra_space",
+ xspace="extra_space",
+ slantperpoint="slant",
+}
function constructors.enhanceparameters(parameters)
- local xheight=parameters.x_height
- local quad=parameters.quad
- local space=parameters.space
- local stretch=parameters.space_stretch
- local shrink=parameters.space_shrink
- local extra=parameters.extra_space
- local slant=parameters.slant
- parameters.xheight=xheight
- parameters.spacestretch=stretch
- parameters.spaceshrink=shrink
- parameters.extraspace=extra
- parameters.em=quad
- parameters.ex=xheight
- parameters.slantperpoint=slant
- parameters.spacing={
- width=space,
- stretch=stretch,
- shrink=shrink,
- extra=extra,
- }
+ local mt=getmetatable(parameters)
+ local getter=function(t,k)
+ if not k then
+ return nil
+ end
+ local s=synonyms[k]
+ if s then
+ return rawget(t,s) or (mt and mt[s]) or nil
+ end
+ if k=="spacing" then
+ return {
+ width=t.space,
+ stretch=t.space_stretch,
+ shrink=t.space_shrink,
+ extra=t.extra_space,
+ }
+ end
+ return mt and mt[k] or nil
+ end
+ local setter=function(t,k,v)
+ if not k then
+ return 0
+ end
+ local s=synonyms[k]
+ if s then
+ rawset(t,s,v)
+ elseif k=="spacing" then
+ if type(v)=="table" then
+ rawset(t,"space",v.width or 0)
+ rawset(t,"space_stretch",v.stretch or 0)
+ rawset(t,"space_shrink",v.shrink or 0)
+ rawset(t,"extra_space",v.extra or 0)
+ end
+ else
+ rawset(t,k,v)
+ end
+ end
+ setmetatable(parameters,{
+ __index=getter,
+ __newindex=setter,
+ })
end
local function mathkerns(v,vdelta)
local k={}
@@ -22959,7 +23055,6 @@ local trace_directions=false registertracker("otf.directions",function(v) trace_
local trace_plugins=false registertracker("otf.plugins",function(v) trace_plugins=v end)
local trace_chains=false registertracker("otf.chains",function(v) trace_chains=v end)
local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kernruns=v end)
-local trace_discruns=false registertracker("otf.discruns",function(v) trace_discruns=v end)
local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end)
local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end)
local forcediscretionaries=false
@@ -25154,7 +25249,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
end
else
notmatchreplace[current]=true
- if not notmatchpre[current] then
+ if notmatchpre[current] then
goto next
else
break
@@ -25869,9 +25964,14 @@ local function txtdirstate(start,stack,top,rlparmode)
top=top+1
stack[top]=dir
elseif dir=="-TRT" or dir=="-TLT" then
- top=top-1
- if stack[top]=="+TRT" then
- new=-1
+ if top==1 then
+ top=0
+ new=rlparmode
+ else
+ top=top-1
+ if stack[top]=="+TRT" then
+ new=-1
+ end
end
else
new=rlparmode
@@ -28539,8 +28639,12 @@ local function convert(t,k)
t[k]=v
return v
end
-local start={ "pdf","page","q" }
-local stop={ "pdf","raw","Q" }
+local start={ "pdf","mode","font" }
+local push={ "pdf","page","q" }
+local pop={ "pdf","page","Q" }
+if not LUATEXFUNCTIONALITY or LUATEXFUNCTIONALITY<6472 then
+ start={ "nop" }
+end
local function initializecolr(tfmdata,kind,value)
if value then
local resources=tfmdata.resources
@@ -28589,14 +28693,20 @@ local function initializecolr(tfmdata,kind,value)
local goback=w~=0 and widths[w] or nil
local t={
start,
- not u and actualb or { "pdf","raw",getactualtext(tounicode(u)) }
+ not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) }
}
local n=2
local l=nil
+ local f=false
for i=1,s do
local entry=colorlist[i]
local v=colorvalues[entry.class] or default
if v and l~=v then
+ if f then
+ n=n+1 t[n]=pop
+ end
+ n=n+1 t[n]=push
+ f=true
n=n+1 t[n]=v
l=v
end
@@ -28605,8 +28715,10 @@ local function initializecolr(tfmdata,kind,value)
n=n+1 t[n]=goback
end
end
+ if f then
+ n=n+1 t[n]=pop
+ end
n=n+1 t[n]=actuale
- n=n+1 t[n]=stop
character.commands=t
end
end
@@ -28654,6 +28766,9 @@ local function pdftovirtual(tfmdata,pdfshapes,kind)
}
local getactualtext=otf.getactualtext
local storepdfdata=otf.storepdfdata
+ local b,e=getactualtext(tounicode(0xFFFD))
+ local actualb={ "pdf","page",b }
+ local actuale={ "pdf","page",e }
for unicode,character in sortedhash(characters) do
local index=character.index
if index then
@@ -28674,16 +28789,16 @@ local function pdftovirtual(tfmdata,pdfshapes,kind)
if data then
local setcode,name,nilcode=storepdfdata(data)
if name then
- local bt,et=getactualtext(unicode)
+ local bt=unicode and getactualtext(unicode)
local wd=character.width or 0
local ht=character.height or 0
local dp=character.depth or 0
character.commands={
- { "pdf","direct",bt },
+ not unicode and actualb or { "pdf","page",(getactualtext(unicode)) },
{ "down",dp+dy*hfactor },
{ "right",dx*hfactor },
{ "image",{ filename=name,width=wd,height=ht,depth=dp } },
- { "pdf","direct",et },
+ actuale,
}
character[kind]=true
end
@@ -34436,6 +34551,7 @@ if context then
texio.write_nl("fatal error: this module is not for context")
os.exit()
end
+local next=next
local fonts=fonts
local nodes=nodes
local nuts=nodes.nuts
diff --git a/tex/generic/context/luatex/luatex-mplib.lua b/tex/generic/context/luatex/luatex-mplib.lua
index 785bc707c..c610fca57 100644
--- a/tex/generic/context/luatex/luatex-mplib.lua
+++ b/tex/generic/context/luatex/luatex-mplib.lua
@@ -462,15 +462,19 @@ else
pdf_startfigure(fignum,llx,lly,urx,ury)
pdf_literalcode("q")
if objects then
+ local savedpath = nil
+ local savedhtap = nil
for o=1,#objects do
local object = objects[o]
local objecttype = object.type
if objecttype == "start_bounds" or objecttype == "stop_bounds" then
-- skip
elseif objecttype == "start_clip" then
+ local evenodd = not object.istext and object.postscript == "evenodd"
pdf_literalcode("q")
flushnormalpath(object.path,t,false)
pdf_literalcode("W n")
+ pdf_literalcode(evenodd and "W* n" or "W n")
elseif objecttype == "stop_clip" then
pdf_literalcode("Q")
miterlimit, linecap, linejoin, dashed = -1, -1, -1, false
@@ -482,96 +486,147 @@ else
pdf_textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth)
pdf_literalcode("Q")
else
- local cs = object.color
- local cr = false
- if cs and #cs > 0 then
- cs, cr = metapost.colorconverter(cs)
- pdf_literalcode(cs)
- end
- local ml = object.miterlimit
- if ml and ml ~= miterlimit then
- miterlimit = ml
- pdf_literalcode("%f M",ml)
- end
- local lj = object.linejoin
- if lj and lj ~= linejoin then
- linejoin = lj
- pdf_literalcode("%i j",lj)
- end
- local lc = object.linecap
- if lc and lc ~= linecap then
- linecap = lc
- pdf_literalcode("%i J",lc)
- end
- local dl = object.dash
- if dl then
- local d = format("[%s] %i d",concat(dl.dashes or {}," "),dl.offset)
- if d ~= dashed then
- dashed = d
- pdf_literalcode(dashed)
+ local evenodd, collect, both = false, false, false
+ local postscript = object.postscript
+ if not object.istext then
+ if postscript == "evenodd" then
+ evenodd = true
+ elseif postscript == "collect" then
+ collect = true
+ elseif postscript == "both" then
+ both = true
+ elseif postscript == "eoboth" then
+ evenodd = true
+ both = true
end
- elseif dashed then
- pdf_literalcode("[] 0 d")
- dashed = false
end
- local path = object.path
- local transformed, penwidth = false, 1
- local open = path and path[1].left_type and path[#path].right_type
- local pen = object.pen
- if pen then
- if pen.type == 'elliptical' then
- transformed, penwidth = pen_characteristics(object) -- boolean, value
- pdf_literalcode("%f w",penwidth)
- if objecttype == 'fill' then
- objecttype = 'both'
- end
- else -- calculated by mplib itself
- objecttype = 'fill'
- end
- end
- if transformed then
- pdf_literalcode("q")
- end
- if path then
- if transformed then
- flushconcatpath(path,open)
+ if collect then
+ if not savedpath then
+ savedpath = { object.path or false }
+ savedhtap = { object.htap or false }
else
- flushnormalpath(path,open)
+ savedpath[#savedpath+1] = object.path or false
+ savedhtap[#savedhtap+1] = object.htap or false
end
- if objecttype == "fill" then
- pdf_literalcode("h f")
- elseif objecttype == "outline" then
- pdf_literalcode((open and "S") or "h S")
- elseif objecttype == "both" then
- pdf_literalcode("h B")
+ else
+ local cs = object.color
+ local cr = false
+ if cs and #cs > 0 then
+ cs, cr = metapost.colorconverter(cs)
+ pdf_literalcode(cs)
end
- end
- if transformed then
- pdf_literalcode("Q")
- end
- local path = object.htap
- if path then
- if transformed then
- pdf_literalcode("q")
+ local ml = object.miterlimit
+ if ml and ml ~= miterlimit then
+ miterlimit = ml
+ pdf_literalcode("%f M",ml)
+ end
+ local lj = object.linejoin
+ if lj and lj ~= linejoin then
+ linejoin = lj
+ pdf_literalcode("%i j",lj)
+ end
+ local lc = object.linecap
+ if lc and lc ~= linecap then
+ linecap = lc
+ pdf_literalcode("%i J",lc)
+ end
+ local dl = object.dash
+ if dl then
+ local d = format("[%s] %i d",concat(dl.dashes or {}," "),dl.offset)
+ if d ~= dashed then
+ dashed = d
+ pdf_literalcode(dashed)
+ end
+ elseif dashed then
+ pdf_literalcode("[] 0 d")
+ dashed = false
+ end
+ local path = object.path
+ local transformed, penwidth = false, 1
+ local open = path and path[1].left_type and path[#path].right_type
+ local pen = object.pen
+ if pen then
+ if pen.type == 'elliptical' then
+ transformed, penwidth = pen_characteristics(object) -- boolean, value
+ pdf_literalcode("%f w",penwidth)
+ if objecttype == 'fill' then
+ objecttype = 'both'
+ end
+ else -- calculated by mplib itself
+ objecttype = 'fill'
+ end
end
if transformed then
- flushconcatpath(path,open)
- else
- flushnormalpath(path,open)
+ pdf_literalcode("q")
end
- if objecttype == "fill" then
- pdf_literalcode("h f")
- elseif objecttype == "outline" then
- pdf_literalcode((open and "S") or "h S")
- elseif objecttype == "both" then
- pdf_literalcode("h B")
+ if path then
+ if savedpath then
+ for i=1,#savedpath do
+ local path = savedpath[i]
+ if transformed then
+ flushconcatpath(path,open)
+ else
+ flushnormalpath(path,open)
+ end
+ end
+ savedpath = nil
+ end
+ if transformed then
+ flushconcatpath(path,open)
+ else
+ flushnormalpath(path,open)
+ end
+ if objecttype == "fill" then
+ pdf_literalcode("h f")
+ elseif objecttype == "outline" then
+ if both then
+ pdf_literalcode(evenodd and "h B*" or "h B")
+ else
+ pdf_literalcode(open and "S" or "h S")
+ end
+ elseif objecttype == "both" then
+ pdf_literalcode(evenodd and "h B*" or "h B")
+ end
end
if transformed then
pdf_literalcode("Q")
end
- end
- if cr then
- pdf_literalcode(cr)
+ local path = object.htap
+ if path then
+ if transformed then
+ pdf_literalcode("q")
+ end
+ if savedhtap then
+ for i=1,#savedhtap do
+ local path = savedhtap[i]
+ if transformed then
+ flushconcatpath(path,open)
+ else
+ flushnormalpath(path,open)
+ end
+ end
+ savedhtap = nil
+ evenodd = true
+ end
+ if transformed then
+ flushconcatpath(path,open)
+ else
+ flushnormalpath(path,open)
+ end
+ if objecttype == "fill" then
+ pdf_literalcode("h f")
+ elseif objecttype == "outline" then
+ pdf_literalcode(evenodd and "h f*" or "h f")
+ elseif objecttype == "both" then
+ pdf_literalcode(evenodd and "h B*" or "h B")
+ end
+ if transformed then
+ pdf_literalcode("Q")
+ end
+ end
+ if cr then
+ pdf_literalcode(cr)
+ end
end
end
end
diff --git a/tex/generic/context/luatex/luatex-swiglib.lua b/tex/generic/context/luatex/luatex-swiglib.lua
index 3108dd43f..cbb6798c3 100644
--- a/tex/generic/context/luatex/luatex-swiglib.lua
+++ b/tex/generic/context/luatex/luatex-swiglib.lua
@@ -16,16 +16,18 @@ function requireswiglib(required,version)
if library then
return library
else
- local name = string.gsub(required,"%.","/") .. libsuffix
+ local full = string.gsub(required,"%.","/"
+ local path = file.pathpart(full)
+ local name = file.nameonly(full) .. libsuffix
local list = kpse.show_path("clua")
for root in string.gmatch(list,pathsplit) do
local full = false
if type(version) == "string" and version ~= "" then
- full = root .. "/" .. version .. "/" .. name
+ full = root .. "/" .. path .. "/" .. version .. "/" .. name
full = lfs.isfile(full) and full
end
if not full then
- full = root .. "/" .. name
+ full = root .. "/" .. path .. "/" .. name
full = lfs.isfile(full) and full
end
if full then